• 3┃音视频直播系统之浏览器中通过 WebRTC 直播视频实时录制回放下载


    一、录制分类

    • 在音视频会议、在线教育等系统中,录制是一个特别重要的功能

    • 录制一般分为服务端录制和客户端录制

    • 服务端录制:优点是不用担心客户因自身电脑问题造成录制失败(如磁盘空间不足),也不会因录制时抢占资源(CPU 占用率过高)而导致其他应用出现问题等;缺点是实现的复杂度很高。

    • 客户端录制:优点是方便录制方(如老师)操控,并且所录制的视频清晰度高,实现相对简单。但是它对内存、硬盘的要求 比较高

    • 它们各有优劣,因此大系统一般会同时支持客户端录制与服务端录制。

     

    二、录制思考

    • 第一:录制后音视频流的存储格式是什么呢?是直接录制原始数据,还是录制成某种多媒体格式(如 MP4 )

    • 第二:录制下来的音视频流如何播放?是使用普通的播放器播放,还是使用私有播放器,如果你的业务是多人互动类型,且回放时也要和直播时一样,那么你就必须使用私有播放器,因为普通播放器是不支持同时播放多路视频的

    • 第三:启动录制后多久可以回放呢?录制完立即回放?边录边看?录完后过一段时间可观看?

    • 录制完立即回放当然体验性最好,但是清晰度却不行,在平时的直播中应该有所体验;录完一段时间再观看,可以对视频进行转码获得更好的清晰度,但是对用户的体验却不好,不能实时观看。

     

    三、录制音视频

    • WebRTC 录制音视频流之后,最终是通过 Blob 对象将数据保存成多媒体文件的

    • Blob(Binary Large Object)是 JavaScript 的大型二进制对象类型 var aBlob = new Blob(array, options);

    • WebRTC 中提供了 MediaRecorder 类去录制本地音视频 var mediaRecorder = new MediaRecorder(stream[, options]);

    • stream:通过 getUserMedia 获取的本地视频流或通过 RTCPeerConnection 获取的远程视频流

    • options:可选项,指定视频格式、编解码器、码率等相关信息,如 mimeType: 'video/webm;codecs=vp8'

    • MediaRecorder 对象还有一个特别重要的事件,即 ondataavailable 事件。当 MediaRecoder 捕获到数据时就会触发该事件。通过它,我们才能将音视频数据录制下来

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>video of WebRTC</title>
    </head>
    
    <body>
        <button onclick="startRecord()">Start Record</button>
    </body>
    <script>
        var buffer;
    
        function startRecord() {
            buffer = [];
    
            // 设置录制下来的多媒体格式
            var options = {
                mimeType: 'video/webm;codecs=vp8'
            }
    
            // 判断浏览器是否支持录制
            if (!MediaRecorder.isTypeSupported(options.mimeType)) {
                console.error(`${options.mimeType} is not supported!`);
                return;
            }
    
            try {
                // 创建录制对象
                mediaRecorder = new MediaRecorder(window.stream, options);
            } catch (e) {
                console.error('Failed to create MediaRecorder:', e);
                return;
            }
            // 当有音视频数据来了之后触发该事件
            mediaRecorder.ondataavailable = handleDataAvailable;
            // 开始录制
         		// 在开启录制时,可以设置一个毫秒级的时间片,这样录制的媒体数据会按照你设置的
         		// 值分割成一个个单独的区块,否则默认的方式是录制一个非常大的整块内容。
         		// 分成一块一块的区块会提高效率和可靠性,如果是一整块数据,随着时间的推移,数据块越来越大
         		// 读写效率就会变差,而且增加了写入文件的失败率
            mediaRecorder.start(10);
        }
    
        // 当该函数被触发后,将数据压入到 blob 中
        function handleDataAvailable(e) {
            if (e && e.data && e.data.size > 0) {
                buffer.push(e.data);
            }
        }
    </script>
    
    </html>

     

    四、回放录制视频

    • 通过上面的方法录制好内容 压入到 blob 以后

    • 首先根据 buffer 生成 Blob 对象

    • 然后,根据 Blob 对象生成 URL,并通过 <video> 标签将录制的内容播放出来了

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>video of WebRTC</title>
    </head>
    
    <body>
        <video id="recvideo"></video>
        <button onclick="recplay()" disabled>Play</button>
    </body>
    <script>
        var buffer;
    
        function recplay() {
            var blob = new Blob(buffer, {type: 'video/webm'});
            recvideo.src = window.URL.createObjectURL(blob);
            recvideo.srcObject = null;
            recvideo.controls = true;
            recvideo.play();
        }
    </script>
    
    </html>

     

    五、下载录制视频

    • 也是先创建一个 Blob 对象,并根据 Blob 对象创建 URL;

    • 然后再创建一个 <a> 标签,设置 a 标签的 href 和 download 属性

    • 这样当用户点击该标签之后,录制好的文件就下载下来了

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>video of WebRTC</title>
    </head>
    
    <body>
        <button onclick="download()" disabled>Download</button>
    </body>
    <script>
        var buffer;
    
        function download() {
            var blob = new Blob(buffer, {type: 'video/webm'});
            var url = window.URL.createObjectURL(blob);
            var a = document.createElement('a');
            a.href = url;
            a.style.display = 'none';
            a.download = '下载的视频.webm';
            a.click();
        }
    </script>
    
    </html>

     

  • 相关阅读:
    两个src案例分享
    需求变更,敏捷项目应如何做?
    Centos7安装RabbitMQ
    特殊类的设计
    绿色至未来,积极应对树木资源消耗问题-FSC认证
    【RocketMQ】消息的消费总结
    区块链:去中心化革命下的创新与发展!
    Excel导出——SheetJS简单使用
    uniapp:swiper-demo效果
    浅谈电源TLVR在Intel VR14 Server的应用
  • 原文地址:https://www.cnblogs.com/autofelix/p/16261099.html