前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用h5新标准MediaRecorder API在web页面进行音视频录制

使用h5新标准MediaRecorder API在web页面进行音视频录制

原创
作者头像
WendyGrandOrder
发布2018-11-26 16:22:14
19.9K11
发布2018-11-26 16:22:14
举报

概述

Media Recorder,顾名思义是控制媒体录制的api,在原生app开发中,是一个应用广泛的api,用于在app内录制音频和视频。

事实上,随着web侧的应用越来越富媒体化,w3c也制定了相应的web标准,称为MediaRecorder API(旧称MediaStream Recording API),它给我们的web页面赋予了录制音视频的能力,使得web可以脱离服务器、客户端的辅助,独立进行媒体流的录制。

该api从2013年指定,2016年后开始频繁修订,对于大多数开发者而言是较为陌生的。本文将结合官方文档和实际案例,对它进行一些说明解释。

什么可以录?

任何媒体形式的标签,包括 <audio>, <video>,<canvas>, 其中 <audio>, <video>可以来自网络媒体文件,也可以来自本机设备采集。而<canvas>的内容则更加自由,任何绘制在画布上的用户操作,2d或3d图像,都可以进行录制。它为web提供了更多可能性,我们甚至可以把一个h5游戏流程录成视频,保存落地或进行实况传输。

录出来的是什么?

是经过标准编码后的媒体流数据,可以注入video标签,也可以打包生成文件,还可以进一步流级别的数据处理,比如画面识别、动态插入内容、播放跳转控制等等。

视频编码格式?

编码过程由浏览器实现,依赖浏览器的能力,因为该标准由w3c推进,目前主要的试验田在chrome和firefox,移动端兼容安卓内置的chrome内核浏览器。ios和ie暂时无解。

该标准本身也为我们提供了检测浏览器编码能力的api

MediaRecorder.isTypeSupported(format)

可以把下面这段代码贴进console,来测试当前浏览器的支持状况。

var types = ["video/webm", 
             "audio/webm", 
             "video/webm\;codecs=vp8", 
             "video/webm\;codecs=daala", 
             "video/webm\;codecs=h264", 
             "audio/webm\;codecs=opus", 
             "video/mpeg"];

for (var i in types) { 
  console.log( "Is " + types[i] + " supported? " + (MediaRecorder.isTypeSupported(types[i]) ? "Maybe!" : "Nope :(")); 
}

上述代码来自官方开发文档

为什么对于支持的格式,官方给出的答案是Maybe呢?

因为就算编码格式支持,也有可能因为计算资源不足而导致编码失败。所以该api仅作为筛选判断,实际应用中,还需要做好错误处理。

MediaRecorder工作流程

MediaRecorder在支持的浏览器中表现为是一个全局对象,下面是一个完整可用的例子,请用chrome或者FF打开。

MediaRecorder使用示例

该例子中,把video标签的内容放进了canvas里,与用户点击时在canvas上绘制图案的过程一起,通过MediaRecorder对象提供的captureStream方法录制下来,合并成一个视频文件并保存。

除了固定的标签之外,我们还可以调取摄像头作为视频的内容。

MediaRecorder使用示例 - 摄像头版

具体过程和上面类似,只是多了一步从摄像头中获取视频,放入canvas中渲染的过程。

使用API录制Canvas核心代码如下


let allChunks = [];
let format='video/webm;codecs=vp9'
const stream = canvas.captureStream(60); // 录制帧率60fps
const recorder = new MediaRecorder(stream, {
    mimeType: format
});
recorder.ondataavailable = e => {
    allChunks.push(
        e.data
    );
}

之后把allChunks放进一个blob对象,即可实现下载


const fullBlob = new Blob(allChunks);
const downloadUrl = window.URL.createObjectURL(fullBlob);
link.href = downloadUrl;
link.download = 'media.mp4';

完整代码请看参见案例工程目录

录制出的流是完整有效的吗?

我们知道一个完整的媒体文件中,流数据的组成是很复杂的,包括头文件,预测帧等等,当我们开始录制后,不一定马上就能获得可播放的文件。

所以,该api提供了一个事件,ondataavailable,当浏览器的录制编码进程积攒出可以使用的媒体数据后,就会抛出该事件,告诉我们“录制的数据已经可用了”,把数据移交给用户做进一步处理。

我们可以打开样例中的开关,来观察console中这个data被抛出的过程。

有没有替代方案?

由于媒体编码依赖浏览器底层的实现,所以很难在代码层面进行polyfill。在采集设备音频的场景下,可以使用使用AudioNodes替代,视频和canvas暂时无解。

和WebRTC的关系?

其实两者不是同一个层面的概念,Web Real-Time Communication(Web实时通信,WebRTC)由一组标准,由一系列Web API组成,从采集、编码到通信层面都有涉及。而Media Recorder只是对WebRTC方案做了一个补充,为录制后的视频提供了一个落地方案。

二者都是由w3c制定并致力推进,但ios和微软反应冷淡,所以目前的兼容性都不理想,还停留在实验阶段。期待Web标准化进程持续推进,进一步解放开发者的生产力,使web应用更加天马行空。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 什么可以录?
  • 录出来的是什么?
  • 视频编码格式?
  • MediaRecorder工作流程
  • 录制出的流是完整有效的吗?
  • 有没有替代方案?
  • 和WebRTC的关系?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档