无需Flash录视频——HTML5中级进阶
本篇介绍的栗子 都是在chrome 47 版本以上的,低版本的可能会出现白屏和错误。
1.安全环境随着Chrome版本的升高,安全性问题也越来越被重视,较新版本的Chrome浏览器在调用一些API时需要页面处在安全环境中。本篇文章所介绍的API函数,都需要在安全环境中执行。如果处在非安全环境下 ( http页面 ) 这些API就会有意想不到的问题。
比如 getUserMedia()就会报出警告,并执行出错。
而在设备枚举enumerateDevices()时,虽然不会报错,但是他隐藏了设备label。
注意:第一次在一个安全页面下执行enumerateDevices()时也会隐藏label,在允许使用摄像头等设备后,第二次执行才会显示label。
getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. Seehttps://goo.gl/rStTGzfor more details.
根据谷歌的意思,常用的安全环境有如下
http://localhost
http://127.0.0.1
https 开头的地址页面
如果你做了一个视频测试的页面,想嘚瑟给局域网的其他人,但是又没有域名证书怎么办?
这时候只能通过修改其他人的hosts文件了
比如你的测试服务器IP地址是192.168.2.18,那么其他人的hosts文件修改如下:
#localhost127.0.0.1localhost192.168.2.18
当使用别人的Chrome浏览器访问http://localhost/[getUserMediaTestPage]时,就会顺利的执行这些API了。
但是移动端的浏览器并不认localhost,就算你修改了hosts ,移动端的浏览器根本不理你,解析都不解析。
所以想在手机上测试,只能老老实实申请个证书了。
2.设备枚举在开启摄像头之前,先要把可以使用的麦克风和摄像头 ( 输入设备 ) 列出来,如果没有这两样设备也就无法继续。
代码如下:
<labelfor="audioDevice">录音设备:</label><selectid="audioDevice"></select><br><labelfor="videoDevice">录影设备:</label><selectid="videoDevice"></select><script>navigator.mediaDevices.enumerateDevices().then(function(data){data.forEach(function(item){if(item.kind=="audioinput"){//麦克风document.getElementById("audioDevice").innerHTML+="<optionvalue='"+item.deviceId+"'>"+item.label+"</option>"}elseif(item.kind=="videoinput"){//摄像头document.getElementById("videoDevice").innerHTML+="<optionvalue='"+item.deviceId+"'>"+item.label+"</option>"}})},function(error){console.log(error);})</script>
效果如下图,和浏览器自己获取的一模一样。
注意:上图的实例中,浏览器地址栏最右边的摄像头标识是需要使用 getUserMedia()函数时才会出现。
<script>vargetUserMedia=navigator.webkitGetUserMedia;//Chrome浏览器的方法getUserMedia.call(navigator,{video:true,//开启音频audio:true//开启视频},function(stream){console.log(stream);//成功获取媒体流},function(error){//处理媒体流创建失败错误});</script>
这时候可以通过浏览器给出的菜单下拉选择设备。
3.设置参数,预览我们可以通过代码来指定使用哪个摄像头和麦克风设备。
也可以通过代码设置视频的宽、高和帧率。
代码如下:
<videoid="video"autoplay></video><!--一定要有autoplay--><script>vargetUserMedia=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,那么我们录制的视频就可以被保存为这种指定的格式。
如果不指定,那么将会使用浏览器自动指定的文件格式。文档原话如下
If this paramater is not specified, the UA will use a platform-specific default format.
但是这个默认值却无法直接获取,全靠猜...
2. 视频录制 MediaRecorder我们使用 MediaRecorder来录制视频,参数是通过getUserMedia()获取的媒体流。
通过绑定ondataavailable事件,来获取视频片段数据,并在内存中累积。
录制的开始和结束分别使用 start和stop 函数。
执行start之后会周期性触发ondataavailable事件。
执行stop之后会停止触发ondataavailable事件。
录制结束后,把累计的片段数据保存为blob对象,并从浏览器下载存为视频文件。
代码如下:
<script>vargetUserMedia=navigator.webkitGetUserMedia;varg_stream=null,g_recorder=null;functionstartPreview(){getUserMedia.call(navigator,{video:true,audio:true},function(stream){g_stream=stream;},function(error){});}functionstopRecording(){g_recorder.stop();}functionstartRecording(){varchunks=[];g_recorder=newMediaRecorder(g_stream,{mimeType:"video/webm"});g_recorder.ondataavailable=function(e){chunks.push(e.data);}g_recorder.onstop=function(e){varblob=newBlob(chunks,{'type':'video/webm'});varaudioURL=URL.createObjectURL(blob);window.open(audioURL);}g_recorder.start();}</script>
注意:本例并没有填写视频文件头,所以保存出来的视频文件没有时间轨,无法快进和跳跃。可以用格式工厂转
“莫基了”上面有一个录制音频的例子传送门
这篇文章的DEMO请戳这里
相关阅读
多屏互动——H5中级进阶
前端,想说爱你不容易!
作者信息
作者来自力谱宿云 LeapCloud 团队_UX成员:王诗诗 【原创】
王诗诗,前端新人,专职前端工作两年。曾供职于AMI做底层软件开发。喜欢分析H5代码,追崇用简单的CSS,构建精美动效,做前端之前,这些是业余爱好。现任职于MaxLeapUX 组,负责MaxWon 的开发和维护。现热衷于Real-time WebApp。
作者往期佳作
无需Flash实现图片裁剪——HTML5中级进阶
多屏互动——H5中级进阶
力谱宿云 LeapCloud 团队首发:https://blog.maxleap.cn/archives/1197
欢迎关注微信订阅号:MaxLeap_yidongyanfa
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。