详解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 相关文章推荐
javascript showModalDialog 多层模态窗口实现页面提交及刷新的代码
Nov 28 Javascript
使用GruntJS构建Web程序之构建篇
Jun 04 Javascript
在JS中操作时间之getUTCMilliseconds()方法的使用
Jun 10 Javascript
jquery实现(textarea)placeholder自动换行
Dec 22 Javascript
JavaScript数组去重的多种方法(四种)
Sep 19 Javascript
mockjs,json-server一起搭建前端通用的数据模拟框架教程
Dec 18 Javascript
bootstrap fileinput插件实现预览上传照片功能
Jan 23 Javascript
微信小程序实现默认第一个选中变色效果
Jul 17 Javascript
localstorage实现带过期时间的缓存功能
Jun 28 Javascript
Jquery属性的获取/设置及样式添加/删除操作技巧分析
Dec 23 jQuery
jQuery 函数实例分析【函数声明、函数表达式、匿名函数等】
May 19 jQuery
javascript canvas时钟模拟器
Jul 13 Javascript
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中的使用情况
2015/11/05 PHP
php版微信公众号接口实现发红包的方法
2016/10/14 PHP
CI框架使用composer安装的依赖包步骤与方法分析
2016/11/21 PHP
JavaScript使用prototype定义对象类型
2007/02/07 Javascript
Javascript 自适应高度的Tab选项卡
2011/04/05 Javascript
JavaScript使用focus()设置焦点失败的解决方法
2014/09/03 Javascript
js实现精美的图片跟随鼠标效果实例
2015/05/16 Javascript
基于javascript实现随机颜色变化效果
2016/01/14 Javascript
使用bootstrap typeahead插件实现输入框自动补全之问题及解决办法
2016/07/07 Javascript
JavaScript学习小结之被嫌弃的eval函数和with语句实例详解
2016/08/01 Javascript
vue2.0项目中使用Ueditor富文本编辑器示例代码
2017/08/14 Javascript
vue axios 表单提交上传图片的实例
2018/03/16 Javascript
vue根据值给予不同class的实例
2018/09/29 Javascript
element ui分页多选,翻页记忆的实例
2019/09/03 Javascript
快速解决layui弹窗按enter键不停弹窗的问题
2019/09/18 Javascript
vue中上传视频或图片或图片和文字一起到后端的解决方法
2019/12/01 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
2020/05/06 Javascript
[28:48]《真视界》- 2017年国际邀请赛
2017/09/27 DOTA
[54:57]DOTA2-DPC中国联赛定级赛 Aster vs DLG BO3第二场 1月8日
2021/03/11 DOTA
[47:43]完美世界DOTA2联赛PWL S3 Magama vs GXR 第二场 12.19
2020/12/24 DOTA
Python模块文件结构代码详解
2018/02/03 Python
Anaconda 离线安装 python 包的操作方法
2018/06/11 Python
python selenium 获取标签的属性值、内容、状态方法
2018/06/22 Python
python redis 删除key脚本的实例
2019/02/19 Python
python pandas模块基础学习详解
2019/07/03 Python
cProfile Python性能分析工具使用详解
2019/07/22 Python
wxpython布局的实现方法
2019/11/01 Python
html5定制表单_动力节点Java学院整理
2017/07/11 HTML / CSS
完美实现CSS垂直居中的11种方法
2021/03/27 HTML / CSS
简历里的自我评价范文
2014/02/24 职场文书
小学毕业感言500字
2014/02/28 职场文书
新闻传媒系求职信范文
2014/04/19 职场文书
党的群众路线教育实践活动宣传标语口号
2014/06/06 职场文书
大学本科生职业生涯规划书范文
2014/09/14 职场文书
2015年八一建军节慰问信
2015/03/23 职场文书
投诉书格式范本
2015/07/02 职场文书