WebRTC remoteVideo流没办法正常工作
问题说明
我添加了一个简单的webRTC应用程序,它将浏览器窗口连接到自身,从我的相机流式传输视频数据。最终目标是在页面上获得两个视频流,一个来自摄像头,另一个来自浏览器在本地制作的WebRTC连接。
I have added a simple webRTC application where it will connect a browser window to itself, streaming video data from the my camera. The end goal is to get two video streams on the page, one coming from the camera directly and the other coming from a WebRTC connection that the browser has made locally.
不幸的是远程视频流未显示。知道为什么吗?
Unfortunately the remote video stream is not showing up. Any idea why?
<video autoplay></video>
<video autoplay></video>
这里是javascript
And here's the 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.谷歌.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的书,并了解他对编码的所作所为。不幸的是,远程视频没有显示。
I'm following Dan Ristic's book on WebRTC and understood what he did with the coding. Unfortunately, the remote video is not showing up.
正确答案
添加 故障回调 让它发挥作用。不仅你不会看到错误,但这样做实际上会使它工作,这是一个非常奇怪的原因:
Add failure callbacks to make it work. Not only won't you see errors otherwise, but doing so will actually make it work, for a really weird reason:
你是一个名为WebIDL重载的东西的受害者。
正在发生的事情是有两个版本的WebRTC API,你正在混合它们。
You're a victim of something called WebIDL overloading. What's happening is there are two versions of the WebRTC API, and you're mixing them.
有一个现代承诺API ,例如:
pc.createOffer(options).then(successCallback, failureCallback);
和已弃用的回调版本,例如:
pc.createOffer(successCallback, failureCallback, options);
换句话说,有两个 createOffer
带有不同数量参数的函数。
In other words, there are two createOffer
functions that take different number of arguments.
不幸的是,你要点击第一个 createOffer
,因为你只是传递一个论点!第一个 createOffer
期望 options 对象与函数无法区分。因此它被视为有效参数(空选项对象)。即使这导致了 TypeError
,也不会导致异常,因为promise API会拒绝返回的promise而不是抛出异常:
Unfortunately, you're hitting the first createOffer
because you're only passing one argument! The first createOffer
expects an options object which unfortunately in WebIDL is indistinguishable from a function. It is therefore treated as a valid argument (an empty options object). Even if this had caused a TypeError
, it wouldn't have caused an exception, because promise APIs reject the returned promise instead of throwing an exception:
pc.createOffer(3).catch(e => console.log("Here: " e.name)); // Here: TypeError
您也没有检查返回的保证,因此错误会丢失。
You're not checking the returned promise either, so errors are lost.
这是一个工作版本( https小提琴对于Chrome):
Here's a working version (https fiddle for 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.谷歌.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 autoplay></video>
<video autoplay></video>
但回调很费力。我强烈推荐使用新的promise API( https for Chrome):
But callbacks are laborious. I highly recommend the new promise API instead (https for 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 autoplay muted></video>
<video autoplay></video><br>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /reply/detail/tanhcfggcg
-
YouTube API 不能在 iOS (iPhone/iPad) 工作,但在桌面浏览器工作正常?
it1352 07-30 -
iPhone,一张图像叠加到另一张图像上以创建要保存的新图像?(水印)
it1352 07-17 -
保持在后台运行的 iPhone 应用程序完全可操作
it1352 07-25 -
使用 iPhone 进行移动设备管理
it1352 07-23 -
在android同时打开手电筒和前置摄像头
it1352 09-28 -
扫描 NFC 标签时是否可以启动应用程序?
it1352 08-02 -
检查邮件是否发送成功
it1352 07-25 -
Android微调工具-删除当前选择
it1352 06-20 -
Android App 和三星 Galaxy S4 不兼容
it1352 07-20 -
希伯来语的空格句子标记化错误
it1352 06-22