未加星标

无需Flash录视频――HTML5中级进阶

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏
视频采集

本篇介绍的栗子 都是在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. See https://goo.gl/rStTGz for more details.

根据谷歌的意思,常用的安全环境有如下

http://localhost http://127.0.0.1 https 开头的地址页面

如果你做了一个视频测试的页面,想V瑟给局域网的其他人,但是又没有域名证书怎么办?

这时候只能通过修改其他人的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.设备枚举

在开启摄像头之前,先要把可以使用的麦克风和摄像头 ( 输入设备 ) 列出来,如果没有这两样设备也就无法继续。

代码如下:

<labelfor="audioDevice"> 录音设备: </label> <select id="audioDevice"> </select> <br> <labelfor="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>

效果如下图,和浏览器自己获取的一模一样。


无需Flash录视频――HTML5中级进阶

注意:上图的实例中,浏览器地址栏最右边的摄像头标识是需要使用 getUserMedia()函数时才会出现。

<script> var getUserMedia = 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> 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,那么他会从视频中心截取 30×100 的画面,而不是把原画面挤压到这个30×100的尺寸。

效果如下:


无需Flash录视频――HTML5中级进阶

如果您的预览一片漆黑,或者只有一个小黑点,那么说明您的摄像头正在被占用…

吐槽:这个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> 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中级进阶

前端,想说爱你不容易!

作者信息

作者来自力谱宿云 LeapCloud 团队_UX成员:王诗诗 【原创】

王诗诗,前端新人,专职前端工作两年。曾供职于AMI做底层软件开发。喜欢分析H5代码,追崇用简单的CSS,构建精美动效,做前端之前,这些是业余爱好。现任职于MaxLeap UX 组,负责MaxWon 的开发和维护。现热衷于Real-time WebApp。

作者往期佳作

无需Flash实现图片裁剪――html5中级进阶

多屏互动――H5中级进阶

-力谱宿云 LeapCloud 团队首发-

欢迎关注微信订阅号:MaxLeap_yidongyanfa


无需Flash录视频――HTML5中级进阶

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: 浏览器HTMLHTML5Chrome服务器CSS微信数据UA谷歌
分页:12
转载请注明
本文标题:无需Flash录视频――HTML5中级进阶
本站链接:http://www.codesec.net/view/482245.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(44)