Изменение MediaStream RTCPeerConnection
Я хочу перейти с аудио- / видеопотока на поток с разделением экрана:
peerConnection.removeStream(streamA) // __o_j_sep... in Screenshots below
peerConnection.addStream(streamB) // SSTREAM in Screenshots below
streamA
это видео / аудио поток с моей камеры и микрофона.streamB
это скриншот, который я получаю от моего расширения.- Оба объекта MediaStream выглядят так:
* 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
(Да, это выглядит неправильно, но нет официального способа получить доступ к одноранговому соединению, см. Обсуждение здесь) и здесь.
Первоначально я пытался просто (ex) изменить videoTracks streamA
с видео-треком streamB
, Смотрите вопрос здесь. Мне было предложено попытаться пересмотреть одноранговое соединение (удалив / добавив к нему потоки), потому что 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
:
Я бегу:
- OS X 10.9.3
- Версия Chrome 35.0.1916.153
2 ответа
Чтобы ответить на ваш первый вопрос, при изменении MediaStream в активном одноранговом соединении объект однорангового соединения вызовет onnegotiationneeded
событие. Вы должны обработать это событие и повторно обменять свои SDP. Основная причина этого заключается в том, что обе стороны знают, какие потоки передаются между ними. Когда SDP обмениваются, включается идентификатор mediaStream, и, если есть новый поток с новым идентификатором (событие при прочих равных условиях), необходимо выполнить повторное согласование.
Для вас второй вопрос (о SSTREAM
). Он действительно содержит видео-треки, но нет атрибута видеотрека для webkitMediaStreams
, Вы можете получить треки через их ID, однако.
Поскольку существует возможность иметь множество дорожек для каждого типа мультимедиа, для видеотрека или аудиотрека нет отдельного атрибута, а вместо этого имеется массив таких. .getVideoTracks()
Вызов возвращает массив текущих videoTracks. Таким образом, вы МОЖЕТЕ получить определенную видео дорожку, указав ее индекс .getVideoTracks()[0]
,
Я делаю нечто подобное, нажимая на кнопку, я удаляю активный поток и добавляю другой.
Это то, как я это делаю, и это прекрасно работает для меня,
_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 не поддерживает звук вместе с "экраном", поэтому я создаю для него отдельный поток. Вам нужно будет сделать наоборот, чтобы переключиться обратно на ваш старый видеопоток или фактически на любой другой поток, который вы хотите.
Надеюсь это поможет