Изменение MediaStream RTCPeerConnection
Я хочу переключиться с аудио/видеопотока на поток с экранами:
peerConnection.removeStream(streamA) // __o_j_sep... in Screenshots below
peerConnection.addStream(streamB) // SSTREAM in Screenshots below
-
streamA
- это видео/аудиопоток, поступающий с моей камеры и микрофона.
-
streamB
- это screencapture, который я получаю от моего расширения.
- Они представляют собой MediaStream объекты, которые выглядят следующим образом:
![streamA]()
![streamB]()
* 1 Замечание
Но если я удаляю streamA
из peerConnection
и addStream(streamB)
, как показано выше, ничего не происходит.
Следующее работает как ожидалось (поток с обоих концов удаляется и добавляется)
peerConnection.removeStream(streamA) // __o_j_sep...
peerConnection.addStream(streamA) // __o_j_sep...
Подробнее
Я нашел этот пример, который делает "обратный" (переключение с экрана на аудио/видео с камерой), но не может заметьте существенную разницу.
Объект peerConnection
RTCPeerConnection фактически создан этим Библиотека SIPML исходный код, доступный здесь. И я обращаюсь к нему так:
var peerConnection = stack.o_stack.o_layer_dialog.ao_dialogs[1].o_msession_mgr.ao_sessions[0].o_pc
(Да, это выглядит неправильно, но нет официального способа получить доступ к Peer Connection см. обсуждение здесь) и здесь.
Изначально я попытался просто (ex) изменить видеотреки streamA
с помощью видеодрайвера streamB
. См. вопрос здесь. Мне было предложено, чтобы я попытался пересмотреть соединение Peer (удалив/добавив Streams к нему), потому что addTrack не запускает повторное обсуждение.
Я также просил о помощи здесь, но сопровождающий кажется очень занятым и еще не получил ответа.
* 1 Примечание: Почему streamB
не имеет свойства videoTracks
? Поток играет в элементе HTML <video>
и, кажется, "работает". Вот как я это понимаю:
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: streamId,
maxWidth: window.screen.width,
maxHeight: window.screen.height
//, maxFrameRate: 3
}
}
// success callback
}, function(localMediaStream) {
SSTREAM = localMediaStream; //streamB
// fail callback
}, function(error) {
console.log(error);
});
он также имеет videoTrack
:
![videoTrack of streamB]()
Я запускаю:
- OS X 10.9.3
- Версия Chrome 35.0.1916.153
Ответы
Ответ 1
Чтобы ответить на ваш первый вопрос, при изменении MediaStream в активном peerconnection объект peerconnection будет запускать событие onnegotiationneeded
. Вам необходимо обработать это событие и повторно обменять ваши SDP. Основная причина этого заключается в том, чтобы обе стороны знали, какие потоки передаются между ними. Когда обмены SDP обмениваются, включается идентификатор mediaStream, и если есть новый поток с новым идентификатором (событие, при котором все остальные вещи равны), необходимо провести повторное согласование.
Для вас второй вопрос (около SSTREAM
). Он действительно содержит видеодорожки, но нет атрибута видеозаписи для webkitMediaStreams
. Однако вы можете захватывать треки через их идентификатор.
Поскольку существует возможность иметь множество дорожек для каждого типа медиа, нет единого атрибута для видеотравы или аудиотрека, но вместо этого такой массив. Вызов .getVideoTracks()
возвращает массив текущих видеотреков. Таким образом, вы можете захватить конкретную видеодорожку, указав ее индекс .getVideoTracks()[0]
.
Ответ 2
Я делаю что-то подобное, при нажатии кнопки я удаляю активный поток и добавляю другой.
Так я это делаю, и он отлично работает для меня,
_this.rtc.localstream.stop();
_this.rtc.pc.removeStream(_this.rtc.localstream);
gotStream = function (localstream_aud){
var constraints_audio={
audio:true
}
_this.rtc.localstream_aud = localstream_aud;
_this.rtc.mediaConstraints= constraints_audio;
_this.rtc.createOffer();
}
getUserMedia(constraints_audio, gotStream);
gotStream = function (localstream){
var constraints_screen={
audio:false,
video:{
mandatory:{
chromeMediaSource: 'screen'
}
}
}
_this.rtc.localstream = localstream;
_this.rtc.mediaConstraints=constraints_video;
_this.rtc.createStream();
_this.rtc.createOffer();
}
getUserMedia(constraints_video, gotStream);
Chrome не позволяет аудио вместе с "экраном", поэтому я создаю для него отдельный поток.
Вам нужно будет сделать обратное, чтобы переключиться обратно на старый видеопоток или на любой другой поток, который вы хотите.
Надеюсь, что это поможет