Upgrade to Pro — share decks privately, control downloads, hide ads and more …

令和元年にもなって wavファイルをバイナリエディタで読んだ話とか / read wa...

OPTiM
October 24, 2019

令和元年にもなって wavファイルをバイナリエディタで読んだ話とか / read wav binary

OPTiM

October 24, 2019
Tweet

More Decks by OPTiM

Other Decks in Programming

Transcript

  1. Copyright © OPTiM Corp. All Right Reserved. 1 株式会社 OPTiM

    R&Dチーム 中村 令和元年にもなって wavファイルをバイナリエディタで読んだ話とか
  2. Copyright © OPTiM Corp. All Right Reserved. 2  中村

    (なかむら)@ 2016 .10 ~ • 愛媛県松山市生まれ → 九州工業大学(電子情報工学科)→ OPTiM  R&Dチームのエンジニア  学生の頃にやってて役立ったな。と最近思ったこと • 自宅ラックマウント(されてない平積みの)サーバーで遊んだこと • NEC IX2015 ルーターで遊んだこと • Adobe Flash黄金時代に生まれたこと(ActionScriptとの出会い) 自己紹介
  3. Copyright © OPTiM Corp. All Right Reserved. 5 アイスブレイク Visual

    Studio Codeでも読めます(読むだけ)
  4. Copyright © OPTiM Corp. All Right Reserved. 6 Copyright ©

    OPTiM Corp. All Right Reserved. WAV と CAF 元年にもなってwavファイルをバイナリエディタで読んだ話とか Ep.1
  5. Copyright © OPTiM Corp. All Right Reserved. 7  WAV

    ( RIFF waveform Audio Format ) • RIFFチャンクとサブチャンクで構成 • 各チャンクの先頭4バイトはチャンク識別子 • RIFF、fmt、data など • fmtチャンク、dataチャンクは必須 • 各チャンクの5バイト目からの4バイトはチャン クサイズ wavファイルの構造 http://soundfile.sapp.org/doc/WaveFormat/
  6. Copyright © OPTiM Corp. All Right Reserved. 8 背景 こういう感じのものを作ってました

    iPhone AVAudioEngine AVAudioRecorder APIサーバー 解析サーバー Go製の普通のAPIサーバー ( http.DetectContentType ) 外部のSaaSなど Validation Error
  7. Copyright © OPTiM Corp. All Right Reserved. 11 背景 caff

    ? https://developer.apple.com/library/archive/documentation/MusicAudio/Reference/CAFSpec/CAF_overview/CAF_overview.html https://en.wikipedia.org/wiki/Core_Audio_Format  Apple Core Audio Format (CAF) • Mac OS X 10.4以降(条件付きで10.3以降)、iOS 5.0以降でサポートされる • ファイルサイズ制限なし • ヘッダのサイズフィールドが未確定でも大丈夫(録音が中断されてヘッダが未ファイナライズでもOK) • チャンネルレイアウトのようなオーディオデータ以外のデータいろいろ格納できる • 様々なフォーマットのラッパーのように振る舞う(コンテナフォーマットに近い) • 「チャンク」の単位で構成され、チャンクヘッダー + データ部で構成される つまり、出てきたものは「caffのコーデックがLinear PCMになってるファイル」
  8. Copyright © OPTiM Corp. All Right Reserved. 13 ちなみに MediaInfo

    先生はちゃんと教えてくれてました… https://mediaarea.net/ja/MediaInfo
  9. Copyright © OPTiM Corp. All Right Reserved. 14  AMR-NB(Narrowband)

    • 8000 [Hz] • モノラル 余談 iOS 12.2からiMessageの音声もcaffになった(らしい) https://applech2.com/archives/20190314-imessage-audio-support-opus-in-ios-12-2.html  caff(Opus) • 24000 [Hz] • モノラル
  10. Copyright © OPTiM Corp. All Right Reserved. 15 Copyright ©

    OPTiM Corp. All Right Reserved. FLLRチャンク 元年にもなってwavファイルをバイナリエディタで読んだ話とか Ep. 2
  11. Copyright © OPTiM Corp. All Right Reserved. 16 背景 こういう感じのものを作ってました(2周目)

    iPhone AVAudioEngine AVAudioRecorder APIサーバー 解析サーバー Go製の普通のAPIサーバー + github.com/youpy/go-wav Could’t read meta data
  12. Copyright © OPTiM Corp. All Right Reserved. 18 背景 何が出てきたのか

    見慣れない FLLRサブチャンクの 入ったwavファイル
  13. Copyright © OPTiM Corp. All Right Reserved. 19 背景 FLLR

    ? https://stackoverflow.com/questions/6284651/avaudiorecorder-doesnt-write-out-proper-wav-file-header  Apple software often creates WAVE files with a non-standard (but "spec" conformant) • fmtチャンクとdataチャンクの間にFLLRサブチャンクが入る • FLLRチャンクの大きさはデータによって異なるが4KB程度 • wavはRIFFのサブセットのため、サブチャンクが入ることは問題ない • wavのデータ部が44バイト目から始まるような想定で書かれているソフトウェアは正しく動 作しない • dataチャンクの識別子を見つけて、そこをオフセットとしてデータを読む実装でなければならない
  14. Copyright © OPTiM Corp. All Right Reserved. 21 背景 bakape/thumbnailer

    を使いました https://github.com/bakape/thumbnailer
  15. Copyright © OPTiM Corp. All Right Reserved. 22 背景 bakape/thumbnailer

     いいところ • FFMPEGをバックエンドにしているのでサブチャンクがあってもきちんと読める • FFMPEGが読めるものをすべて読めるようにするには少し手を加える必要あり? • func NewFFContext(rs io.ReadSeeker) (*FFContext, error) • net/httpパッケージのParseMultipartForm()は32MBを超えるデータは一時ファイルへ書き込まれる • io.Readerを受け取れるものの一時ファイルのパスはパッケージ外で見れない • そして大体のFFMPEGをバックエンドにしてる系のContextはファイルパス(String)を引数にとる
  16. Copyright © OPTiM Corp. All Right Reserved. 24 Copyright ©

    OPTiM Corp. All Right Reserved. AES-CBC と Go と Node.js 元年にもなってwavファイルをバイナリエディタで読んだ話とか Ep.3
  17. Copyright © OPTiM Corp. All Right Reserved. 25 背景 こういう感じのものを作ってました

    テキスト Node.js 標準のCrypto() AES暗号化 UTF-8な 一般的なテキスト 外部のSaaSなど 復号化 Not match テキスト Go crypto/cipher
  18. Copyright © OPTiM Corp. All Right Reserved. 26 背景 Q.

    Node.jsのcrypt()で AES-CBC-256暗号したテキストを Goのcryptoで復号できる?
  19. Copyright © OPTiM Corp. All Right Reserved. 27 背景 A.

    一部実装しないとできません
  20. Copyright © OPTiM Corp. All Right Reserved. 28  AES

    • ブロック暗号(指定されたブロック長ごとにデータを暗号化) • ブロックの大きさより小さいデータはパディング(何らかの文字で埋める) • パディング方式はPKCSなど 背景 https://kiririmode.hatenablog.jp/entry/20181014/1539473020  goの crypto/cipher や crypto/aes • パディングが未定義 • 暗号化するとき: ブロックサイズの倍数でないとエラー • 復号化するとき: パディング部分を残したまま出力 実装しましょう
  21. Copyright © OPTiM Corp. All Right Reserved. 31 Copyright ©

    OPTiM Corp. All Right Reserved. おわりに
  22. Copyright © OPTiM Corp. All Right Reserved. 32  フォーマット・仕様、そして実装はきちんと確認しましょう(N回目)

    • バイナリファイルでも恐れずに • 既存のソースや外部のソースも正しい実装とは限りません • 99%は自分のミスな気が…  けっこう泥臭いこともやります • 欲しいデータセットがない → 自分たちで作る • ライブラリに欲しい機能がない → 自分で実装する おわりに 結局新しいことをやるって、こうなるところありますよね