rch850 の上澄み

技術的な話題とか、雑談とか。タイトルを上澄みに変えました @ 2020/09/02

Web Audio API の奥底から Angular とつながりたかった

Angular 2 の勉強がてらに、Web Audio API で録音するウェブアプリを作ろうとしたら、変なところでハマったのでメモ。

録音には MediaRecorder を使おうとしました。コードは今のリンク先にあるものを参考に書きました。getUserMedia で取った stream を使って MediaRecorder を作って、その onstop で結果を得る形です。

が、なかなか録音完了後の結果がビューに反映されませんでした。AngularJS 1.x で言うダイジェストをしたかったんですが、ドキュメント の Change Detection あたりを読んでも Angular zone がいい具合にやるから大丈夫と書いてあるだけでさっぱり。

いろいろ調べて Triggering Angular2 change detection manually - Stack Overflow に行き当たって ChangeDetectorRef.detectChanges() が良さそうということが分かりました。

最終的にはこのようなコードになりました。

  constructor(private ref: ChangeDetectorRef) {
    navigator.mediaDevices.getUserMedia(
      { audio: true }
    ).then((stream: MediaStream) => {
      this.mediaRecorder = new MediaRecorder(stream);
      this.mediaRecorder.ondataavailable = (e) => {
        this.chunks.push(e.data)
      }
      this.mediaRecorder.onstop = (e) => {
        let clipName = prompt("Enter a name for your sound clip")

        let blob = new Blob(this.chunks, {"type": "audio/ogg; codecs=opus"})
        this.chunks = []
        this.clips.push({
          name: clipName,
          audioUrl: window.URL.createObjectURL(blob)
        })
        console.log(this.clips)
        // これを呼び出したら clips への要素追加が反映された
        this.ref.detectChanges()
      }
    }, function(err: any) {
      console.error(err);
    });
  }

以上!