- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 WebRTC + Socket.io 制作一个屏幕共享应用程序,但卡在一个地方。使用WebRTC + Socket.io连接两个浏览器并且可以发送文本
我正在接受 codelab 的支持但它不适用于流。(如果解决方案基于此链接,则非常有帮助)
如何发送 getUserMedia() 流:
dataChannel.send(stream);
并在channel.onmessage()上接收相同的流:我将 event.data 作为“[object MediaStream]”而不是流获取。
channel.onmessage = function(event){
// unable to get correct stream
// event.data is "[object MediaStream]" in string
}
function createPeerConnection(isInitiator, config) {
console.log('Creating Peer connection as initiator?', isInitiator, 'config:', config);
peerConn = new RTCPeerConnection(config);
// send any ice candidates to the other peer
peerConn.onicecandidate = function (event) {
console.log('onIceCandidate event:', event);
if (event.candidate) {
sendMessage({
type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate
});
} else {
console.log('End of candidates.');
}
};
if (isInitiator) {
console.log('Creating Data Channel');
dataChannel = peerConn.createDataChannel("screen");
onDataChannelCreated(dataChannel);
console.log('Creating an offer');
peerConn.createOffer(onLocalSessionCreated, logError);
} else {
peerConn.ondatachannel = function (event) {
console.log('ondatachannel:', event.channel);
dataChannel = event.channel;
onDataChannelCreated(dataChannel);
};
}
}
它对于字符串或 json 工作正常,即 dataChannel.send('Hello');
我已经创建了一个相同的维基页面:wiki
请帮忙。
最佳答案
请尝试这样的操作:(代码末尾有说明)
var btnShareYourCamera = document.querySelector('#share-your-camera');
var localVideo = document.querySelector('#local-video');
var remoteVideo = document.querySelector('#remote-video');
var websocket = new WebSocket('wss://path-to-server:port/');
websocket.onmessage = function(event) {
var data = JSON.parse(event.data);
if (data.sdp) {
if (data.sdp.type === 'offer') {
getUserMedia(function(video_stream) {
localVideo.srcObject = video_stream;
answererPeer(new RTCSessionDescription(data.sdp), video_stream);
});
}
if (data.sdp.type === 'answer') {
offerer.setRemoteDescription(new RTCSessionDescription(data.sdp));
}
}
if (data.candidate) {
addIceCandidate((offerer || answerer), new RTCIceCandidate(data.candidate));
}
};
var iceTransportPolicy = 'all';
var iceTransportLimitation = 'udp';
function addIceCandidate(peer, candidate) {
if (iceTransportLimitation === 'tcp') {
if (candidate.candidate.toLowerCase().indexOf('tcp') === -1) {
return; // ignore UDP
}
}
peer.addIceCandidate(candidate);
}
var offerer, answerer;
var iceServers = {
iceServers: [{
'urls': [
'stun:stun.l.google.com:19302',
'stun:stun1.l.google.com:19302',
'stun:stun2.l.google.com:19302',
'stun:stun.l.google.com:19302?transport=udp',
]
}],
iceTransportPolicy: iceTransportPolicy,
rtcpMuxPolicy: 'require',
bundlePolicy: 'max-bundle'
};
// https://https;//cdn.webrtc-experiment.com/IceServersHandler.js
if (typeof IceServersHandler !== 'undefined') {
iceServers.iceServers = IceServersHandler.getIceServers();
}
var mediaConstraints = {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
};
/* offerer */
function offererPeer(video_stream) {
offerer = new RTCPeerConnection(iceServers);
offerer.idx = 1;
video_stream.getTracks().forEach(function(track) {
offerer.addTrack(track, video_stream);
});
offerer.ontrack = function(event) {
remoteVideo.srcObject = event.streams[0];
};
offerer.onicecandidate = function(event) {
if (!event || !event.candidate) return;
websocket.send(JSON.stringify({
candidate: event.candidate
}));
};
offerer.createOffer(mediaConstraints).then(function(offer) {
offerer.setLocalDescription(offer).then(function() {
websocket.send(JSON.stringify({
sdp: offer
}));
});
});
}
/* answerer */
function answererPeer(offer, video_stream) {
answerer = new RTCPeerConnection(iceServers);
answerer.idx = 2;
video_stream.getTracks().forEach(function(track) {
answerer.addTrack(track, video_stream);
});
answerer.ontrack = function(event) {
remoteVideo.srcObject = event.streams[0];
};
answerer.onicecandidate = function(event) {
if (!event || !event.candidate) return;
websocket.send(JSON.stringify({
candidate: event.candidate
}));
};
answerer.setRemoteDescription(offer).then(function() {
answerer.createAnswer(mediaConstraints).then(function(answer) {
answerer.setLocalDescription(answer).then(function() {
websocket.send(JSON.stringify({
sdp: answer
}));
});
});
});
}
var video_constraints = {
mandatory: {},
optional: []
};
function getUserMedia(successCallback) {
function errorCallback(e) {
alert(JSON.stringify(e, null, '\t'));
}
var mediaConstraints = {
video: true,
audio: true
};
navigator.mediaDevices.getUserMedia(mediaConstraints).then(successCallback).catch(errorCallback);
}
btnShareYourCamera.onclick = function() {
getUserMedia(function(video_stream) {
localVideo.srcObject = video_stream;
offererPeer(video_stream);
});
};
peer.addTrack
附加流,如上面的示例所示peer.ontrack
接收远程流,如上例所示即使用 addTrack
连接相机并使用 ontrack
接收远程相机。
您绝不能使用dataChannel.send
发送流。两者是完全不同的协议(protocol)。 MediaStream
必须使用 RTP 共享;不是 SCTP。仅当您调用 peer.addTrack
方法附加相机流时才使用 RTP。
此过程发生在您打开或加入房间之前。
在此处查看单页演示:https://www.webrtc-experiment.com/getStats/
上述代码片段的 HTML:
<button id="share-your-camera"></button>
<video id="local-video" controls autoplay playsinline></video>
<video id="remote-video" controls autoplay playsinline></video>
关于javascript - 如何发送和接收通过 getUsermedia() 生成的桌面捕获流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53731348/
我们正在尝试制作视频 session 应用程序。在 Windows 上运行该应用程序进行测试时,视频打开得很好,但是当我们在物理设备(Android 手机)上运行它时,出现以下错误并且视频不显示。 E
我知道有几篇关于此的帖子,但我的问题不同。 在 Mozilla developer guide for getUserMedia 之后,我可以看到使用:navigator.getUserMedia()
我正在使用“facingMode”约束来在两个摄像头之间切换,但我不能完全确定用户端是否有一个“环境”摄像头(后置摄像头)。计算 enumerateDevices 函数返回的 promise 的“视频
这是我的问题。 我正在制作一个使用 JS-OCR 拍照并检测单词的小应用程序。它运作良好,但我只能使用前置摄像头。我的想法是只使用后置摄像头,没有必要切换摄像头。 我正在阅读 getUserMedia
我正在为相机和麦克风运行 getUserMedia, navigator.mediaDevices .getUserMedia({audio:true, video: true)
我在使用 getUserMedia 创建的预览视频时遇到问题。视频会连接,但只显示第一帧或第二帧,并在它们之间快速切换。使用 ImageCapture 时,我仍然可以获取相机所面对的画面,但预览窗口停
我有以下限制,这些限制在桌面上的 Chrome 上运行良好(模拟移动分辨率) const constraints = { audio: false, video: {
例如,假设我有 然后我开始流式传输视频: async function startVideo() { const video = document.querySelector("#video
我尝试使用 cordova + crosswalk 显示来 self 的手机摄像头的视频,并且可以从 getUserMedia() 获取视频流,但是当流显示在 html5 视频标签上时,它显示黑屏。
有什么方法可以使用HTML5的getUserMedia()从特定麦克风(而不是默认麦克风)获取音频输入? 最佳答案 恐怕您将需要使用getSources API,该API到目前为止还没有得到很好的支持
我正在使用getUserMedia api捕获屏幕并记录来自chrome扩展程序的音频(两者一起)。 api捕获屏幕,记录视频,但不捕获音频。 Chrome版本:55 没有捕获音频的任何原因。 API
我使用“前沿”HTML5/WebRTC API 编写了一个 Web 应用程序(请参阅下面的代码)。这适用于 Chrome v20(启用了 MediaStream 标志)和最新的 FF Nightly
我在网上找到了一些代码来访问我的网络摄像头。它访问网络摄像头,但不显示它所看到的内容。我知道这是正常的,因为文档中没有 html,但我想知道如何显示结果。我找到的代码是: var constraint
我正在尝试通过 webRTC 和 GetUserMedia 共享计算机的音频,但我不知道是否可以获取此流。 在 Linux 和 Firefox 上,当我请求具有以下约束的 GetUserMedia 时
我正在使用 getusermedia() 将网络摄像头用于在线应用程序。我使用的是罗技 C615 网络摄像头(即插即用),效果很好。 getusermedia() 将仅适用于即插即用网络摄像头,还是也
我无法在 Google Chrome (v21) 中显示视频流 代码 window.addEventListener('DOMContentLoaded', function() { n
如何在 javascript 中获取流对象的当前流时间? navigator.mediaDevices.getUserMedia(约束) .then(函数(流){ console.log("在此处获取
我一直在为我的下一个项目尝试使用 webRTC 创建视频聊天,但测试很困难。我有这个简单的代码来访问相机: navigator.getUserMedia = navigator.get
我正在使用 HTML 媒体捕获和 getUserMedia 方法。它不适用于 Chrome,我收到失败时的警报。 这是我使用的示例代码: if (navigator.getUserMedia) {
我知道 iOS 不支持 getUserMedia()。有没有办法绕过它,在 iOS 和 Android 移动浏览器上流式传输视频或从视频流中捕获图像? 最佳答案 我建议查看 Video 元素“srcO
我是一名优秀的程序员,十分优秀!