Video/Audio 通讯
Video/Audio communication
我正在尝试使用 peer/getUserMedia 创建视频会议 Web 应用程序。
目前,当我将唯一 ID 发送到视频会议时,我可以 hear/see 任何加入我 session 的人。
但是只有第一个加入我session的人才能communicate/see我
我想做到这一点,以便其他用户也可以 see/hear 视频会议中的每个用户。
到目前为止,这就是我目前所做的工作。还有当前编写的代码,每当有新用户加入时,我的视频就会再次添加,所以我会看到我自己的两个视频(如果我是主持人),但这对我来说很容易解决
<html>
<body>
<h3 id="show-peer"></h3>
<div style="display: grid; justify-content: space-around; margin:10px;">
<div style="width: 300px;height: 200px;transform: scale(-1, 1);border: 2px solid; display:grid; margin-bottom: 5%;" id="ourVideo"></div>
<div style="width: 300px;height: 200px;transform: scale(-1, 1);border: 2px solid; display: grid;" id="remoteVideo"></div>
</div>
<input id="peerID" placeholder="Peer ID">
<button id="call-peer" onclick="callPeer()">Call Peer</button>
<br>
<button id="screenShare"onclick="shareScreen()">Share Screen</button>
</body>
<script src="https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js"></script>
<script>
window.addEventListener('load',(event)=>{
var peer= new Peer()
var myStream;
var currentPeer;
var peerList=[];
peer.on('open',function(id){
document.getElementById("show-peer").innerHTML=id
})
peer.on('call',function(call){
navigator.mediaDevices.getUserMedia({
video:true,
audio:true
}).then((stream)=>{
myStream = stream
addOurVideo(stream)
call.answer(stream)
call.on('stream',function(remoteStream){
if(!peerList.includes(call.peer)){
addRemoteVideo(remoteStream)
currentPeer = call.peerConnection
peerList.push(call.peer)
}
})
}).catch((err)=>{
console.log(err+" unable to get media")
})
})
function stopScreenShare(){
let videoTrack = myStream.getVideoTracks()[0];
var sender = currentPeer.getSenders().find(function(s){
return s.track.kind ==videoTrack.kind;
})
sender.replaceTrack(videoTrack)
};
document.getElementById("call-peer").addEventListener('click',(e)=>{
let remotePeerId= document.getElementById("peerID").value;
document.getElementById("show-peer").innerHTML= "connecting "+remotePeerId;
console.log(remotePeerId)
callPeer(remotePeerId);
})
document.getElementById("screenShare").addEventListener('click',(e)=>{
navigator.mediaDevices.getDisplayMedia({
video: {
cursor: "always"
},
audio:{
autoGainControl: false,
echoCancellation: false,
googAutoGainControl: false,
noiseSuppression: false
}
}).then((stream)=>{
let videoTrack = stream.getVideoTracks()[0];
videoTrack.onended = function(){
stopScreenShare()
}
let sender = currentPeer.getSenders().find(function(s){
return s.track.kind == videoTrack.kind
})
sender.replaceTrack(videoTrack)
}).catch((err)=>{
console.log("unable to get display media"+err)
})
})
function callPeer(id){
navigator.mediaDevices.getUserMedia({
video:true,
audio:true
}).then((stream)=>{
myStream = stream
addOurVideo(stream)
let call = peer.call(id,stream)
call.on('stream',function(remoteStream){
if(!peerList.includes(call.peer)){
addRemoteVideo(remoteStream)
currentPeer = call.peerConnection
peerList.push(call.peer)
}
})
}).catch((err)=>{
console.log(err+" unable to get media")
})
}
function addRemoteVideo(stream){
let video = document.createElement("video");
video.classList.add("video")
video.srcObject = stream;
video.play()
document.getElementById("remoteVideo").append(video)
}
function addOurVideo(stream){
let video = document.createElement("video");
video.classList.add("video")
video.srcObject = stream;
video.play()
video.muted=true;
document.getElementById("ourVideo").append(video)
}
});
</script>
</html>
我认为您需要创建一个“网格”。因此,对于 3 个对等点,每个用户(对等点)建立两个连接,一个连接到另外两个用户中的每一个。在每个客户端,有两个完全不同的连接。
PeerJs GitHub 上的用户 @daGrevis asked this question。最终,这是他们用于 multi-peer 聊天的实现,可能会有所帮助:
Chat = React.createClass
displayName: "Foo"
getInitialState: ->
messages: []
connectionsToPeerIds: (connections) ->
_.map connections, (connection) => connection.peer
componentWillMount: ->
who = getSegments()[1]
peer = new Peer who, key: PEER_KEY, debug: 2
@connections = []
peer.on "error", (error) =>
alert error.type
peer.on "open", (peerId) =>
if who == "x"
peer.on "connection", (connection) =>
@connections.push connection
@listenForMessage connection
peerIds = @connectionsToPeerIds @connections
connection.on "open", =>
connectionsWithoutNewConnection = _.filter @connections, (c) -> c.peer != connection.peer
peerIdsWithoutNewConnection = @connectionsToPeerIds connectionsWithoutNewConnection
if peerIdsWithoutNewConnection.length
connection.send type: "newConnection", peerIds: peerIdsWithoutNewConnection
if who != "x"
connection = peer.connect "x"
connection.on "error", (error) =>
alert error
connection.on "open", =>
@connections.push connection
@listenForMessage connection
connection.on "data", (data) =>
if data.type == "newConnection"
peerIds = data.peerIds
_.forEach peerIds, (peerId) =>
connection = peer.connect peerId
do (connection) =>
connection.on "error", (error) =>
alert error.type
connection.on "open", =>
@connections.push connection
@listenForMessage connection
peer.on "connection", (connection) =>
connection.on "open", =>
@connections.push connection
@listenForMessage connection
然后我发现了一个实例,其中用户@mluketin used peerjs-server, and created a conference call example https://github.com/mluketin/peerjs-helloworld-conference
据我所知和阅读,网状设计似乎是最简单的方法,但受限于最慢对等体的速度。因此,如果您只需要 3-5 个人,应该没问题。否则,您可能必须遵循 mluketin 列出的示例。
更多可能有帮助的链接:
- Having multiple peers PeerJS?
我正在尝试使用 peer/getUserMedia 创建视频会议 Web 应用程序。
目前,当我将唯一 ID 发送到视频会议时,我可以 hear/see 任何加入我 session 的人。
但是只有第一个加入我session的人才能communicate/see我
我想做到这一点,以便其他用户也可以 see/hear 视频会议中的每个用户。
到目前为止,这就是我目前所做的工作。还有当前编写的代码,每当有新用户加入时,我的视频就会再次添加,所以我会看到我自己的两个视频(如果我是主持人),但这对我来说很容易解决
<html>
<body>
<h3 id="show-peer"></h3>
<div style="display: grid; justify-content: space-around; margin:10px;">
<div style="width: 300px;height: 200px;transform: scale(-1, 1);border: 2px solid; display:grid; margin-bottom: 5%;" id="ourVideo"></div>
<div style="width: 300px;height: 200px;transform: scale(-1, 1);border: 2px solid; display: grid;" id="remoteVideo"></div>
</div>
<input id="peerID" placeholder="Peer ID">
<button id="call-peer" onclick="callPeer()">Call Peer</button>
<br>
<button id="screenShare"onclick="shareScreen()">Share Screen</button>
</body>
<script src="https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js"></script>
<script>
window.addEventListener('load',(event)=>{
var peer= new Peer()
var myStream;
var currentPeer;
var peerList=[];
peer.on('open',function(id){
document.getElementById("show-peer").innerHTML=id
})
peer.on('call',function(call){
navigator.mediaDevices.getUserMedia({
video:true,
audio:true
}).then((stream)=>{
myStream = stream
addOurVideo(stream)
call.answer(stream)
call.on('stream',function(remoteStream){
if(!peerList.includes(call.peer)){
addRemoteVideo(remoteStream)
currentPeer = call.peerConnection
peerList.push(call.peer)
}
})
}).catch((err)=>{
console.log(err+" unable to get media")
})
})
function stopScreenShare(){
let videoTrack = myStream.getVideoTracks()[0];
var sender = currentPeer.getSenders().find(function(s){
return s.track.kind ==videoTrack.kind;
})
sender.replaceTrack(videoTrack)
};
document.getElementById("call-peer").addEventListener('click',(e)=>{
let remotePeerId= document.getElementById("peerID").value;
document.getElementById("show-peer").innerHTML= "connecting "+remotePeerId;
console.log(remotePeerId)
callPeer(remotePeerId);
})
document.getElementById("screenShare").addEventListener('click',(e)=>{
navigator.mediaDevices.getDisplayMedia({
video: {
cursor: "always"
},
audio:{
autoGainControl: false,
echoCancellation: false,
googAutoGainControl: false,
noiseSuppression: false
}
}).then((stream)=>{
let videoTrack = stream.getVideoTracks()[0];
videoTrack.onended = function(){
stopScreenShare()
}
let sender = currentPeer.getSenders().find(function(s){
return s.track.kind == videoTrack.kind
})
sender.replaceTrack(videoTrack)
}).catch((err)=>{
console.log("unable to get display media"+err)
})
})
function callPeer(id){
navigator.mediaDevices.getUserMedia({
video:true,
audio:true
}).then((stream)=>{
myStream = stream
addOurVideo(stream)
let call = peer.call(id,stream)
call.on('stream',function(remoteStream){
if(!peerList.includes(call.peer)){
addRemoteVideo(remoteStream)
currentPeer = call.peerConnection
peerList.push(call.peer)
}
})
}).catch((err)=>{
console.log(err+" unable to get media")
})
}
function addRemoteVideo(stream){
let video = document.createElement("video");
video.classList.add("video")
video.srcObject = stream;
video.play()
document.getElementById("remoteVideo").append(video)
}
function addOurVideo(stream){
let video = document.createElement("video");
video.classList.add("video")
video.srcObject = stream;
video.play()
video.muted=true;
document.getElementById("ourVideo").append(video)
}
});
</script>
</html>
我认为您需要创建一个“网格”。因此,对于 3 个对等点,每个用户(对等点)建立两个连接,一个连接到另外两个用户中的每一个。在每个客户端,有两个完全不同的连接。
PeerJs GitHub 上的用户 @daGrevis asked this question。最终,这是他们用于 multi-peer 聊天的实现,可能会有所帮助:
Chat = React.createClass
displayName: "Foo"
getInitialState: ->
messages: []
connectionsToPeerIds: (connections) ->
_.map connections, (connection) => connection.peer
componentWillMount: ->
who = getSegments()[1]
peer = new Peer who, key: PEER_KEY, debug: 2
@connections = []
peer.on "error", (error) =>
alert error.type
peer.on "open", (peerId) =>
if who == "x"
peer.on "connection", (connection) =>
@connections.push connection
@listenForMessage connection
peerIds = @connectionsToPeerIds @connections
connection.on "open", =>
connectionsWithoutNewConnection = _.filter @connections, (c) -> c.peer != connection.peer
peerIdsWithoutNewConnection = @connectionsToPeerIds connectionsWithoutNewConnection
if peerIdsWithoutNewConnection.length
connection.send type: "newConnection", peerIds: peerIdsWithoutNewConnection
if who != "x"
connection = peer.connect "x"
connection.on "error", (error) =>
alert error
connection.on "open", =>
@connections.push connection
@listenForMessage connection
connection.on "data", (data) =>
if data.type == "newConnection"
peerIds = data.peerIds
_.forEach peerIds, (peerId) =>
connection = peer.connect peerId
do (connection) =>
connection.on "error", (error) =>
alert error.type
connection.on "open", =>
@connections.push connection
@listenForMessage connection
peer.on "connection", (connection) =>
connection.on "open", =>
@connections.push connection
@listenForMessage connection
然后我发现了一个实例,其中用户@mluketin used peerjs-server, and created a conference call example https://github.com/mluketin/peerjs-helloworld-conference
据我所知和阅读,网状设计似乎是最简单的方法,但受限于最慢对等体的速度。因此,如果您只需要 3-5 个人,应该没问题。否则,您可能必须遵循 mluketin 列出的示例。
更多可能有帮助的链接:
- Having multiple peers PeerJS?