NCMBとMonacaを使ってボイスレコーディングアプリを作ります。HTML APIだけを使うので、プラグインを使わずに開発できます。録音した音声をNCMBのファイルストアへアップロードし、逆にダウンロードして再生できるアプリです。
前回までで一通りの実装は完了したのですが、音声ファイルをHTTPSファイル公開して再生するのがちょっと気になっていたので、Web Audio APIでの再生に変更してみました。
コードについて
今回のコードはNCMBMania/monaca-voice-recorderにアップロードしてあります。実装時の参考にしてください。
今回の処理について
今回の処理はすべて www/pages/home.html
に記述しています。
前回のコードから削除する箇所
前回のコードでは uri が指定されると、画面にaudioタグを表示していましたが、それが不要になります。以下の部分です。
<!-- 録音データが選択されたら audio タグを表示する -->
${ uri !== '' ?
$h`<audio src="${uri}" controls style="width:100%;"></audio>`
:
''
}
また、アプリIDや再生用URIも不要です。以下は不要です。
// 再生用のURI
let uri = '';
// アプリID
const appId = 'YOUR_APP_ID';
音声ファイルを選択した際の処理
音声ファイルを選択した際の処理 listen
関数を修正します。元々の実装は以下のようになっているでしょう。
const listen = async (file) => {
// ファイルストアからダウンロード
const blob = await ncmb.File.download(file.fileName, 'blob');
// URIに変換
uri = URL.createObjectURL(blob);
// 描画更新
$update();
}
以下はすべて listen
関数の内容です。まずファイルをダウンロードするところは変わりません。
// ファイルストアからダウンロード
const blob = await ncmb.File.download(file.fileName, 'blob');
そして、BlobからArrayBufferに変更します。
// BlobからArrayBufferに変換
const arrayBuffer = await blob.arrayBuffer();
このArrayBufferをAudioBufferに変換します。
// Web Audio APIのコンテキストを作成
window.AudioContext = window.AudioContext || window.webkitAudioContext;
const context = new AudioContext();
// ArrayBufferからAudioBufferに変換
const audioBuffer = await (new Promise((res, rej) => {
context.decodeAudioData(arrayBuffer, res, rej);
}));
続けて、再生するソースとして適用します。
// ソースを使って再生
const source = context.createBufferSource();
source.buffer = audioBuffer;
最後の再生を開始して終了です。
source.connect(context.destination);
source.start(0);
listen
関数の内容は次の通りです。
// 録音データを選択した際の処理
const listen = async (file) => {
// ファイルストアからダウンロード
const blob = await ncmb.File.download(file.fileName, 'blob');
// BlobからArrayBufferに変換
const arrayBuffer = await blob.arrayBuffer();
// Web Audio APIのコンテキストを作成
window.AudioContext = window.AudioContext || window.webkitAudioContext;
const context = new AudioContext();
// ArrayBufferからAudioBufferに変換
const audioBuffer = await (new Promise((res, rej) => {
context.decodeAudioData(arrayBuffer, res, rej);
}));
// ソースを使って再生
const source = context.createBufferSource();
source.buffer = audioBuffer;
source.connect(context.destination);
source.start(0);
}
これでHTTPSファイル公開を使わず、ファイルストアからダウンロードした音声を直接再生できます。audioタグのように再生ボタンを押す必要もないので、ユーザー体験も向上します。
まとめ
今回はaudioタグからWeb Audio APIを使う方法に変更しました。BlobからArrayBufferに変換し、さらにAudioBufferに変換するところさえ分かれば、再生すること自体は難しくありません。
ただし、この方法ではストリーミング再生はできないので(一旦すべてダウンロードする必要があります)、ダウンロード中はローディングを出すと言った工夫が必要でしょう。