これで髪を抜いています。1か月ほど前、SignalRの優秀な人々からのサンプルコードを使用して、概念実証WebRTCデモをまとめることができました。デモはここにあり、そのソースはここにあり、本来の機能を果たします。
しかし、そのコードを実際のアプリケーションに移動したとき、それを機能させることができませんでした。もちろん、コードを大幅に変更する必要がありました。さまざまなバックエンド、さまざまなフレームワークのセット、サポートコード、複数の同時接続のサポートなどですが、コアロジックは非常に似ています。しかし、私はそれを機能させることができません。
問題を示すサンプルアプリをここにまとめました。
https://bitbucket.org/smithkl42/signalr.webrtc
コアWebRTCロジックは、すべてこのTypeScriptファイルに含まれています。
数百行なので、ここに投稿することはしませんが、上のリンクをクリックすると表示されます。
実行すると、次のような出力が生成されます。
12:17:58.531 WebRTCController.call():準備が完了したときに7d9e0d39-5047-4afe-86e5-e6e01b9f5955を呼び出します
12:17:58.533 WebRTCController.prepareForCall():呼び出しの準備:localSessionId = '39d2df53-6854-415a-8748-b5230eda2eb1'; remoteSessionId = '7d9e0d39-5047-4afe-86e5-e6e01b9f5955'
12:18:0.139 Object。():ユーザーがメディアデバイスへのアクセスを許可したため、通話の準備に進みます
12:18:0.141 Connection.createPeerConnection():ピア接続を作成しています。stunServerの使用stun:stun1.l.google.com:19302
12:18:0.144():準備が終了しました。JSEPオファーの作成と送信。Util.js:21
12:18:0.272 Connection.handleIceCandidate():STUNサーバーがICE候補を検出しました(event.type ='icecandidate')。
12:18:0.282 Connection.handleIceCandidate():STUNサーバーがICE候補を検出しました(event.type ='icecandidate')。
(もっとそのように)
12:18:0.655 WebRTCController.handleJsepAnswer():7d9e0d39-5047-4afe-86e5-e6e01b9f5955からのJsepAnswerの処理
12:18:0.694 Object。():ICE候補をリモートマシンに送信しています:{"sdpMLineIndex":0、 "sdpMid": "audio"、 "candidate": "a = candidate:2999745851 1 udp 2113937151 192.168.56.1 62978 typホスト生成0\r \ n "}
12:18:0.706 Object。():ICE候補をリモートマシンに送信しています:{"sdpMLineIndex":0、 "sdpMid": "audio"、 "candidate": "a = candidate:2999745851 2 udp 2113937151 192.168.56.1 62978 typホスト生成0\r \ n "}
(もっとそのように)
しかし、その後は接続されません。つまり、反対側からのビデオの再生が開始されることはありません。シグナリングレイヤーでは、ログとコードをステップスルーすることで、最初のブラウザーがJSEPオファーを送信していることを確認できます。2番目のブラウザはそれを受信して保存し、適切なJSEP回答を送り返します。そして最初のマシンはその答えを保存しています。次に、各peerConnectionはICE候補を見つけて、それらをリモートマシンに送信します。そして、各peerConnectionは、それらのICE候補を受信し、明らかに試行しています。そしてpeerConnectionsはonaddstream
イベントを発生させています。ただし、ビデオの再生は開始されません。
ずっとpeerConnectionオブジェクトの状態は次のようになります:
(iceGatheringState=new; iceState=starting; readyState=active)
イライラするのは、20回に1回程度の頻度で機能することです。つまり、両方の動画が表示されます。だから私はすべてを間違っているわけではありません。ある種のタイミングの問題のように聞こえますが、それが何であるかはわかりません。そして、私が知る限り、WebRTCオブジェクト(特にRTCPeerConnection)には、何が問題になっているのかを伝えるものはほとんどありません。
他の人にトラブルシューティングを依頼するのは嫌いですが...まあ、オプションが不足しています。他の誰かが私が明らかに間違っていることを見ていますか?
更新2012-12-19:私はいくつかの進歩を遂げています。peerConnection.setLocalDescription()
同期的に、つまりコールバックを指定せずに呼び出していることに気づきました。これで、次のようなコード行がいくつかあります。
// Answer the call by sending a JsepAnswer message.
connection.peerConnection.createAnswer(
answer => {
connection.peerConnection.setLocalDescription(answer, () => {
var signalState: mData.SignalState = {
FromSessionId: connection.localSessionId,
ToSessionId: connection.remoteSessionId,
Message: JSON.stringify(answer)
};
me.roomHub.server.jsepAnswer(signalState);
mUtil.log("Sent JSEP answer: " + signalState.Message);
connection.readyForIceCandidates.resolve();
},
error => {
mUtil.error("Error setting local description from created answer: " + error + "; answer=" + JSON.stringify(answer));
});
},
error => {
mUtil.error("Error creating answer: " + error);
}, me.mediaConstraints);
そして、setLocalDescription()
エラーコールバックはこのエラーを示しています:
16:14:42.439 WebRTCController.handleJsepOffer():作成された回答からのローカル記述の設定中にエラーが発生しました:SetLocalDescriptionが失敗しました。; answer = {"sdp": "v = 0 \ r \ no =-439659381 2 IN IP4 127.0.0.1 \ r \ ns =-\ r \ nt = 0 0 \ r \ na = group:BUNDLE audio video \ r \ na = msid-semantic:WMS u9fhVrWeLLweqb5ubLkw61Ijsh6BM6vZLhjf \ r \ nm = audio 1 RTP / SAVPF 103104111 0 8107106105 13126 \ r \ nc = IN IP4 0.0.0.0 \ r \ na = rtcp:1 INIP40.0。 0.0 \ r \ na = ice-ufrag:vOKflTJ56gV0R9i0 \ r \ na = ice-pwd:9nuXPMDvQ2mZATFCQyEzPRQz \ r \ na = sendrecv \ r \ na = mid:audio \ r \ na = rtcp-mux \ r \ na = crypto: 1 AES_CM_128_HMAC_SHA1_80インライン:m9q9pmLgLuFnfFC09KXKW5p8TjsKk + VdqX0OWv77 \ r \ na = rtpmap:103 ISAC / 16000 \ r \ na = rtpmap:104 ISAC / 32000 \ r \ na = rtpmap:111 opus / 48000/2 PCMU / 8000 \ r \ na = rtpmap:8 PCMA / 8000 \ r \ na = rtpmap:107 CN / 48000 \ r \ na = rtpmap:106 CN / 32000 \ r \ na = rtpmap:105 CN / 16000 \ r \ na = rtpmap:13 CN / 8000 \ r \ na = rtpmap:
ここで、メソッドから直接得られる特定のSDPcreateAnswer()
が失敗する理由を理解する必要があります。
更新2012-12-20:ここで問題のオンラインデモンストレーションを作成しました:http ://srdemo.alanta.com/ 。Chromeのデバッグログもオンにした結果、次のようなエラーが多数表示されます。
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
[6584:7308:1220/091356:ERROR:rtc_peer_connection_handler.cc(84)] Native session description is null.
彼らが私の問題とどのような関係にあるのかはわかりませんが、私はそれを調査し続けています。
* 2012年12月20日編集:問題を絞り込むことができました(私は思います)。より正確な詳細については、この質問を参照してください。