gpt4 book ai didi

javascript - WebRTC 远程视频流不工作

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:31:22 26 4
gpt4 key购买 nike

我添加了一个简单的 webRTC 应用程序,它将浏览器窗口连接到自身,从我的相机流式传输视频数据。最终目标是在页面上获得两个视频流,一个直接来自摄像头,另一个来自浏览器在本地建立的 WebRTC 连接。

很遗憾,远程视频流没有显示。知道为什么吗?

<video id="yours" autoplay></video>
<video id="theirs" autoplay></video>

这是javascript

function hasUserMedia() {
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
navigator.msGetUserMedia;

return !!navigator.getUserMedia;
}

function hasRTCPeerConnection() {
window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection
|| window.mozRTCPeerConnection;

return !!window.RTCPeerConnection;
}

var yourVideo = document.querySelector('#yours'),
theirVideo = document.querySelector('#theirs'),
yourConnection, theirConnection;


if (hasUserMedia()) {
navigator.getUserMedia({ video: true, audio: false }, function(stream) {
yourVideo.src = window.URL.createObjectURL(stream);
if (hasRTCPeerConnection()) {
startPeerConnection(stream);
} else {
alert("Sorry, your browser does not support WebRTC.");
}
}, function (error) {
console.log(error);
});
}else{
alert("Sorry, your browser does not support WebRTC.");
}


function startPeerConnection(stream){
var configuration = {
"iceServers": [{ "url": "stun:stun.1.google.com:19302"
}]
};

yourConnection = new RTCPeerConnection(configuration);
theirConnection = new RTCPeerConnection(configuration);



// Setup stream listening
yourConnection.addStream(stream);

theirConnection.onaddstream = function (event) {
theirVideo.src = window.URL.createObjectURL(event.stream);
console.log('stream added');
};

// console.log(yourConnection);
//console.log(theirConnection);

// Setup ice handling
yourConnection.onicecandidate = function (event) {
if (event.candidate) {
theirConnection.addIceCandidate(new RTCIceCandidate(event.
candidate));
}
};
theirConnection.onicecandidate = function (event) {
if (event.candidate) {
yourConnection.addIceCandidate(new RTCIceCandidate(event.
candidate));
}
};

// Begin the offer
yourConnection.createOffer(function (offer) {
yourConnection.setLocalDescription(offer);
theirConnection.setRemoteDescription(offer);

theirConnection.createAnswer(function (offer) {
theirConnection.setLocalDescription(offer);
yourConnection.setRemoteDescription(offer);
});
});
};

我正在关注 Dan Ristic 关于 WebRTC 的书,并了解他对编码所做的工作。不幸的是,远程视频没有显示。

最佳答案

添加失败回调使其正常工作。否则你不仅不会看到错误,而且这样做实际上会使它工作,原因很奇怪:

您是 WebIDL 重载的受害者。发生的情况是有两个版本的 WebRTC API,而您正在混合使用它们。

有一个 modern promise API ,例如:

pc.createOffer(options).then(successCallback, failureCallback);

和一个deprecated callback version ,例如:

pc.createOffer(successCallback, failureCallback, options);

换句话说,有两个 createOffer 函数接受不同数量的参数。

不幸的是,您正在点击第一个 createOffer,因为您只传递了一个参数!第一个 createOffer 需要 options不幸的是,在 WebIDL 中,对象与函数无法区分。因此,它被视为有效参数(空选项对象)。即使这导致了 TypeError,它也不会导致异常,因为 promise API 拒绝返回的 promise 而不是抛出异常:

pc.createOffer(3).catch(e => console.log("Here: "+ e.name)); // Here: TypeError

您也没有检查返回的 promise ,因此错误会丢失。

这是一个工作版本(https fiddle 用于 Chrome):

navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
window.RTCPeerConnection = window.RTCPeerConnection ||
window.webkitRTCPeerConnection;

var yourConnection, theirConnection;

navigator.getUserMedia({ video: true, audio: false }, function(stream) {
yourVideo.src = window.URL.createObjectURL(stream);

var config = { "iceServers": [{ "urls": "stun:stun.1.google.com:19302"}] };
yourConnection = new RTCPeerConnection(config);
theirConnection = new RTCPeerConnection(config);

yourConnection.addStream(stream);

theirConnection.onaddstream = function (event) {
theirVideo.src = window.URL.createObjectURL(event.stream);
};

yourConnection.onicecandidate = function (e) {
if (e.candidate) {
theirConnection.addIceCandidate(new RTCIceCandidate(e.candidate),
success, failure);
}
};
theirConnection.onicecandidate = function (e) {
if (e.candidate) {
yourConnection.addIceCandidate(new RTCIceCandidate(e.candidate),
success, failure);
}
};

yourConnection.createOffer(function (offer) {
yourConnection.setLocalDescription(offer, success, failure);
theirConnection.setRemoteDescription(offer, success, failure);
theirConnection.createAnswer(function (offer) {
theirConnection.setLocalDescription(offer, success, failure);
yourConnection.setRemoteDescription(offer, success, failure);
}, failure);
}, failure);
}, failure);

function success() {};
function failure(e) { console.log(e); };
<video id="yourVideo" width="160" height="120" autoplay></video>
<video id="theirVideo" width="160" height="120" autoplay></video>

但是回调很费力。我强烈建议改用新的 promise API(https 用于 Chrome):

var pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();

navigator.mediaDevices.getUserMedia({video: true, audio: true})
.then(stream => pc1.addStream(video1.srcObject = stream))
.catch(log);

var add = (pc, can) => pc.addIceCandidate(can).catch(log);
pc1.onicecandidate = e => add(pc2, e.candidate);
pc2.onicecandidate = e => add(pc1, e.candidate);

pc2.ontrack = e => video2.srcObject = e.streams[0];
pc1.oniceconnectionstatechange = e => log(pc1.iceConnectionState);
pc1.onnegotiationneeded = e =>
pc1.createOffer().then(d => pc1.setLocalDescription(d))
.then(() => pc2.setRemoteDescription(pc1.localDescription))
.then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
.then(() => pc1.setRemoteDescription(pc2.localDescription))
.catch(log);

var log = msg => console.log(msg);
<video id="video1" height="120" width="160" autoplay muted></video>
<video id="video2" height="120" width="160" autoplay></video><br>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

关于javascript - WebRTC 远程视频流不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38279635/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com