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

Posted

技术标签:

【中文标题】在 PeerJs 正在进行的实时连接(流)期间请求视频【英文标题】:Request video during PeerJs ongoing live connection (stream) 【发布时间】:2021-09-25 19:47:43 【问题描述】:

我是 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');

请帮忙。

【问题讨论】:

【参考方案1】:

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

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

您在上面的代码中有一个错误,我知道您没有问过它,它很难看到并且并不总是会显现出来。当您的发起方在目的地有时间接收带有本地视频/音频流的承诺之前发送呼叫时,就会出现此问题。解决方案是颠倒调用的顺序,并从为 peer.on("call", ... 设置事件处理程序开始,而不是在我们请求视频流时等待返回的承诺开始。失败模式将取决于目标客户端发出它想要的信号并调用发起方需要多长时间,以及发起方响应需要多长时间,以及流承诺返回目标客户端需要多长时间。您可以看到一个完整的工作示例,其中消息也来回发送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);
    ;
);

【讨论】:

感谢您的精彩解释。是的,它救了我。不过,我仍然面临一些麻烦。你能帮我***.com/questions/68472182/…。

以上是关于在 PeerJs 正在进行的实时连接(流)期间请求视频的主要内容,如果未能解决你的问题,请参考以下文章

使用python 多进程进行基于websocket 的实时视频流处理

我发现了 高性能异步编程 和 实时流模型 那千丝万缕的联系!

我发现了 高性能异步编程 和 实时流模型 那千丝万缕的联系!

SpringBoot+WebSocket+Vue+PeerJs实现WebRTC视频通话功能

使用videojs进行实时流式传输的CORS和请求标头错误[重复]

监控rtsp交互失败怎么回事?