从0打造音视频直播系统
李超
前新东方音视频直播技术专家,前沪江音视频架构师
立即订阅
2827 人已学习
课程目录
已完结 40 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 5G的到来将会为音视频插上飞翔的翅膀
免费
WebRTC 1对1通话 (23讲)
01 | 原来通过浏览器访问摄像头这么容易
02 | 如何通过WebRTC进行音视频设备检测呢?
03 | 如何使用浏览器给自己拍照呢?
04 | 可以把采集到的音视频数据录制下来吗?
05 | 原来浏览器还能抓取桌面?
06 | WebRTC中的RTP及RTCP详解
07 | 你竟然不知道SDP?它可是WebRTC的驱动核心!
08 | 有话好商量,论媒体协商
09 | 让我们揭开WebRTC建立连接的神秘面纱
10 | WebRTC NAT穿越原理
11 | 如何通过Node.js实现一套最简单的信令系统?
12 | RTCPeerConnection:音视频实时通讯的核心
13 | 在WebRTC中如何控制传输速率呢?
14 | 如何打开/关闭音视频?
15 | WebRTC中的数据统计原来这么强大(上)
16 | WebRTC中的数据统计原来这么强大(下)
17 | 如何使用Canvas绘制统计图表(上)?
18 | 如何使用Canvas绘制统计图表(下)?
19 | WebRTC能不能进行文本聊天呢?
20 | 原来WebRTC还可以实时传输文件?
21 | 如何保证数据传输的安全(上)?
22 | 如何保证数据传输的安全(下)?
23 | 实战演练:通过WebRTC实现一个1对1音视频实时直播系统
WebRTC多人音视频实时通话 (7讲)
24 | 多人音视频实时通讯是怎样的架构?
25 | 那些常见的流媒体服务器,你该选择谁?
26 | 为什么编译Medooze Server这么难?
27 | 让我们一起探索Medooze的具体实现吧(上)
28 | 让我们一起探索Medooze的具体实现吧(下)
29 | 如何使用Medooze 实现多方视频会议?
30 | 实战演练:通过WebRTC实现多人音视频实时互动直播系统
支持上万人同时在线的直播系统 (8讲)
31 | 一对多直播系统RTMP/HLS,你该选哪个?
32 | HLS:实现一对多直播系统的必备协议
33 | FLV:适合录制的多媒体格式
34 | 如何使用Nginx搭建最简单的直播服务器?
35 | 如何构建云端一对多直播系统?
36 | 如何使用 flv.js 播放 FLV 多媒体文件呢?
37 | 如何使用 video.js 播放多媒体文件?
38 | 实战推演:带你实现一个支持万人同时在线的直播系统
结束语 (1讲)
结束语 | 路漫漫其修远兮,吾将上下而求索
从0打造音视频直播系统
登录|注册

04 | 可以把采集到的音视频数据录制下来吗?

李超 2019-07-23
在音视频会议、在线教育等系统中,录制是一个特别重要的功能。尤其是在线教育系统,基本上每一节课都要录制下来,以便学生可以随时回顾之前学习的内容。
实现录制功能有很多方式,一般分为服务端录制客户端录制,具体使用哪种方式还要结合你自己的业务特点来选择。
服务端录制:优点是不用担心客户因自身电脑问题造成录制失败(如磁盘空间不足),也不会因录制时抢占资源(CPU 占用率过高)而导致其他应用出现问题等;缺点是实现的复杂度很高。不过由于本文要重点讲解的是接下来的客户端录制,所以这里我就不再深入展开讲解了,你只需要知道有服务端录制这回事就行了,或者如果你感兴趣,也可以自行搜索学习。
客户端录制:优点是方便录制方(如老师)操控,并且所录制的视频清晰度高,实现相对简单。这里可以和服务端录制做个对比,一般客户端摄像头的分辨率都非常高的(如 1280x720),所以客户端录制可以录制出非常清晰的视频;但服务端录制要做到这点就很困难了,本地高清的视频在上传服务端时由于网络带宽不足,视频的分辨率很有可能会被自动缩小到了 640x360,这就导致用户回看时视频特别模糊,用户体验差。不过客户端录制也有很明显的缺点,其中最主要的缺点就是录制失败率高。因为客户端在进行录制时会开启第二路编码器,这样会特别耗 CPU。而 CPU 占用过高后,就很容易造成应用程序卡死。除此之外,它对内存、硬盘的要求也特别高。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《从0打造音视频直播系统》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(11)

  • xiao豪
    示例代码

    var buffer;
    // 创建录制对象
    var mediaRecorder;

    // 当该函数被触发后,将数据压入到 blob 中
    function handleDataAvailable(e){
        if(e && e.data && e.data.size > 0){
                buffer.push(e.data);
        }
    }

    function startRecord(){
        // 防止多次启动报错
        if(mediaRecorder && mediaRecorder.state === "recording"){
            return;
        }

        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(videoplay.srcObject, options);
        }catch(e){
            console.error('Failed to create MediaRecorder:', e);
            return;
        }

        // 当有音视频数据来了之后触发该事件
        mediaRecorder.ondataavailable = handleDataAvailable;
        // 开始录制
        mediaRecorder.start(10);
    }

    function startRecplay(){
        console.log(mediaRecorder)
        var blob = new Blob(buffer, {type: 'video/webm'});
        recvideo.src = window.URL.createObjectURL(blob);
        recvideo.srcObject = null;
        recvideo.controls = true;
        recvideo.play();
    }

    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 = 'aaa.webm';
        a.click();
        a.remove();
    }

    function stop(){
        if(mediaRecorder && (mediaRecorder.state === "recording" || mediaRecorder.state === "paused")){
            mediaRecorder.stop();
        }
    }

    作者回复: 非常棒!

    2019-07-23
    4
  • 耳东
    React版示例代码:
    https://github.com/baayso/react-tic-tac-toe/commits/master/src/components/Video/Video.js

    作者回复: 给你个大大的赞!

    2019-07-23
    1
  • lvxus
    老师,想请问一下录制桌面具体是什么操作

    作者回复: 后面的课程有讲,别着急!

    2019-07-23
    1
  • ZeroIce
    作业: https://codepen.io/vicksiyi/pen/pMWybg

    作者回复: 赞!

    2019-08-03
  • hao11111205
    老师,在谷歌浏览器点击下载,不出现保存窗口,直接下载。这是为什么?

    作者回复: 如果你之前在浏览器中有设置保存文件的默认路径就会这样子

    2019-08-01
  • K
    视屏可以下载播放,但是无法回放。
    rePlayVideo.src = window.URL.createObjectURL(blob); 提示不能赋值src为null t.js:75 Uncaught TypeError: Cannot set property 'src' of null
    控制台输出window.URL.createObjectURL(blob); 是blob:http://localhost:63342/15434d88-60de-44fc-bd2e-b1ecd453cc5a

    但是同样的代码 我把生成的url赋值给a标签 然后是可以下载的 而且视屏是有内容的啊


    这是什么情况啊

    作者回复: 明天例子就更新了,你对照着例子看一下

    2019-07-24
  • 恋着歌
    交作业 https://codepen.io/htkar/pen/OKMbzV

    作者回复: 不错! 不错!

    2019-07-24
  • K
    为啥我回放的时候提示我recvideo 是null blob的size是0

    作者回复: 明天demo会被放到 git 上,到时候你对照一下 demo看是不是哪里写错了

    2019-07-24
    1
  • CHY
    在安卓端也有这种现成的录制视频的类吗?如果没有的话是不是需要自己来合流并控制时间戳呢。

    作者回复: 一般都不使用移动端进行录制。如果真的要录制的话,需要使用 Native 的方法。

    2019-07-23
  • 李跃爱学习
    从产品的角度来讲, 应该是设置保存路径,开始录制,结束录制这么操作。
    但是看老师介绍的是要点击保存,就将当前blob的内容保存下来, 真实场景中,要录制很长时间,内存肯定是放不下吧,所以有点困惑,录制开始后是写到磁盘了,还是保存在内存中呢?

    作者回复: 我看一下 handleDataAvailable 这个函数,在这个函数中我是直接将它保存到内存中了。如果你想保存成文,可以直接在这里修改代码!

    2019-07-23
  • 剑衣清风
    github 里的代码可以运行么?

    关于这讲,推荐看看这个 https://cloud.tencent.com/developer/article/1366886 里的MediaRecorder使用示例 - 摄像头版,或者直接打开 https://wendychengc.github.io/media-recorder-video-canvas/cameracanvas.html,看看源文件的相关代码即可。

    作者回复: 可以运行,你再试一下

    2019-07-23
收起评论
11
返回
顶部