无需Flash录视频――HTML5中级进阶
视频采集本篇介绍的栗子 都是在chrome 47 版本以上的,低版本的可能会出现白屏和错误。 1.安全环境随着Chrome版本的升高,安全性问题也越来越被重视,较新版本的Chrome浏览器在调用一些API时需要页面处在安全环境中。本篇文章所介绍的API函数,都需要在安全环境中执行。如果处在非安全环境下 ( http页面 ) 这些API就会有意想不到的问题。 比如 getUserMedia()就会报出警告,并执行出错。 而在设备枚举enumerateDevices()时,虽然不会报错,但是他隐藏了设备label。 注意:第一次在一个安全页面下执行enumerateDevices()时也会隐藏label,在允许使用摄像头等设备后,第二次执行才会显示label。
根据谷歌的意思,常用的安全环境有如下
如果你做了一个视频测试的页面,想?N瑟给局域网的其他人,但是又没有域名证书怎么办? 这时候只能通过修改其他人的hosts文件了 比如你的测试服务器IP地址是192.168.2.18,那么其他人的hosts文件修改如下: #localhost?127.0.0.1 localhost?192.168.2.18 当使用别人的Chrome浏览器访问?http://localhost/[getUserMediaTestPage]时,就会顺利的执行这些API了。 但是移动端的浏览器并不认localhost,就算你修改了hosts ,移动端的浏览器根本不理你,解析都不解析。 所以想在手机上测试,只能老老实实申请个证书了。 2.设备枚举在开启摄像头之前,先要把可以使用的麦克风和摄像头 ( 输入设备 ) 列出来,如果没有这两样设备也就无法继续。 代码如下: <label?for="audioDevice">?录音设备:?</label> <select?id="audioDevice"> </select> <br> <label?for="videoDevice">?录影设备:?</label> <select?id="videoDevice"> </select> <script> navigator.mediaDevices.enumerateDevices().then(function?(data)?{ ??data.forEach(function?(item)?{ ????if(item.kind=="audioinput"){?//麦克风 ?????document.getElementById("audioDevice").innerHTML?+=??"<option?value='"+?item.deviceId?+"'>"?+?item.label?+?"?</option>?" ????}else?if(item.kind=="videoinput"){?//摄像头 ?????document.getElementById("videoDevice").innerHTML?+=??"<option?value='"+?item.deviceId?+"'>"?+?item.label?+?"?</option>?" ????} ??}) },function?(error)?{ ??console.log(error); }) </script> 效果如下图,和浏览器自己获取的一模一样。 注意:上图的实例中,浏览器地址栏最右边的摄像头标识是需要使用 getUserMedia()函数时才会出现。 <script> ??var?getUserMedia?=?navigator.webkitGetUserMedia;?//Chrome浏览器的方法 ????getUserMedia.call(navigator,?{ ??????video:true,?//?开启音频 ??????audio:true??//?开启视频 ????},?function(stream){ ????????console.log(stream);?//?成功获取媒体流 ????},?function(error){ ????????//处理媒体流创建失败错误 ????}); </script> 这时候可以通过浏览器给出的菜单下拉选择设备。 3.设置参数,预览我们可以通过代码来指定使用哪个摄像头和麦克风设备。 也可以通过代码设置视频的宽、高和帧率。 代码如下: <video?id="video"?autoplay></video>?<!--?一定要有?autoplay?--> <script> var?getUserMedia?=?navigator.webkitGetUserMedia?; getUserMedia.call(navigator,?{ ??"audio":{ ????"mandatory":{ ??????"sourceId":""?//?指定设备的?deviceId ????} ??},??"video":{ ????????"optional":[? ????????????{"minWidth":400},????????????{"maxWidth":400},??//?数字类型,固定宽度 ????????????{"minHeight":220},? ??????{"maxHeight":220},??//?数字类型,固定高度 ????????????{"frameRate":"12"}??//?帧率 ????????],"mandatory":{ ????????"sourceId":""?//?指定设备的?deviceId ????????} ??????} },?function(stream){ ????//绑定本地媒体流到video标签用于输出 ????document.getElementById("video").src?=?URL.createObjectURL(stream); },?function(error){ ????//处理媒体流创建失败错误 }); </script> 输出的视频流通过blob对象链接绑定到video标签输出。 这个deviceId就是从上文设备枚举 enumerateDevices() 获取到的。 两种设备,如果有一个deviceId填写不正确,就会报出一个DevicesNotFoundError的错误。 而且一旦指定了设备后,浏览器自己的设备选择就会变成灰色不可选。 视频的宽高,并不会因为填写的数值比例不合法而失真。 比如你设定了宽度30,高度100,那么他会从视频中心截取 30x100 的画面,而不是把原画面挤压到这个30x100的尺寸。 效果如下: 如果您的预览一片漆黑,或者只有一个小黑点,那么说明您的摄像头正在被占用... 吐槽:这个getUserMedia()函数的参数,w3的官方文档链接如下: https://www.w3.org/TR/mediacapture-streams/ 可是Chrome并没有遵循它,而且差距还挺大... 视频保存1. 格式支持Chrome浏览器是大力推广webm的视频格式的。可以用MediaRecorder.isTypeSupported("video/webm")来测试是否支持这种类型的编码。 如果返回true,那么我们录制的视频就可以被保存为这种指定的格式。 如果不指定,那么将会使用浏览器自动指定的文件格式。文档原话如下
但是这个默认值却无法直接获取,全靠猜... 2. 视频录制 MediaRecorder我们使用 MediaRecorder来录制视频,参数是通过getUserMedia()获取的媒体流。
<script> var?getUserMedia?=?navigator.webkitGetUserMedia?; var?g_stream?=?null,?g_recorder?=?null; function?startPreview(){ ??getUserMedia.call(navigator,?{ ??video:true,??audio:true ??},?function(stream){ ??????g_stream?=?stream; ??},?function(error){ ??}); } function?stopRecording(){ ??g_recorder.stop(); } function?startRecording(){ ??var?chunks?=?[]; ??g_recorder?=?new?MediaRecorder(g_stream,{mimeType:"video/webm"}); ??g_recorder.ondataavailable?=?function(e)?{ ????chunks.push(e.data); ??} ??g_recorder.onstop?=?function(e)?{ ????var?blob?=?new?Blob(chunks,?{?'type'?:?'video/webm'?}); ????var?audioURL?=?URL.createObjectURL(blob); ????window.open(audioURL); ??} ??g_recorder.start(); } </script> 注意:本例并没有填写视频文件头,所以保存出来的视频文件没有时间轨,无法快进和跳跃。可以用格式工厂转 “莫基了”上面有一个录制音频的例子?传送门 这篇文章的DEMO请戳?这里 相关阅读 多屏互动――H5中级进阶
作者信息 王诗诗,前端新人,专职前端工作两年。曾供职于AMI做底层软件开发。喜欢分析H5代码,追崇用简单的CSS,构建精美动效,做前端之前,这些是业余爱好。现任职于MaxLeap?UX 组,负责MaxWon 的开发和维护。现热衷于Real-time WebApp。 作者往期佳作 无需Flash实现图片裁剪――HTML5中级进阶 力谱宿云 LeapCloud 团队首发:?https://blog.maxleap.cn/archives/1197 欢迎关注微信订阅号:MaxLeap_yidongyanfa (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |