物置小屋

メモ置き場

MediaRecorderを使って音声録音したら再生時間が取れなかった件

はじめに

IPFactory Advent Calendar 2019 12日目の記事です。

qiita.com

インターン先で、ブラウザで音声入力からの音声解析してチャットボットぽいものを作る機会がありました。 その際、ブラウザでの音声入力で詰まった点があったので適当に書く予定です。

一応言っておきますが、全てPC版のChromeで試しています。Firefox等他のブラウザでは一切試していないのであしからず。

MediaRecorderを使ってサクッと音声録音してみよう

まず、ブラウザで音声入力をするにはどうすればいいだろうか?
調べてみたところWebRTCという技術があり、getUserMediaMediaRecorderというものを使えば楽に音声入力が実現できそうでした。

ということでサクッとJSから音声録音を実現するために書いたコードが以下のものとなっています。

github.com

デモページも用意しました。下記リンクに飛べば実際に録音して、再生、ダウンロードを試すことができます。

mnao305.github.io

録音ボタンを押すと録音が開始されますが、その際ブラウザからマイクの許可が求められます。

ソースコード内のコメントでも書いてあるが、MediaRecorderではwebmしか使えないらしい。 webmとはGoogleが開発しているフリーのメディアフォーマット。

今回はwavを使いたかったのでそれも後ほど解決します。

動画長さが存在しない

さて、上記のデモを試してみたらわかるが、この録音した音声データには再生時間が存在していません。

> ffprobe test.webm -hide_banner
Input #0, matroska,webm, from 'test.webm':
  Metadata:
    encoder         : Chrome
  Duration: N/A, start: 0.000000, bitrate: N/A

色々と調べてみたところ、これはChromeのバグとして報告されていました。

bugs.chromium.org

ですが、WontFixとなっています。
上記Issueにも書いてある通り、W3Cの方のIssueにも上がっていました。

github.com

ということでこれはバグと言うより仕様みたいです。

webmではなくwavで保存し、動画長さを追加する。

色々と試してみた結果、解決するために実際にやったのはファイルヘッダを書き換えてwavにするという方法です。

コードを見てもらったほうがわかりやすいと思うので、下記にGitHubへのリンクを張っておきます。

github.com

デモページ

mnao305.github.io

wavで保存され再生時間も取れているのがわかる。

> ffprobe.exe test.wav -hide_banner
Input #0, wav, from 'test.wav':
  Duration: 00:00:10.77, bitrate: 705 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 1 channels, s16, 705 kb/s

この方法の何が嬉しいかというと、wavにできること、追加でライブラリがいらないことなどですかね。
ということでコードの説明を軽くします。

// TODO 後で書く

参考

ユーザーから音声データを取得する  |  Web  |  Google Developers

Inside WebM

GitHub - grishkovelli/vue-audio-recorder: A simple audio recorder for VueJS applications

WAVEファイルの構造