- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试设置一个基本的视频聊天示例。目前正在尝试在同一台计算机上的两个 Chrome 选项卡之间聊天。
一切看起来都很好,直到我获得远程视频流,当我使用 URL.createObjectURI
将其放入 remoteVideo
元素时,我什么也没有得到。尽管我收到了远程流事件,但没有视频显示。
什么会导致这种情况?有任何想法吗?请帮忙!
这是信号日志:
调用者:
Got userMedia
Registered signaling room
BY_WebRTC.startSession HOQfXIe3uoLMtDgSlHVH+A== true
VM9840:128 tryStart: created peer connection.
VM9840:150 Created RTCPeerConnnection
VM9840:133 tryStart: added stream to peer connection.
VM9840:170 Sending offer to peer
VM9840:184 sending sdp RTCSessionDescription {type: "offer", sdp: "v=0
↵o=- 3416476007859143551 2 IN IP4 127.0.0.1
↵s…9521 label:a8a8592f-d78d-40b2-bc1c-1a7c33772201
↵"}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3054232416 1 udp 2122260223 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3708192848 1 udp 2122194687 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3054232416 2 udp 2122260222 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3708192848 2 udp 2122194686 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3054232416 1 udp 2122260223 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "video", sdpMLineIndex: 1}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3708192848 1 udp 2122194687 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "video", sdpMLineIndex: 1}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3054232416 2 udp 2122260222 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "video", sdpMLineIndex: 1}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3708192848 2 udp 2122194686 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "video", sdpMLineIndex: 1}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:4169670544 1 tcp 1518280447 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:2474996896 1 tcp 1518214911 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:4169670544 2 tcp 1518280446 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:2474996896 2 tcp 1518214910 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:4169670544 1 tcp 1518280447 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "video", sdpMLineIndex: 1}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:2474996896 1 tcp 1518214911 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "video", sdpMLineIndex: 1}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:4169670544 2 tcp 1518280446 169.254.80.8… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 2", sdpMid: "video", sdpMLineIndex: 1}
VM9840:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:2474996896 2 tcp 1518214910 172.19.67.39… generation 0 ufrag Ab1ql0yuiJZgNzDJ network-id 1", sdpMid: "video", sdpMLineIndex: 1}
VM9840:110 Received answer
VM9840:207 Remote stream added. MediaStreamEvent {stream: MediaStream, type: "addstream", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
VM9840:191 handleIceCandidate event: null
VM9840:202 End of candidates.
被调用者:
Got User Media
Registered signaling room
Received offer
webrtc.js?v=2.22:128 tryStart: created peer connection.
webrtc.js?v=2.22:150 Created RTCPeerConnnection
webrtc.js?v=2.22:133 tryStart: added stream to peer connection.
webrtc.js?v=2.22:175 Sending answer to peer.
webrtc.js?v=2.22:207 Remote stream added. MediaStreamEvent {stream: MediaStream, type: "addstream", target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2…}
webrtc.js?v=2.22:184 sending sdp RTCSessionDescription {type: "answer", sdp: "v=0
↵o=- 1405083852183288173 2 IN IP4 127.0.0.1
↵s…5319 label:9a0427e6-be00-4a66-a862-77c1deafb89d
↵"}
webrtc.js?v=2.22:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3054232416 1 udp 2122260223 169.254.80.8… generation 0 ufrag wf8+wbbJ2eepjam8 network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
webrtc.js?v=2.22:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:3708192848 1 udp 2122194687 172.19.67.39… generation 0 ufrag wf8+wbbJ2eepjam8 network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
webrtc.js?v=2.22:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:4169670544 1 tcp 1518280447 169.254.80.8… generation 0 ufrag wf8+wbbJ2eepjam8 network-id 2", sdpMid: "audio", sdpMLineIndex: 0}
webrtc.js?v=2.22:191 handleIceCandidate event: RTCIceCandidate {candidate: "candidate:2474996896 1 tcp 1518214911 172.19.67.39… generation 0 ufrag wf8+wbbJ2eepjam8 network-id 1", sdpMid: "audio", sdpMLineIndex: 0}
webrtc.js?v=2.22:191 handleIceCandidate event: null
webrtc.js?v=2.22:202 End of candidates.
代码(在调用者的 startSession 处以 isInitiator=true 开始 - 获取本地媒体后):
var BY_WebRTC = {
// consts
pc_config: {
'iceServers': [
{ url: 'stun:stun1.l.google.com:19302' }]
},
pc_constraints: { 'optional': [{ 'DtlsSrtpKeyAgreement': true }] },
sdpConstraints: {
'mandatory': {
// Set up audio and video regardless of what devices are present.
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true
}
},
localStream: null,
remoteStream: null,
isStarted: false,
isInitiator: false,
realtimeEventId: null, // current conversation object realtime server room id
pc: null, // peer connection
getUserMedia: function (video, audio, callback) {
var constraints = { video: video, audio: audio };
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
BY_WebRTC.localStream = stream;
callback(stream);
}).catch(function (error) {
console.log("BY_WebRTC:getUserMedia Error!", error);
});
},
startSession: function (encryptedObjectId, isInitiator) {
// store the realtime event id
BY_WebRTC.realtimeEventId = { groupType: 'object', groupId: encryptedObjectId, eventType: "webrtc" };
BY_WebRTC.encryptedObjectId = encryptedObjectId;
// register chat room for webrtc signaling
nowManager.registerGroupEvents([BY_WebRTC.realtimeEventId], BY_WebRTC.realtimeWebRTC_EventHandler);
console.log("BY_WebRTC.startSession", encryptedObjectId, isInitiator);
if (isInitiator) {
BY_WebRTC.isInitiator = true;
BY_WebRTC.tryStart();
}
},
realtimeWebRTC_EventHandler: function (message) {
if (message === 'start') {
BY_WebRTC.tryStart();
}
else if (message.type === 'offer') {
console.log('Received offer');
if (!BY_WebRTC.isInitiator && !BY_WebRTC.isStarted) {
BY_WebRTC.tryStart();
}
BY_WebRTC.pc.setRemoteDescription(new RTCSessionDescription(message));
BY_WebRTC.sendAnswer();
}
else if (message.type === 'answer' && isStarted) {
console.log('Received answer');
BY_WebRTC.pc.setRemoteDescription(new RTCSessionDescription(message));
}
else if (message.type === 'candidate' && BY_WebRTC.isStarted) {
var candidate = new RTCIceCandidate({
sdpMLineIndex: message.label,
candidate: message.candidate
});
BY_WebRTC.pc.addIceCandidate(candidate);
}
else if (message === 'bye' && BY_WebRTC.isStarted) {
BY_WebRTC.handleRemoteHangup();
}
},
tryStart: function () {
if (!BY_WebRTC.isStarted && typeof BY_WebRTC.localStream != null) {
console.log("tryStart: created peer connection.");
BY_WebRTC.createPeerConnection();
BY_WebRTC.pc.addStream(BY_WebRTC.localStream);
console.log("tryStart: added stream to peer connection.");
isStarted = true;
if (BY_WebRTC.isInitiator) {
BY_WebRTC.sendOffer();
}
}
},
createPeerConnection: function () {
try {
var pc = new RTCPeerConnection(this.pc_config);
pc.onicecandidate = this.handleIceCandidate;
pc.onaddstream = this.handleRemoteStreamAdded;
pc.onremovestream = this.handleRemoteStreamRemoved;
console.log('Created RTCPeerConnnection');
BY_WebRTC.pc = pc;
} catch (e) {
console.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object.');
return;
}
},
handleCreateOfferError: function (event) {
console.log('sendOffer() error: ', e);
},
handleSendAnswerError: function (event) {
console.log('sendAnswer() error: ', e);
},
sendOffer: function () {
console.log('Sending offer to peer');
BY_WebRTC.pc.createOffer(BY_WebRTC.setLocalAndSendMessage, BY_WebRTC.handleCreateOfferError);
},
sendAnswer: function () {
console.log('Sending answer to peer.');
BY_WebRTC.pc.createAnswer(BY_WebRTC.setLocalAndSendMessage, BY_WebRTC.handleSendAnswerError, BY_WebRTC.sdpConstraints);
},
setLocalAndSendMessage: function (sessionDescription) {
// Set Opus as the preferred codec in SDP if Opus is present.
sessionDescription.sdp = BY_WebRTC.preferOpus(sessionDescription.sdp);
BY_WebRTC.pc.setLocalDescription(sessionDescription);
console.log("sending sdp", sessionDescription);
nowManager.sendGroupEvent(BY_WebRTC.realtimeEventId, sessionDescription);
},
handleIceCandidate: function (event) {
console.log('handleIceCandidate event: ', event.candidate);
if (event.candidate) {
nowManager.sendGroupEvent(BY_WebRTC.realtimeEventId, {
type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate
});
}
else {
console.log('End of candidates.');
}
},
handleRemoteStreamAdded: function (event) {
console.log('Remote stream added.', event);
// todo: send callback event after got remote stream
document.querySelector('#remoteVideo').src = window.URL.createObjectURL(event.stream);
BY_WebRTC.remoteStream = event.stream;
$("#remoteVideo").show();
},
handleRemoteStreamRemoved: function (event) {
console.log('Remote stream removed. Event: ', event);
},
hangup: function () {
console.log('Hanging up.');
this.stop();
nowManager.sendGroupEvent(this.realtimeEventId, "bye");
},
handleRemoteHangup: function () {
// console.log('Session terminated.');
// stop();
// isInitiator = false;
},
stop: function () {
BY_WebRTC.isStarted = false;
BY_WebRTC.pc.close();
BY_WebRTC.pc = null;
}
}
最佳答案
好的,我找到了答案!由于一些小错误(我没有 init isStarted = true ),我没有添加冰候选者。这是导致问题的原因。
关于javascript - webrtc pc.onaddstream window.URL.createObjectURl 远程视频未显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38424014/
我使用 WebRTC 连接 2 个 Chrome 浏览器。我在第一个客户端上创建 offer 并通过 signalR 将其发送给第二个客户端,如下所示: function initiate_call(
我正在使用 WebRTC 创建一个测试视频聊天应用程序。我有两个对等点成功连接。我想为用户添加一种“重新连接”的方式(断开连接并与另一个用户连接。出于测试目的,“其他”用户与以前的用户相同)。所以,当
我创建了以下脚本,它是混合应用程序的一部分,有时它可以正常运行,我可以接收/发送音频/视频调用,但有时 onaddstream 或 ontrack甚至没有从发送方调用,但 spd 数据包是通过套接字发
我正在尝试设置一个基本的视频聊天示例。目前正在尝试在同一台计算机上的两个 Chrome 选项卡之间聊天。 一切看起来都很好,直到我获得远程视频流,当我使用 URL.createObjectURI 将其
我是一名优秀的程序员,十分优秀!