我正在使用simple-peer来简化webrtc的使用,一切都在正常工作。但我面临一个问题,当广播员开始流和观众加入流,没有视频显示给观众。但是如果广播员刷新他的页面,视频就会显示在观看者那边。
广播员.js
componentDidMount() {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
})
.then(stream => {
// Display own video
if("srcObject" in this.localVideo.current) {
this.localVideo.current.srcObject = stream;
}
else {
this.localVideo.current.src = window.URL.createObjectURL(stream);
}
// Stream video to attendees
this.gotMedia(stream);
})
.catch(error => {
console.error(error);
});
}
gotMedia = (stream) => {
const broadcaster = new Peer({ initiator: true, stream: stream });
broadcaster.on("signal", data => {
this.socket.emit("signal", data);
});
this.socket.on("signal", data => {
broadcaster.signal(data);
});
};
观看者.js
componentDidMount() {
const attendee = new Peer();
attendee.on("signal", data => {
this.socket.emit("signal", data);
});
this.socket.on("signal", data => {
attendee.signal(data);
});
// Get remote video stream and display it
attendee.on("stream", stream => {
if("srcObject" in this.remoteVideo.current) {
this.remoteVideo.current.srcObject = stream;
}
else {
this.remoteVideo.current.src = window.URL.createObjectURL(stream);
}
});
}
浏览器.js
// Handle socket connections
io.on("connection", socket => {
socket.on("signal", (data) => {
socket.broadcast.emit("signal", data);
});
});
之所以会出现这种情况,是因为广播员在发出信号后,会立即发送信号。所以信号只会由广播公司发送一次,当观看者以后连接时,就不会收到任何信号。
为了解决这个问题,可以先设置查看器,并要求广播公司建立一个新的连接。
在这个 github项目 你可以看到一个例子,在这个例子中,有两个以上的对等体可以同时连接。
这里是一个实现。
Broadcaster.js
// this method is the same
componentDidMount() {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
})
.then(stream => {
// Display own video
if("srcObject" in this.localVideo.current) {
this.localVideo.current.srcObject = stream;
}
else {
this.localVideo.current.src = window.URL.createObjectURL(stream);
}
// Stream video to attendees
this.gotMedia(stream);
})
.catch(error => {
console.error(error);
});
}
// new way to handle
gotMedia = (stream) => {
this.localStream = stream
this.broadcaster = new Peer({ initiator: true, stream: this.localStream });
this.broadcaster.on("signal", data => {
this.socket.emit("signal", data);
});
// destroy current peerconnection and create a new one
this.socket.on("startConnection", () => {
if(this.broadcaster) this.broadcaster.destroy()
this.broadcaster = new Peer({ initiator: true, stream: this.localStream });
this.broadcaster.on("signal", data => {
this.socket.emit("signal", data);
});
});
this.socket.on("signal", data => {
this.broadcaster.signal(data);
});
};
浏览器.js
componentDidMount() {
const attendee = new Peer();
attendee.on("signal", data => {
this.socket.emit("signal", data);
});
this.socket.on("signal", data => {
attendee.signal(data);
});
// Get remote video stream and display it
attendee.on("stream", stream => {
if("srcObject" in this.remoteVideo.current) {
this.remoteVideo.current.srcObject = stream;
}
else {
this.remoteVideo.current.src = window.URL.createObjectURL(stream);
}
});
// Ask broadcaster to start his connection
this.socket.emit("startConnection")
}
浏览器.js
// Handle socket connections
io.on("connection", socket => {
socket.on("startConnection", () => {
socket.broadcast.emit("startConnection")
});
socket.on("signal", (data) => {
socket.broadcast.emit("signal", data);
});
});