如何修改正在进行的连接上的流以暂停/恢复流传输 [英] How to modify stream on ongoing connection to pause/resume stream transmission

查看:34
本文介绍了如何修改正在进行的连接上的流以暂停/恢复流传输的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始学习并在学校的服务器(VPS)上使用WebRTC和PeerJ为我的学校构建了一个远程在线课程的应用程序。到目前为止,我可以设置一对一对等连接,但在暂停和恢复流传输时遇到困难。

我正在寻求一些关于如何在活动连接时暂停和恢复自身和远程用户的视频流和音频流的帮助。当我执行localStream.getVideoTracks()[0].enabled = false时,它只为我禁用视频(不为远程用户禁用)。

正如一些人建议的replaceTrack API,但我并不是找不到有关它的教程,因为我是新手。

我的代码(感谢Link)如下所示:

var url = new URL(window.location.href)
var disableStreamInBeginning = url.searchParams.get("disableStreamInBeginning")
var passwordProtectedRoom = url.searchParams.get("passwordProtectedRoom")
var muteAllInBeginning = url.searchParams.get("muteAllInBeginning")
var isVideoCall = url.searchParams.get("isVideoCall")
var singleOrConference = url.searchParams.get("singleOrConference")

const conferenceView = document.getElementById('conference')
const loader = document.getElementById('loader')
const localVideoView = document.getElementById('local-video')
const remoteVideoView = document.getElementById('remote-video')
const remoteVideoDiv = document.getElementById('remote-video-div')
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
}
if(typeof isVideoCall !== 'undefined' && isVideoCall == 'true'){
    var videoCall = true
} else {
    var videoCall = false
}
if(typeof singleOrConference !== 'undefined' && singleOrConference == 'conference'){
    var isConference = true
    conferenceView.style.display = 'block'
} else {
    var isConference = false
    localVideoView.style.opacity = 0
    remoteVideoView.style.opacity = 0
    remoteVideoDiv.style.opacity = 0
}

var selectedCamera = 'user'
let localStream;

const socket = io('/');
localVideoView.muted = true;
const peers = {};
const peer = new Peer(undefined, {
    host: '/',
    port: '443',
    path: '/myapp',
    secure: true
})

// Handelling incoming call connection
peer.on("call", async (call) => {
    let stream = null;
    try {
        stream = await navigator.mediaDevices.getUserMedia(
            {
                video: {
                    facingMode: selectedCamera
                },
                audio: true
            });
        call.answer(stream);
        call.on("stream", (remoteVideoStream) => {
            addVideoStream(remoteVideoView, remoteVideoStream);
        });
    } catch (err) {
        console.log('peer.on("call": ' + err);
    };
});

// On new user connected
socket.on("user-connected", async (userId) => {
    connectDataToNewUser(userId);
    try {
        stream = await navigator.mediaDevices.getUserMedia(
            {
                audio: true,
                video: true,
            })
    }
    catch (err) {
        console.log('socket.on("user-connected": ' + err);
    };
    connectMediaToNewUser(userId, stream);
});

// Show  own Video on own device screen
(async () => {
    try {
        localStream= await navigator.mediaDevices.getUserMedia(
            {
                video: {
                    facingMode: selectedCamera
                },
                audio: true
            });
            addVideoStream(localVideoView, localStream);
    } catch (err) {
        console.log('(async () =>: ' + err);
    }
})();

peer.on("open", (id) => {
    socket.emit("join-room", ROOM_ID, id);
});

peer.on("error", (err) => {
    console.log('peer.on("error": ' + err);
})

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

// Set up event listener for an "another user" data connection established event
peer.on("connection", (conn) => {
    conn.on("data", (data) => {
        console.log('Received data ' + data);
    });
    // Set up event listener for connection conn established event
    conn.on("open", () => {
        conn.send('Hello!');
    });
});

// Initiate a Data call (Messages) to user
const connectDataToNewUser = (userId) => {
    let conn = peer.connect(userId);
    conn.on("data", (data) => {
        console.log('Received data: ' + data);
    });
    conn.on("open", () => {
        conn.send('hi!');
    });
};

// Initiate a Media call (Audio/Video) to user
const connectMediaToNewUser = (userId, stream) => {
    const call = peer.call(userId, stream);
    call.on("stream", (userVideoStream) => {
        addVideoStream(remoteVideoView, userVideoStream);
    });
    call.on("close", () => {
        remoteVideoView.remove();
    });
    call.on("error", (error) => {
        console.log('connectMediaToNewUser' + error);
    });
    peers[userId] = call;
};

const addVideoStream = (video, stream) => {
    video.srcObject = stream;
    video.addEventListener("loadedmetadata", () => {
        if(disbaleSelfStream){
            systemStream.getVideoTracks()[0].enabled = false
            systemStream.getAudioTracks()[0].enabled = false
        } else {
            loader.style.opacity = 0
            video.style.opacity = 1
            video.play()
            remoteVideoDiv.style.opacity = 0
        }
    });
};

服务器端代码:

const express = require('express')
const app = express()
const httpPort = process.env.PORT || 80
const httpsPort = 443
const { ExpressPeerServer } = require('peer')
const path = require('path')
const http = require('http')
const https = require('https')
const fs = require('fs')

// Certificate & credentials
const privateKey = fs.readFileSync(path.join(__dirname, 'certs', 'key.pem'))
const certificate = fs.readFileSync(path.join(__dirname, 'certs', 'cert.pem'))
const credentials = {
    key: privateKey,
    cert: certificate
}

const httpsServer = https.createServer(credentials, app).listen(httpsPort, () => { console.log('Peer Server listening to port ' + httpsPort) })

const peerServer = ExpressPeerServer(httpsServer, {
        debug: true,
        path: '/myapp'
})

app.use(peerServer)

const io = require('socket.io')(httpsServer, {
   forceNew: true,
   transports: ["polling"],
})
const { v4: uuidV4 } = require('uuid')

app.set('view engine', 'ejs')
app.use(express.static('public'))

app.get('/', (req, res) => {
  res.redirect(`/${uuidV4()}`)
})

app.get('/:room', (req, res) => {
  res.render('room', { roomId: req.params.room })
})

io.on('connection', (socket) => {
    socket.on('join-room', (roomId, userId) => {
        socket.join(roomId)
        socket.broadcast.to(roomId).emit('user-connected', userId)

        socket.on('disconnect', () => {
            socket.broadcast.to(roomId).emit('user-disconnected', userId)
        })
        socket.on('text-message', message => {
            socket.broadcast.to(roomId).emit('text-message-received', message)
        })
        socket.on('system-stream-updated', remoteUserId => {
            socket.broadcast.to(roomId).emit('new-remote-stream', remoteUserId)
        })
    })
})

和room.ejs(如果需要)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script>
    const ROOM_ID = "<%= roomId %>"
  </script>
  <script src="peer.min.js" defer></script>
  <script src="/socket.io/socket.io.js" defer></script>
  <script src="client.js" defer></script>
  <title>Interface</title>
  <style type="text/css">
        html, body {
            padding: 0;
            margin: 0;
        }
        .container, .local-video {
            position: absolute;
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        .remote-video-div {
            position: absolute;
            max-width: 30%;
            width: 30%;
            margin: 16px;
        }
        .remote-video {
            max-width: 100%;
            width: 100%;
            margin-bottom: -5px;
        }
        .video-inset {
            outline: unset;
            visibility: hidden;
            position: relative;
            margin:0; 
            padding:0; 
        }
        
        .background-black {
            background-color: #000000 !important;
        }
        
        .display-none {
            display: none;
        }
        
        .loader {
            margin: 250px auto;
            border: 7px solid #9e9c9c;
            border-radius: 50%;
            border-top: 7px solid #ffffff;
            width: 40px;
            height: 40px;
            -webkit-animation: spin 2s linear infinite; /* Safari */
            animation: spin 2s linear infinite;
        /* Safari */
        @-webkit-keyframes spin {
            0% { -webkit-transform: rotate(0deg); }
            100% { -webkit-transform: rotate(360deg); }
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
  </style>
  <link rel="icon" type="image/ico" href="favicon.ico"/>
</head>
<body>
    <div class="local-video-div background-black">
        <video class="local-video" autoplay></video>
    </div>
    <div class="container background-black display-none" id="loader">
        <div class="loader"></div>
    </div>
    <div class="remote-video-div background-black">
        <video class="remote-video" autoplay onclick="remoteVideoClick()"></video>
    </div>
    <div class="container background-black display-none" id="conference">
    </div>
</body>
</html>

提前感谢。

推荐答案

我遇到了同样的问题,正在寻找解决方案。这很有趣,因为你的问题本身就解决了我的问题!这是我做的.

 <button
        onClick={() =>
          (stream.getVideoTracks()[0].enabled =
            !stream.getVideoTracks()[0].enabled)
        }
  >

顺便说一句,您可能已经注意到(从C舌舔上的),我在Reaction上执行此操作。然而,在您的情况下,我认为您应该首先从设备获取视频流,并将其设置为一个变量。然后使用该流变量调用用户,当您需要它时,您可以通过执行stream.getVideoTracks()[0].enable=!Stream.getVideoTracks()[0].enable来停止和启动流。但是,请确保您有一个流的真实来源,并始终从那里引用它。我在"反应"中做了这件事,它对我很管用。希望它也能为您服务!

这篇关于如何修改正在进行的连接上的流以暂停/恢复流传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆