在 PeerJs 正在进行的实时连接(流)期间请求视频

Request video during PeerJs ongoing live connection (stream)

我是 PeerJs 的新手,最近在 Covid 大流行期间开始为我的学校开发应用程序。

我已经能够使用 express 将代码部署到 NodeJs 服务器,并且能够在 2 个用户之间建立连接。

但是当两个用户的视频从流开始时关闭并且用户想要发起视频通话时,问题就出现了。

我需要的是向用户 2 发送某种通知,告知用户 1 正在请求视频。这样用户 2 就会打开视频。

我现有的代码是:

var url = new URL(window.location.href);
var disableStreamInBeginning = url.searchParams.get("disableStreamInBeginning"); // To disable video in the beginning
var passwordProtectedRoom = url.searchParams.get("passwordProtectedRoom");
var muteAllInBeginning = url.searchParams.get("muteAllInBeginning");

const socket = io('/')
const localVideoDiv = document.getElementById('local-video-div')
const oneOnOneSelf = document.getElementById('local-video')
const oneOnOneRemote = document.getElementById('remote-video')
if(typeof disableStreamInBeginning !== 'undefined' && disableStreamInBeginning == 'true'){
    var disbaleSelfStream = true
} else {
    var disbaleSelfStream = false
}
if(typeof passwordProtectedRoom !== 'undefined' && passwordProtectedRoom == 'true'){
    var passwordProtected = true
} else {
    var passwordProtected = false
}
if(typeof muteAllInBeginning !== 'undefined' && muteAllInBeginning == 'true'){
    var muteAll = true
} else {
    var muteAll = false
}
var systemStream

oneOnOneSelf.style.opacity = 0
oneOnOneRemote.style.opacity = 0

const myPeer = new Peer(undefined, {
    host: '/',
    port: '443',
    path: '/myapp',
    secure: true
})
const ownVideoView = document.createElement('video')
const peers = {}
navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true
}).then(ownStream => {
    systemStream = ownStream
    addVideoStream(ownStream, oneOnOneSelf)

    myPeer.on('call', call => {
        call.answer(ownStream)
        call.on('stream', remoteStream => {
            addVideoStream(remoteStream, oneOnOneRemote)
        })
    })

    socket.on('user-connected', userId => {
        //connectToNewUser(userId, stream)
        setTimeout(connectToNewUser, 1000, userId, ownStream)
    })

})

socket.on('user-disconnected', userId => {
    if (peers[userId]) peers[userId].close()
})

myPeer.on('open', id => {
    //Android.onPeerConnected();
    socket.emit('join-room', ROOM_ID, id)
})

function connectToNewUser(userId, stream) {
    const call = myPeer.call(userId, stream)
    call.on('stream', remoteStream => {
        //console.log('Testing')
        addVideoStream(remoteStream, oneOnOneRemote)
    })
    call.on('close', () => {
        oneOnOneRemote.remove()
    })

    peers[userId] = call
}

function addVideoStream(stream, videoView) {
    videoView.srcObject = stream
    videoView.addEventListener('loadedmetadata', () => {
        if(disbaleSelfStream){
            audioVideo(true)
        } else {
            localVideoDiv.style.opacity = 0
            videoView.style.opacity = 1
            videoView.play()
        }
    })
}

function audioVideo(bool) {
    if(bool == true){
        localVideoDiv.style.opacity = 1
        oneOnOneSelf.style.opacity = 0
        systemStream.getVideoTracks()[0].enabled = false
    } else {
        if(disbaleSelfStream){
            console.log('Waiting For Another User To Accept') // Here is need to inform user 2 to tun on video call
        } else {
            localVideoDiv.style.opacity = 0
            oneOnOneSelf.style.opacity = 1
            systemStream.getVideoTracks()[0].enabled = true
        }
    }
}

function muteUnmute(bool) {
    if(bool == true){
        systemStream.getAudioTracks()[0].enabled = true
    } else {
        systemStream.getAudioTracks()[0].enabled = false
    }
}

function remoteVideoClick(){
    alert('Hi');
}

请帮忙。

您可以直接使用对等点本身来回发送消息 const dataConnection = peer.connect(id) 会将您连接到远程对等点,它 return 是一个 dataConnection class 实例,您稍后可以将其与 class 的发送方法一起使用。

请记住,您还想在另一端设置侦听器来侦听此事件,例如“打开”以了解数据通道何时打开: dataConnection.on('open', and dataConnection.on('数据...

你上面的代码中有一个错误,我知道你没有问过它,它很难被发现而且并不总是会显现出来。当您的发起者在目的地有时间通过​​其本地 video/audio 流接收回承诺之前发送呼叫时,就会出现问题。解决方案是颠倒调用顺序,并首先为 peer.on("call", ... 设置事件处理程序,而不是等待对 return 的承诺请求视频流。失败模式将取决于您的目标客户端发出信号并呼叫发起者需要多长时间,加上发起者响应需要多长时间与流承诺需要多长时间return 在目标客户端上。您可以看到一个完整的工作示例,其中还来回发送消息 here

// Function to obtain stream and then await until after it is obtained to go into video chat call and answer code. Critical to start the event listener ahead of everything to ensure not to miss an incoming call.
peer.on("call", async (call) => {
    let stream = null;
    console.log('*** "call" event received, calling call.answer(strem)');
    // Obtain the stream object
    try {
        stream = await navigator.mediaDevices.getUserMedia(
            {
                audio: true,
                video: true,
            });
        // Set up event listener for a peer media call -- peer.call, returns a mediaConnection that I name call        
        // Answer the call by sending this clients video stream --myVideo-- to calling remote user
        call.answer(stream);
        // Create new DOM element to place the remote user video when it comes
        const video = document.createElement('video');
        // Set up event listener for a stream coming from the remote user in response to this client answering its call
        call.on("stream", (userVideoStream) => {
            console.log('***"stream" event received, calling addVideoStream(UserVideoStream)');
            // Add remote user video stream to this client's active videos in the DOM
            addVideoStream(video, userVideoStream);
        });
    } catch (err) {
        /* handle the error */
        console.log('*** ERROR returning the stream: ' + err);
    };
});