12. カメラ(マイク)の停止と再開
前項までのビデオチャットプログラムは、チャットの途中でカメラの停止をするとチャット相手のリモート映像は静止画像となり、停止したカメラを再開してもチャット相手のリモート映像は再開しません。
本項では、チャットの途中でカメラ(マイク)の停止や再開ができるようにします。
解説
チャットの途中でカメラとマイクの停止や再開ですべきことは、以下です。
- カメラ(マイク)を停止するには、コネクションオブジェクトが保持するトラックの削除を行います。
- カメラ(マイク)を再開するには、コネクションオブジェクトにトラックの結果発生する、Negotiation needed イベント時に、OfferSDPを作成し送信し、新たなシグナリングを開始します。
- 新たなシグナリングにおけるお互いの情報の交換は、シグナリングサーバーを経由して行うのではなく、DataChannelを通して行います。
準備
「11. 独自データの送受信」を実施していない場合は、実施します。
サーバー側の処理
変更なし。
ウェブページ
変更なし。
クライアント側の処理
「public/client.js」ファイルを編集します。
カメラとマイクのOn/Offのチェックボックスを押すと呼ばれる関数
「UIから呼ばれる関数」コード部の「カメラとマイクのOn/Offのチェックボックスを押すと呼ばれる関数」の処理を変更します。
- カメラとマイクのOn/Offのチェックボックスの状態に変化があったときには、コネクションオブジェクトが保持するトラックの削除を行います。トラックは、senderが保持するので、senderの取得も行います。
- トラックの削除のために、これまでのトラックのidを取得も行います。
- カメラとマイクのOn/Offのチェックボックスの状態がOnに変化するときには、コネクションオブジェクトにトラックの追加を行います。
Negotiation needed イベントが発生したときのイベントハンドラ
RTCPeerConnectionオブジェクトに対するTrackの追加の結果として、Negotiation needed イベントが発生します。Negotiation
needed イベント時の処理として、OfferSDPを作成し送信し、新たなシグナリングを開始します。
「RTCPeerConnection関連の関数」コード部の「RTCPeerConnectionオブジェクトのイベントハンドラの構築」の関数の「Negotiation
needed イベントが発生したときのイベントハンドラ」の処理を変更します。
- データチャンネルが開いているときは、OfferSDP作成関数を呼び出します。(データチャンネルが開いていないときは、OfferSDPは、ユーザーイベントから直接呼出します。)
OfferSDPの作成関数
DataChannelが開いているときは、OfferSDPの送信を、DataChannelを通して行うようにします。
「RTCPeerConnection関連の関数」コード部の「OfferSDPの作成」関数の処理を変更します。
- OfferSDPの送信について、DataChannelが開いていないときはサーバーを経由して送信し、DataChannelが開いているときはDataChannelを通して送信するようにします。
OfferSDPの設定とAnswerSDPの作成関数
DataChannelが開いているときは、AnswerSDPの送信を、DataChannelを通して行うようにします。
「RTCPeerConnection関連の関数」コード部の「OfferSDPの設定とAnswerSDPの作成」関数の処理を変更します。
- AnswerSDPの送信について、DataChannelが開いていないときはサーバーを経由して送信し、DataChannelが開いているときはDataChannelを通して送信するようにします。
ICE candidate イベントが発生したときのイベントハンドラ
DataChannelが開いているときは、ICE candidateの送信を、DataChannelを通して行うようにします。
「RTCPeerConnection関連の関数」コード部の「RTCPeerConnectionオブジェクトのイベントハンドラの構築」の関数の「ICE
candidate イベントが発生したときのイベントハンドラ」の処理を変更します。
- ICE candidateの送信について、DataChannelが開いていないときはサーバーを経由して送信し、DataChannelが開いているときはDataChannelを通して送信するようにします。
DataChannelオブジェクトのイベントハンドラの構築関数
「DataChannel関連の関数」コード部の「DataChannelオブジェクトのイベントハンドラの構築」の関数の「message イベントが発生したときのイベントハンドラ」の処理を変更します。
- Signalingメッセージに対する処理を追加します。
- 処理内容は、サーバーからのメッセージ受信に対する処理におけるSignalingメッセージの受信の処理と同様です。
Track イベントが発生したときのイベントハンドラ
「RTCPeerConnection関連の関数」コード部の「RTCPeerConnectionオブジェクトのイベントハンドラの構築」関数の「Track イベントが発生したときのイベントハンドラ」の処理を変更します。
- 「相手のメディアストリームがRTCPeerConnectionから削除されたときのイベントハンドラ」を追加します。
- 処理内容は、削除されたトラックの種類に対応したHTML要素に設定されたメディアストリームをクリアします。
動作確認
node でサーバーを起動します。
ブラウザを2つ立ち上げ、それぞれのブラウザで「localhost:1337」にアクセスします。
片方のブラウザで「Send OfferSDP」ボタンを押すと、ビデオチャットが開始します。
チャット相手がカメラを停止すると、リモート映像がクリアされます。
チャット相手が再度、カメラを開始すると、リモート映像が表示されます。
ダウンロード
デモ
デモ(Google App Engine) : https://my-video-chat.appspot.com/app12/index.html
デモ(Heroku) : https://myvideochat1234.herokuapp.com/app12/index.html
関連ページ
前項目 : 11. 独自データの送受信
次項目 : 13. チャット離脱の相手への通知