美文网首页音视频通话
Web网页音视频通话之Webrtc相关操作(一)

Web网页音视频通话之Webrtc相关操作(一)

作者: HeloWxl | 来源:发表于2022-07-03 00:51 被阅读0次

    目录

    • 打开摄像头/关闭摄像头
    • 静音/解除静音
    • 打开视频/关闭视频
    • 截图且下载

    打开摄像头/关闭摄像头

    效果图

    image.png image.png

    HTML

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>打开摄像头</title>
        <link rel="stylesheet" href="../../../static/layui/css/layui.css">
    </head>
    <body>
    <div id="container">
        <div class="layui-row">
            <div class="layui-col-xs6 layui-col-md12" style="text-align: center">
                <video id="video-local" autoplay playsinline width="400px" height="400px"></video>
            </div>
        </div>
        <div class="layui-row">
            <div class="layui-col-xs6 layui-col-md12" style="text-align: center">
                <button type="button" class="layui-btn layui-btn-normal" onclick="openCamera()">打开摄像头</button>
                <button type="button" class="layui-btn layui-btn-danger" onclick="stopVideo()">关闭摄像头</button>
            </div>
        </div>
        <blockquote class="layui-elem-quote layui-text" style="margin-top: 15px;">
            <p>显示摄像头预览的内容,网页上由元素video来呈现。</p>
            <p>点击打开摄像头按钮后,浏览器会询问是否允许,请点击“允许”。</p>
        </blockquote>
    </div>
    </body>
    </html>
    

    javaScript

       let videoElem = document.querySelector('video');
    
        /**
         * MediaDevices.getUserMedia()方法在用户允许后,按照请求,拿到stream。 stream可以包含视频或音频。前面的设定里,我们只使用视频。
         * 如果用户拒绝了使用摄像头申请,或者申请的媒体不可用,即表现为被拒绝。 用户拒绝会报NotAllowedError,找不到符合要求的设备会报NotFoundError DOMException。
         * @param e
         * @returns {Promise<void>}
         */
        function openCamera() {
            if (window.stream != null) {
                alert('摄像头已打开,请勿重新打开摄像头');
                return false;
            }
            const constraints = {
                audio: true,
                video: true
            };
            navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(error => {
                console.error(error)
            });
        }
    
        /**
         * 成功获取到流
         * @param stream
         */
        function gotStream(stream) {
            window.stream = stream;
            videoEle.srcObject = stream;
        }
    
        /**
         *  关闭摄像头
         *  获取到video中的流,并将流中的轨道关闭
         */
        function stopVideo() {
            // 获取video中的流
            const stream = videoElem.srcObject;
            // 判断stream 是否为空
            if (stream == null) {
                return;
            }
            // 获取流中的所有轨道
            const tracks = stream.getTracks();
            tracks.forEach(function (track) {
                track.stop();
            });
            videoElem.srcObject = null;
            window.stream = null;
        }
    

    静音/解除静音

    效果图

    image.png 静音开启.png 解除静音.png

    前端代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>静音-解除静音</title>
        <link rel="stylesheet" href="../../../static/layui/css/layui.css">
    </head>
    <body>
    <div id="container">
        <div class="layui-row">
            <div class="layui-col-xs6 layui-col-md12" style="text-align: center">
                <video id="video-local" autoplay playsinline width="400px" height="400px"></video>
            </div>
        </div>
        <div class="layui-row">
            <div class="layui-col-xs6 layui-col-md12" style="text-align: center">
                <button type="button" class="layui-btn layui-btn-normal" onclick="openCamera()">打开摄像头</button>
                <button id="mute" type="button" class="layui-btn layui-btn-normal" onclick="muted()">静音</button>
                <button id="unmute" type="button" class="layui-btn layui-btn-normal" onclick="unmuted()">解除静音</button>
            </div>
        </div>
        <blockquote class="layui-elem-quote layui-text" style="margin-top: 15px;">
            <p>1.显示摄像头预览的内容,网页上由元素video来呈现。</p>
            <p>2.点击打开摄像头按钮后,浏览器会询问是否允许,请点击“允许”。</p>
            <p>3.打开摄像头获取到浏览器摄像头数据后,可以对获取到的流数据进行静音以及解除静音相关操作</p>
        </blockquote>
    </div>
    </body>
    </html>
    

    javaScript

        const constraints = {
            audio: true,
            video: true
        };
    
        let localStream = null;
        let videoEle = document.querySelector('video');
        /**
         * MediaDevices.getUserMedia()方法在用户允许后,按照请求,拿到stream。 stream可以包含视频或音频。前面的设定里,我们只使用视频。
         * 如果用户拒绝了使用摄像头申请,或者申请的媒体不可用,即表现为被拒绝。 用户拒绝会报NotAllowedError,找不到符合要求的设备会报NotFoundError DOMException。
         * @param e
         * @returns {Promise<void>}
         */
         function openCamera() {
            if(localStream!=null){
                alert('摄像头已打开,请勿重新打开摄像头');
                return false;
            }
             navigator.mediaDevices.getUserMedia(constraints).then(stream=>{
                localStream = stream;
                videoEle.srcObject = stream;
            }).catch(error=>{
                alert('打开摄像头失败');
                console.error('打开摄像头失败',error)
            });
        }
    
        function muted() {
            if(localStream==null){
                alert('请打开音视频');
                return false;
            }
            const tracks = localStream.getTracks();
            tracks.forEach(track => {
                if(track.kind === 'audio'){
                    track.enabled = false
                }
                console.log(track)
            });
            alert('静音开启,u can`t speak ')
        }
    
        function unmuted() {
            if(localStream==null){
                alert('请打开音视频');
                return false;
            }
            const tracks = localStream.getTracks();
            tracks.forEach(track => {
                if(track.kind === 'audio'){
                    track.enabled = true
                }
                console.log(track)
            });
            alert('解除静音,u can speak ')
        }
    }
    

    打开视频/关闭视频

    效果图

    image.png 打开视频.png 关闭视频.png

    前端代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>打开视频/关闭视频</title>
        <link rel="stylesheet" href="../../../static/layui/css/layui.css">
    </head>
    <body>
    <div id="container">
        <div class="layui-row">
            <div class="layui-col-xs6 layui-col-md12" style="text-align: center">
                <video id="video-local" autoplay playsinline width="400px" height="400px"></video>
            </div>
        </div>
        <div class="layui-row">
            <div class="layui-col-xs6 layui-col-md12" style="text-align: center">
                <button type="button" class="layui-btn layui-btn-normal" onclick="openCamera()">打开摄像头</button>
                <button id="openVideo"  type="button" class="layui-btn layui-btn-normal" onclick="openVideo()">打开视频</button>
                <button id="closeVideo"  type="button" class="layui-btn layui-btn-normal" onclick="closeVideo()">关闭视频</button>
            </div>
        </div>
        <blockquote class="layui-elem-quote layui-text" style="margin-top: 15px;">
            <p>1.显示摄像头预览的内容,网页上由元素video来呈现。</p>
            <p>2.点击打开摄像头按钮后,浏览器会询问是否允许,请点击“允许”。</p>
            <p>3.打开摄像头获取到浏览器摄像头数据后,可以对获取到的流数据进行打开视频/关闭视频相关操作</p>
        </blockquote>
    </div>
    
    </body>
    </html>
    

    javaScript

     const constraints = {
            audio: true,
            video: true
        };
    
        let localStream = null;
        let videoEle = document.querySelector('video');
        /**
         * MediaDevices.getUserMedia()方法在用户允许后,按照请求,拿到stream。 stream可以包含视频或音频。前面的设定里,我们只使用视频。
         * 如果用户拒绝了使用摄像头申请,或者申请的媒体不可用,即表现为被拒绝。 用户拒绝会报NotAllowedError,找不到符合要求的设备会报NotFoundError DOMException。
         * @param e
         * @returns {Promise<void>}
         */
         function openCamera() {
            if(localStream!=null){
                alert('摄像头已打开,请勿重新打开摄像头');
                return false;
            }
             navigator.mediaDevices.getUserMedia(constraints).then(stream=>{
                localStream = stream;
                videoEle.srcObject = stream;
            }).catch(error=>{
                alert('打开摄像头失败');
                console.error('打开摄像头失败',error)
            });
        }
    
        function openVideo() {
            if(localStream==null){
                alert('请打开音视频');
                return false;
            }
            const tracks = localStream.getTracks();
            tracks.forEach(track => {
                if(track.kind === 'video'){
                    track.enabled = true
                }
                console.log(track)
            });
            alert('打开视频,u can see u ')
        }
    
        function closeVideo() {
            if(localStream==null){
                alert('请打开音视频');
                return false;
            }
            const tracks = localStream.getTracks();
            tracks.forEach(track => {
                if(track.kind === 'video'){
                    track.enabled = false
                }
                console.log(track)
            });
            alert('关闭视频,u can`t see u ')
        }
    

    视频截图

    效果图

    image.png 截取图.png

    HTML

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>截屏</title>
        <link rel="stylesheet" href="../../../static/layui/css/layui.css">
    
    </head>
    <body>
    <div id="container">
        <div class="layui-row">
            <div class="layui-col-xs6 layui-col-md12" style="text-align: center">
                <video id="video-local" autoplay playsinline width="400px" height="400px"></video>
            </div>
        </div>
        <div class="layui-row">
            <div class="layui-col-xs6 layui-col-md12" style="text-align: center">
                <button type="button" class="layui-btn layui-btn-normal" onclick="openCamera()">打开摄像头</button>
                <button type="button" class="layui-btn layui-btn-normal" onclick="getCapure()">截图</button>
            </div>
        </div>
        <canvas id="mainCanvas"></canvas>
        <div id="list" style="display: grid; grid-template-columns: repeat(auto-fill, 100px);
        column-gap: 20px; row-gap: 20px;"></div>
        <blockquote class="layui-elem-quote layui-text" style="margin-top: 15px;">
            <p>1.获取摄像头数据,点击截图,展示截图数据</p>
        </blockquote>
    </div>
    </body>
    </html>
    

    javaScript

     const video = document.querySelector('video');
        const constraints = {
            audio: false,
            video: true
        };
    
        const list = document.querySelector('#list'); // 拿来存放多个元素
    
        function openCamera() {
            navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(onError);
        }
    
        /**
         * 成功获取流数据
         * @param stream
         */
        function gotStream(stream) {
            window.stream = stream;
            video.srcObject = stream;
        }
        /**
         * 获取流发生错误
         * @param stream
         */
        function onError(error) {
            console.log('navigator.MediaDevices.getUserMedia error: ', error.message, error.name);
        }
    
        /**
         * 捕获
         */
        function getCapure(){
            const mCanvas = window.canvas = document.querySelector('#mainCanvas');
            mCanvas.width = 480;
            mCanvas.height = 360;
    
            // 开始截取
            mCanvas.width = video.videoWidth;
            mCanvas.height = video.videoHeight;
            mCanvas.getContext('2d').drawImage(video, 0, 0, mCanvas.width, mCanvas.height);
            // 新增1张
            var divItem = document.createElement("div");
            divItem.style.display = "block";
            divItem.width = 100;
            divItem.height = divItem.width * video.videoHeight / video.videoWidth; // 计算一下比例
            divItem.style.width = divItem.width + "px";
            divItem.style.height = divItem.height + "px";
            var c1 = document.createElement("canvas");
            c1.width = divItem.width;
            c1.height = divItem.height;
            c1.getContext('2d').drawImage(video, 0, 0, mCanvas.width, mCanvas.height, 0, 0, c1.width, c1.height);
            divItem.appendChild(c1);
            list.appendChild(divItem);
        }
    
        /**
         * 清除记录
         */
        function clear(){
            var child = list.lastElementChild;
            while (child) {
                list.removeChild(child);
                child = list.lastElementChild;
            }
        }
    

    写在最后学习参考视频讲解比较详细:https://space.bilibili.com/394612055/video?tid=0&page=2&keyword=&order=pubdate

    image.png

    相关文章

      网友评论

        本文标题:Web网页音视频通话之Webrtc相关操作(一)

        本文链接:https://www.haomeiwen.com/subject/zznmmrtx.html