详解js的视频和音频采集


Posted in Javascript onAugust 09, 2018

今天要写的,不是大家平时会用到的东西。因为兼容性实在不行,只是为了说明下前端原来还能干这些事。
大家能想象前端是能将摄像头和麦克风的视频流和音频流提取出来,再为所欲为的么。或者说我想把我canvas画板的内容录制成一个视频,这些看似js应该做不到的事情,其实都是可以做到的,不过兼容性不好。我在这里都是以chrome浏览器举的例子。

这里先把用到的api列一下:

  • getUserMedia:打开摄像头和麦克风的接口(文档链接)
  • MediaRecorder:采集音视频流(文档链接)
  • srcObject:video标签可直接播放视频流,这是一个大家应该很少用到其实兼容性很好的属性,推荐大家了解(文档链接)
  • captureStream:可以将canvas输出流,其实不单单是canvas这里只是举有这个功能,具体的可以看文档(文档链接)

1、从摄像头展示视频

一、打开摄像头

// 这里是打开摄像头和麦克设备(会返回一个Promise对象)
navigator.mediaDevices.getUserMedia({
 audio: true,
 video: true
}).then(stream => {
 console.log(stream) // 放回音视频流
}).catch(err => {
 console.log(err) // 错误回调
})

上面我们成功打开了摄像头和麦克风,并获取到视频流。那接下来就是要把流呈现到交互界面中了。

二、展示视频

<!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">
 <title>Document</title>
</head>
<body>
 <video id="video" width="500" height="500" autoplay></video>
</body>
<script>
 var video = document.getElementById('video')
 navigator.mediaDevices.getUserMedia({
 audio: true,
 video: true
 }).then(stream => {
 // 这里就要用到srcObject属性了,可以直接播放流资源
 video.srcObject = stream
 }).catch(err => {
 console.log(err) // 错误回调
 })
</script>

效果如下图:

详解js的视频和音频采集

到这里为止我们已经成功的将我们的摄像头在页面展示了。下一步就是如何将采集视频,并下载视频文件。

2、从摄像头采集视频

这里用到的是MediaRecorder对象:

创建一个新的MediaRecorder对象,返回一个MediaStream 对象用来进行录制操作,支持配置项配置容器的MIME type (例如"video/webm" or "video/mp4")或者音频的码率视频码率

MediaRecorder接收两个参数第一个是stream音视频流,第二个是option配置参数。下面我们可以把上面摄像头获取的流加入MediaRecorder中。

var video = document.getElementById('video')
navigator.mediaDevices.getUserMedia({
 audio: true,
 video: true
}).then(stream => {
 // 这里就要用到srcObject属性了,可以直接播放流资源
 video.srcObject = stream
 var mediaRecorder = new MediaRecorder(stream, {
 audioBitsPerSecond : 128000, // 音频码率
 videoBitsPerSecond : 100000, // 视频码率
 mimeType : 'video/webm;codecs=h264' // 编码格式
 })
}).catch(err => {
 console.log(err) // 错误回调
})

在上面我们创建了MediaRecorder的实例mediaRecorder。接下来就是控制mediaRecorder的开始采集和停止采集的方法了。
MediaRecorder提供了一些方法和事件供我们使用:

  • MediaRecorder.start(): 开始录制媒体,这个方法调用时可以通过给timeslice参数设置一个毫秒值,如果设置这个毫秒值,那么录制的媒体会按照你设置的值进行分割成一个个单独的区块, 而不是以默认的方式录制一个非常大的整块内容.
  • MediaRecorder.stop(): 停止录制. 同时触发dataavailable事件,返回一个存储Blob内容的录制数据.之后不再记录
  • ondataavailable事件: MediaRecorder.stop触发该事件,该事件可用于获取记录的媒体(Blob在事件的data属性中可用作对象)
// 这里我们增加两个按钮控制采集的开始和结束
var start = document.getElementById('start')
var stop = document.getElementById('stop')
var video = document.getElementById('video')
navigator.mediaDevices.getUserMedia({
 audio: true,
 video: true
}).then(stream => {
 // 这里就要用到srcObject属性了,可以直接播放流资源
 video.srcObject = stream
 var mediaRecorder = new MediaRecorder(stream, {
 audioBitsPerSecond : 128000, // 音频码率
 videoBitsPerSecond : 100000, // 视频码率
 mimeType : 'video/webm;codecs=h264' // 编码格式
 })
 // 开始采集
 start.onclick = function () {
 mediaRecorder.start()
 console.log('开始采集')
 }
 // 停止采集
 stop.onclick = function () {
 mediaRecorder.stop()
 console.log('停止采集')
 }
 // 事件
 mediaRecorder.ondataavailable = function (e) {
 console.log(e)
 // 下载视频
 var blob = new Blob([e.data], { 'type' : 'video/mp4' })
 let a = document.createElement('a')
 a.href = URL.createObjectURL(blob)
 a.download = `test.mp4`
 a.click()
 }
}).catch(err => {
 console.log(err) // 错误回调
})

ok,现在执行一波操作;

详解js的视频和音频采集

上图可以看到结束采集后ondataavailable事件返回的数据中有一个Blob对象,这就是视频资源了,再接下来我们就可以通过URL.createObjectURL()方法将Blob为url下载到本地了。视频的采集到下载就结束了,很简单粗暴。

上面是视频采集下载的例子,如果只要音频采集的,同样道理的设置“mimeType”就好了。这里我就不举例了。下面我在介绍将canvas录制为一个视频文件

2、canvas输出视频流

这里用到的是captureStream方法,将canvas输出流,再用video展现,或者用MediaRecorder采集资源也是可以的。

// 这里就闲话少说直接上重点了因为和上面视频采集的是一样的道理的。
<!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">
 <title>Document</title>
</head>
<body>
 <canvas width="500" height="500" id="canvas"></canvas>
 <video id="video" width="500" height="500" autoplay></video>
</body>
<script>
 var video = document.getElementById('video')
 var canvas = document.getElementById('canvas')
 var stream = $canvas.captureStream(); // 这里获取canvas流对象
 // 接下来你先为所欲为都可以了,可以参考上面的我就不写了。
</script>

下面我再贴一个gif(这是结合我上次写的canvas事件的demo结合这次视频采集的结合)传送门(Canvas事件绑定)

希望大家可以实现下面的效果,其实还可以在canvas视频里插入背景音乐什么的,这些都比较简单。

详解js的视频和音频采集

Javascript 相关文章推荐
用JQuery调用Session的实现代码
Oct 29 Javascript
javascript中常用编程知识
Apr 08 Javascript
PHP abstract与interface之间的区别
Nov 11 Javascript
异步安全加载javascript文件的方法
Jul 21 Javascript
js实现的tab标签切换效果代码分享
Aug 25 Javascript
浅析JS运动
Dec 28 Javascript
javascript完美实现给定日期返回上月日期的方法
Jun 15 Javascript
JS中正则表达式要注意lastIndex属性
Aug 08 Javascript
js canvas实现二维码和图片合成的海报
Nov 19 Javascript
Js on及addEventListener原理用法区别解析
Jul 11 Javascript
解决vue一个页面中复用同一个echarts组件的问题
Jul 19 Javascript
vue基于Echarts的拖拽数据可视化功能实现
Dec 04 Vue.js
Angular中的ng-template及angular 使用ngTemplateOutlet 指令的方法
Aug 08 #Javascript
深入理解Promise.all
Aug 08 #Javascript
vue js秒转天数小时分钟秒的实例代码
Aug 08 #Javascript
vue devtools的安装与使用教程
Aug 08 #Javascript
jQuery AJAX 方法success()后台传来的4种数据详解
Aug 08 #jQuery
通过jquery的ajax请求本地的json文件方法
Aug 08 #jQuery
Vue 开发音乐播放器之歌手页右侧快速入口功能
Aug 08 #Javascript
You might like
PHP 多进程 解决难题
2009/06/22 PHP
PHP 无限分类三种方式 非函数的递归调用!
2011/08/26 PHP
php利用header函数下载各种文件
2016/08/24 PHP
在laravel中使用Symfony的Crawler组件分析HTML
2017/06/19 PHP
在Javascript里访问SharePoint列表数据的实现方法
2011/05/22 Javascript
通过onmouseover选项卡实现img图片的变化
2014/02/12 Javascript
JQuery分屏指示器图片轮换效果实例
2015/05/21 Javascript
[原创]jQuery常用的4种加载方式分析
2016/07/25 Javascript
JavaScript兼容性总结之获取非行间样式案例
2016/08/07 Javascript
bootstrap datepicker 与bootstrapValidator同时使用时选择日期后无法正常触发校验的解决思路
2016/09/28 Javascript
JS实现表单验证功能(验证手机号是否存在,验证码倒计时)
2016/10/11 Javascript
jQuery插件echarts实现的多柱子柱状图效果示例【附demo源码下载】
2017/03/04 Javascript
微信小程序 滚动到某个位置添加class效果实现代码
2017/04/19 Javascript
JavaScript实现邮箱后缀提示功能的示例代码
2018/12/13 Javascript
微信头像地址失效踩坑记附带解决方案
2019/09/23 Javascript
浅谈nuxtjs校验登录中间件和混入(mixin)
2020/11/06 Javascript
[00:18]天涯墨客三技能展示
2018/08/25 DOTA
[41:12]Liquid vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.24
2019/09/10 DOTA
python通过字典dict判断指定键值是否存在的方法
2015/03/21 Python
Python实现新型冠状病毒传播模型及预测代码实例
2020/02/05 Python
Python迭代器Iterable判断方法解析
2020/03/16 Python
python高级特性简介
2020/08/13 Python
CSS3动画特效在活动页中的应用
2020/01/21 HTML / CSS
html5使用canvas画三角形
2014/12/15 HTML / CSS
Html5 页面适配iPhoneX(就是那么简单)
2019/09/05 HTML / CSS
Geekbuying波兰:购买中国电子产品
2019/10/20 全球购物
人力资源管理毕业生自荐信
2013/11/21 职场文书
带薪年假请假条
2014/02/04 职场文书
2014财产信托协议书范本
2014/11/18 职场文书
2014小学教师年度考核工作总结
2014/12/03 职场文书
教师年度个人总结
2015/02/11 职场文书
2015医院个人工作总结范文
2015/05/21 职场文书
2016元旦文艺汇演主持词
2015/07/06 职场文书
2015年信息技术教研组工作总结
2015/07/22 职场文书
SpringBoot读取Resource下文件的4种方法
2021/07/02 Java/Android
logback如何自定义日志存储
2021/08/30 Java/Android