Edited at

WebRTCを試すときにオッサンが映り続ける問題に対処する

More than 3 years have passed since last update.


はじめに

WebRTCを使ったアプリを作る際に、切っても切れないのがカメラ映像の取得です。ノート型のPCで作業したりすると、延々と自分の顔を見続けなければなりません。そこで、自分の顔の替わりに好きな動画をメディアストリームとして流すサンプルを作って見ました。


仕組み


動画ファイルの変換


  • ユーザにローカルの動画ファイルを指定してもらう(ファイル選択 or ドラッグ&ドロップ)

  • FileオブジェクトからURLを生成 (window.URL.createObjectURLを利用)

  • それをVideoタグで再生

  • 継続的にCanvasタグに転写 (window.requestAnimationFrameを利用)

  • CanvasタグからMediaStreamを取り出す (Canvas.captureStreamを利用)



音声ファイルの変換


  • ユーザにローカルの音声ファイルを指定してもらう(ファイル選択 or ドラッグ&ドロップ)

  • FileReaderでファイルを読み込む

  • WebAudio API デコード、再生

  • WebAudio API の createMediaStreamDestination でMediaStreamを取り出す



動画と音声の結合


  • 新しく MediaStreamのオブジェクトを用意

  • 動画ファイルを変換した MediaStream から Video Trackを取り出し、新しいMediaStreamに渡す

  • 音声ファイルを変換した MediaStream から Audio Trackを取り出し、新しいMediaStreamに渡す



combine

    convertedStream = new MediaStream();

convertedStream.addTrack(duplicateStream.getVideoTracks()[0]);
convertedStream.addTrack(audioOutputStream.getAudioTracks()[0]);


やってみよう

実際にローカルの動画ファイル/音声ファイルからメディアストリームを取り出すサンプルを作ってみました。ChromeかFirefoxでご利用ください。

ローカルに映像ファイルと、音声ファイルをご用意の上、こちらの手順で試してください。(音声だけや、映像だけの変換もできます)

※今回はこちらのNHKクリエイティブライブラリの素材を使わせていただきました。

変換したメディアストリームは、こちらにセットしてあるので、あとは焼くなり煮るなりRTCPeerConnectionで通信するなり、好きにご利用ください。

let convertedStream;


注意点


  • requestAnimationFrame()は、該当のタブ/ウィンドウが隠れてしまうと全く呼び出されません。変換を行っているタブ/ウィンドウが一部でも表示されている状態にしてください

  • Chrome 52の場合は変換に使っているCanvasのスタイルを display:none; にすると変換後の動画が停止してしまいます

  • Firefox 47の場合、Canvasの描画や変換後の映像がチラつく場合があります。その時は変換に使っているCanvasのスタイルを visibility:hidden; や display:none; に変更すると改善します

  • Firefox 47の場合に変換後の convertedStream を RTCPeerConnetionに追加(addStream)しようとするとエラーになります


    • NotSupportedError: track in constructed stream not yet supported (see Bug 1259236) )

    • 現在の制約として new RTCPeerConnectionで生成したオブジェクトにトラックを追加すると通信には使えないようです

    • Canvasから取り出した映像だけのメディアストリームは通信に使うことができました



  • ローカルの動画ファイルの代わりに他のサーバーの動画ファイルを指定しての変換もできそうですが、そうではないようです


    • Canvasへの複写までは可能です

    • メディアストリームを取り出すことは出来ませんでした

    • ドメインが異なると禁止されているのかもしれません(詳しい方がいたら教えてください)




おわりに

ローカルファイルをメディアストリームに変換する方法をご紹介しました。まだブラウザごとに細かい挙動が違ったりするところもありますが、あらかじめ用意したメディアを配信する用途に使えるのではないでしょうか。

※既存の動画/音声ファイルを使う場合には、その利用条件は尊重してご利用ください。よろしくお願いします。

HTMLExperts.jp というサイトで「WebRTC入門2016」という記事も書いているので、WebRTCにご興味を持たれた方はそちらもご覧いただけると嬉しいです。