2016-08-24 7 views
7

を呼び出すことなく、WebRTCで会話中にカメラを切り替えることができます。WebRTC:スイッチカメラ

{ 
    id: "id_source_1" | "id_source_2", 
    facing: "user" | "environment", 
    kind: "kind_1" | "kind_2", 
    label: "label_1" | "label_2" 
} 

私たちは、「source_1」(「ユーザー」を向いている)との通話を開始し、我々は、ユーザーが切り替えることができるようにしたい:

と仮定我々は2「mediaSources」MediaStreamTrack.getSources方法を使用してオブジェクトを持っています"source_2"( "環境"に面している)に移動します。私の現在のコードでは

ユーザーは次のように実行された「スイッチカメラ」ボタンをクリックした:(callingSessionは、現在のWebRTCセッションです)

var mediaParams = { 
     audio: true, 
     video: { deviceId : source_2.id}, 
     options: { 
      muted: true, 
      mirror: true 
     }, 
     elemId: 'localVideo' 
}; 

callingSession.getUserMedia(mediaParams, function (error, stream) { 
if (error) { 
    console.error('error getting user media'); 
} else { 
      var oldVideoTracks = callingSession.localStream.getVideoTracks();  
      var newVideoTracks = stream.getVideoTracks(); 

      if (oldVideoTracks.length > 0 && newVideoTracks.length > 0) { 
       callingSession.localStream.removeTrack(oldVideoTracks[0]); 
       callingSession.localStream.addTrack(newVideoTracks[0]); 
      } 
     } 
}); 

あなたがmediaParams制約を見ることができるようになりましたに設定されています"source_2"では、getUserMediaメソッドに新しい制約付きのmediaParamsを渡します。次に、古いストリームと新しいストリームの両方からビデオトラックを取得します。

このコードの主な問題は、新しいストリームがgetUserMediaメソッドに渡されても、新しいストリームとまったく同じストリームなので、明らかに同じビデオトラックで、何も起こりません。カメラは切り替えられません!!!

私はこのコードで何か間違っていますか?なしでカメラを切り替える方法はありますか WebRTCのコールを再ネゴシエートしますか?実験方法はどうですか?applyConstraint()私はそれをクロムで見ることができませんか?

ありがとうございます。

UPDATE 私のWebRTCアプリは横断歩道とイオンアプリです=> WebViewが

+0

私は隔離して、ローカルで最初に2台のカメラを同時に見ることができるようにします(多くの電話機では、フロントとバックカメラを同時に使用できません)。また、 'video:{deviceId:{exact:source_2.id}}'を使って制約を強制します。最後に、 'MediaStreamTrack.getSources'は' navigator.mediaDevices.enumerateDevices'に取って代わられました。それがうまくいく場合は、ピア接続の前にストリームを削除してから、もう一度追加してみてください。 – jib

+0

@jib現在の実装では、ソースをローカルに切り替えることができます(モバイルデバイスでも機能します)。私はピアに送信されたストリームを切り替えることができません。 – dafriskymonkey

+1

私はChromeのエキスパートではありません(これはFirefoxで 'replaceTrack'をサポートしていますが問題ありません)。しかし、Chromeではまだあなたは[再交渉する]必要があると思います(http://stackoverflow.com/questions/35504214/どのようにaddtrack-in-mediastream-in-webrtc/35515536​​#35515536​​)、これはデータチャネル上で行うことができるので、シームレスに近いでしょう。 – jib

答えて

1

replaceTrack APIはこのためだけに定義されたクロムです。

最終的にクロムはRTCRtpSender.replaceTrackメソッド(http://w3c.github.io/webrtc-pc/#rtcrtpsender-interface)をサポートします。これは、再交渉なしでトラックを置き換えるために使用できます。 Chromeでその機能の開発状況を追跡できます。https://www.chromestatus.com/feature/5347809238712320

これは、ネイティブAPIで既に一部利用可能です。しかし、現在開発中ですので、あなた自身の責任で使用してください。

+0

'getUserMedia'の' stream'が 'callingSession.localStream'とまったく同じなので' replaceTrack'の使い方は分かりません – dafriskymonkey

5

この記事を書いている時点で、WebRTC specificationは非常に有望ですが、依然としてこの仕様の実装はブラウザによって異なります。現在のところ、Chromeの実装はまだ古いです。それにもかかわらず、ジブのコメントのおかげで、このSO answerへの理解と、SDP (Session Description Protocol)の理解が増しました。これで、Chromeを使用してカメラを切り替えることができます。我々はピア接続からの現在のストリームを削除する必要がmediaParams引数でgetUserMediaを呼び出した後

var mediaParams = { 
      // the other constraints 
      video: {mandatory: {sourceId: source_2.id}} 
      // ... 
     }; 

:私のgetUserMedia方法に

まず制約は、ここで私は右の制約を渡すために管理方法です、間違っていました、コードの

peerConnection.removeStream(peerConnection.getLocalStreams()[0]); 
peerConnection.addLocalStream(stream); 

これらの2行はpeerConnectionオブジェクト上onnegotiationneededをトリガするピア1つの必須を意味する。このような新しいものを追加tell peer 2彼は新しい記述が必要なようにストリームを変更しました。ザッツなぜ我々はオファーを作成する必要があり、新しい説明を設定し、ピアにこの新しい説明を送信する:あなたはSDPをsendしたいどのように

peerConnection.createOffer() 
.then(function (offer) { 
     peerConnection.setLocalDescription(offer); 
}) 
.then(function() { 
     send(JSON.stringify({ "sdp": peerConnection.localDescription })); 
}); 

この時点でそのアップ。 (私のユースケースでは、私は、WebSocketをを使用してそれらを送信する必要がありました。)

他のピアは、彼は彼自身のピア接続でそれを設定する必要があり、新たなSDPを受信すると:

var obj = JSON.parse(answer).sdp; 
peerConnection.setRemoteDescription(new RTCSessionDescription(obj)); 

を、私は、これはいつか誰かを助けることを願っています。

+0

ありがとう! 私はこれで私の12時間を無駄にして、あなたの答えは私の一日を作った。しかし、私はカメラの顔を切り替えるときに直面している問題があります。カメラが3〜4回向き合っていると、ビデオ通話が切断されます。 問題はoniceconnectionstatechangedにあります。 – hamzox

+0

@hamzox正確な詳細を思い出すことはありませんが、何らかの理由で 'onnegotiationneeded'が2回トリガされます。私はブール値を作成しました。私は 'onnegotiationneeded'コールバックでブール値の状態を切り替えました。ブール値が' true'なら 'peerConnection.createOffer'を実行します。これは' createOffer'が2.そのハックは確かに、しかし、私はこれでより多くの時間を無駄にしたくない;)これが助けて欲しい – dafriskymonkey