TML5的权限越来越大了,浏览器可以直接调用摄像头、麦克风了,好激动啊。我们要用纯洁的HTML代码造出自己的天地。
视频采集
本篇介绍的栗子 都是在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/rStTGz for more details.
根据谷歌的意思,常用的安全环境有如下
http://localhost
http://127.0.0.1
https 开头的地址页面
如果你做了一个视频测试的页面,想嘚瑟给局域网的其他人,但是又没有域名证书怎么办?
这时候只能通过修改其他人的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,那么我们录制的视频就可以被保存为这种指定的格式。
如果不指定,那么将会使用浏览器自动指定的文件格式。文档原话如下
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>
注意:本例并没有填写视频文件头,所以保存出来的视频文件没有时间轨,无法快进和跳跃。可以用格式工厂转
“莫基了”上面有一个录制音频的例子 传送门:http://t.cn/RvxZAeo
这篇文章的DEMO请戳 这里:http://t.cn/RVt9Q6I
☞―――――――――↓―――――――――☜
相关阅读
多屏互动——H5中级进阶
前端,想说爱你不容易!
无需Flash实现图片裁剪——HTML5中级进阶
作者信息
作者来自力谱宿云 LeapCloud 团队_UX成员:王诗诗 【原创】
力谱宿云 LeapCloud 团队首发:https://blog.maxleap.cn/archives/1197
欢迎关注微信订阅号:MaxLeap_yidongyanfa
08年HTML5第一份正式草案发布后,业界就视其为一个充满希望的新生儿。有人曾预言HTML5将成为互联网的新大陆,在那些年这是个充满争议的话题,而如今其伴随移动互联网而野蛮生长和无孔不入,当年的预言也逐渐成为现实。
14年手机小游戏《围住神经猫》的一夜爆红令HTML5游戏开发工具白鹭引擎一举成名,同时也让更多人看到了HTML5的广阔前景。随着其最大绊脚石IE+Flash的日渐式微,HTML5在移动互联时代高歌猛进,成为唯一通吃Windows、Linux、OS X、iOS、安卓和WP的跨平台语言。
我们知道,在移动互联网初期原生APP制约了开发规则和利润分配,商家、开发者都急于寻求一种规范统一、技术开放的WebAPP来打破原生APP的垄断,HTML5显然成了他们的垂青对象。HTML5依赖开放Web分布,很好地继承了传统Web超文本时代的链接经济;同时还能实现原本只有原生APP才能实现的诸如LBS、本地数据存储、音视频播放、调用摄像头和GPU硬件加速等功能。也就是说,WebAPP不仅继承了Web的特性,还能够替代APP的大部分功能,无论从用户体验层面还是从应用间数据传输来看都是非常棒的选择。这让人不禁想起B/S架构取代C/S风靡互联网的种种经典案例。
随着HTML5未来愈渐明朗,互联网公司围绕着WebAPP的建设也开始大张旗鼓。搜狐力推的快站,百度的直达号,腾讯的微信公众账号,阿里的UC应用中心,都采用HTML5技术,各大平台都希望利用WebAPP来打造移动产品的生态基础。这不仅仅说明HTML5技术、开发上的便利性,更体现在商业模式上的多元化,用户体验和生态扩大的固有需求。
很多人已经知道搜狐快站是一个一站式移动建站云平台,服务贴近中小企业需求,而近期其所宣布的全面免费也颇体现了互联网的开放分享精神。快站樊功臣在无穷俱乐部沙龙上强调了APP和HTML5之间为什么选择后者,一方面是看中了HTML5重交互、重开放的特性, H5能满足中小企业百分之八九十的建站需求,企业对信息服务的推广是在任何地方传播任何内容,它可以无孔不入,相对APP的成本壁垒则较低;另一方面APP还面临一个更新难的问题,更新一个功能需要来回发版重做,效率低下,而HTML5能够克服各种困难,因为它背后的驱动力非常强大,国内几乎平台级公司都是其推动者。
我们认为,快站集搜狐技术部15年建站的组织过程资产积累,包括CMS、社区互动和电子商务版本,其产品成熟品质可靠值得肯定,而上线数月来已打通百度直达号、微信公众平台和各大搜索引擎等等,为快站的13万多家站点提供强力引流的成绩来看,其发展还是非常迅速的。这也从侧面验证了HTML5的生态渗透性是如何地“无孔不入”。
尽管HTML5具备众多卓越性,但在移动端与原生APP之争仍处下风,主要原因归结为以下四点:
1、标准尚未完善,技术不成熟,开发者生态不完整;
2、尚未突破载体瓶颈,浏览器渲染性能低下;
3、缺乏渠道、运营商等成熟生态支持;
4、对网络环境依赖较大。
这些原因最终造成HTML5在部分功能和体验上大打折扣,但事实上我们发现随着互联网公司逐渐入局和开发者生态日渐完善,加之业界上游对技术性能的解决,大多是可以克服的。
未来趋势来看,HTML5成为主流我们几乎都可预见。跨平台、低成本、程序快速迭代、开放的数据交互,这些显著优势都将成为企业、开发者选择HTML5的理由。以版本交付为例,很多开发者有这样的体会,一个原生APP上线,这时突如其来的一个大BUG往往成为大麻烦,开发者须连夜修复然后静待二、三周Apple审核,这段时间往往就已决定这款产品的成败。而HTML5则没有这样的问题,你只需修复再刷新即可。
最近,业界传来了可喜消息:W3C宣布HTML5标准于今年10月底正式定稿,这为所有HTML5开发者注入了一针强心剂,也预示着HTML5的时代即将全面来临。有了标准,剩下的就是完善生态的事情了。值得一提,搜狐在新闻客户端产品曾领跑至前,而快站的免费策略与开发者体系的支持完善,汇聚更多开发人才和专业者智慧,打造全面拥抱移动互联网的HTML5移动建站云平台及衍生生态,其未来表现令人期许。
近项目中需要实时播放摄像头rtsp视频流,于是就专门做了些研究。而浏览器不能直接播放,只有通过插件或者转码来实现这个需求。
要实现这个目的,可以采用的方案非常得多,有商业的也有开源的,这里主要列举一些开源的方案。这里的方案都是我尝试过了的,有些成功,有些没成功。但是因为每个项目情况不同,这次没成的方法,换个项目也许就能成。
方案一: html5 + websocket_rtsp_proxy 实现视频流直播
实现原理
实现步骤
<video id="test_video" controls autoplay></video>
<script src="free.player.1.8.4.js"></script>
<script>
if (window.Streamedian) {
var errHandler = function(err){
console.log('err', err.message);
};
var infHandler = function(inf) {
console.log('info', inf)
};
var playerOptions = {
socket: "ws://localhost:8088/ws/",
redirectNativeMediaErrors : true,
bufferDuration: 30,
errorHandler: errHandler,
infoHandler: infHandler
};
var html5Player = document.getElementById("test_video");
html5Player.src = "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov";
var player = Streamedian.player('test_video', playerOptions);
window.onbeforeunload = function(){
player && player.destroy();
player = null;
Request = null;
}
}
</script>
注意:测试时先从官网申请license key,否则socket 只能识别localhost和127.0.0.1
优缺点
参考链接
rtmp是adobe开发的协议,一般使用adobe media server 可以方便的搭建起来;随着开源时代的到来,有大神开发了nginx的rtmp插件,也可以直接使用nginx实现rtmp
rtmp方式的最大的优点在于低延时,经过测试延时普遍在1-3秒,可以说很实时了;缺点在于它是adobe开发的,rtmp的播放严重依赖flash,而由于flash本身的安全,现代浏览器大多禁用flash
相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】
音视频免费学习地址:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~
实现步骤
rtmp{
server{
listen 1935;
application live{
live on;
record off;
}
application hls{
live on;
hls on;
hls_path nginx-rtmp-module/hls;
hls_cleanup off;
}
}
}
ffmpeg转码
ffmpeg -i "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov" -f flv -r 25 -s 1080*720 -an "rtmp://127.0.0.1:1935/hls/mystream"
video 播放
<html>
<head>
<title>video</title>
<!-- 引入css -->
<link rel="stylesheet" type="text/css" href="./videojs/video-js.min.css" />
</head>
<body>
<video id="test_video" class="video-js vjs-default-skin vjs-big-play-centered" controls autoplay>
<source src='rtmp://127.0.0.1:1935/hls/mystream' type='rtmp/flv'/>
</video>
</body>
</html>
<!-- 引入js -->
<script type="text/javascript" src="./videojs/video.min.js"></script>
<script type="text/javascript" src="./videojs/videojs-flash.js"></script>
<script>
videojs.options.flash.swf = "./videojs/video-js.swf"
var player = videojs('test_video', {"autoplay":true});
player.play();
</script>
注意:使用谷歌浏览器播放时,需要开启flash允许
参考链接
方案三:ffmpeg + video,rtsp转hls播放
HLS (HTTP Live Streaming) 直播 是有苹果提出的一个基于http的协议。其原理是把整个流切分成一个个的小视频文件,然后通过一个m3u8的文件列表来管理这些视频文件
HTTP Live Streaming 并不是一个真正实时的流媒体系统,这是因为对应于媒体分段的大小和持续时间有一定潜在的时间延时。在客户端,至少在一个分段媒体文件被完全下载后才能够开始播放,而通常要求下载完两个媒体文件之后才开始播放以保证不同分段音视频之间的无缝连接。
此外,在客户端开始下载之前,必须等待服务器端的编码器和流分割器至少生成一个TS文件,这也会带来潜在的时延。
服务器软件将接收到的流每缓存一定时间后包装为一个新的TS文件,然后更新m3u8文件。m3u8文件中只保留最新的几个片段的索引,以保证观众任何时候连接进来都会看到较新的内容,实现近似直播的效果。
这种方式的理论最小延时为一个ts文件的时长,一般为2-3个ts文件的时长。
实现步骤
ffmpeg -i "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov" -c copy -f hls -hls_time 2.0 -hls_list_size 0 -hls_wrap 15 "D:/Program Files/html/hls/test.m3u8"
ffmpeg 关于hls方面的指令说明
<html>
<head>
<title>video</title>
<!-- 引入css -->
<link rel="stylesheet" type="text/css" href="./videojs/video-js.min.css" />
</head>
<body>
<div class="videoBox">
<video id="my_video_1" class="video-js vjs-default-skin" controls>
<source src="http://localhost:8088/hls/test.m3u8" type="application/x-mpegURL">
</video>
</div>
</body>
</html>
<script type="text/javascript" src="./videojs/video.min.js"></script>
<script type="text/javascript" src="./videojs/videojs-contrib-hls.min.js"></script>
<script>
videojs.options.flash.swf = "./videojs/video-js.swf"
var player = videojs('my_video_1', {"autoplay":true});
player.play();
</script>
参考链接
方案四:VLC插件播放
播放步骤
<object type='application/x-vlc-plugin' pluginspage="http://www.videolan.org/" id='vlc' events='false' width="720" height="410">
<param name='mrl' value='rtsp://admin:12345@192.168.10.235:554/h264/ch1/main/av_stream' />
<param name='volume' value='50' />
<param name='autoplay' value='true' />
<param name='loop' value='false' />
<param name='fullscreen' value='false' />
<param name='controls' value='false' />
</object>
优缺点
参考链接
其他方案
WebRTC
WebRTC 是支持网页浏览器进行实时音视频的一套API,例如:HTML5 通过 webRTC 直接调用摄像头,但是如果要实现远程视频流的显示,则需要将 RTSP 转换为 WebRTC 流,供 web 端显示。
参考地址:github.com/lulop-k/kur…
h5stream
参考地址:
参考地址:
参考地址
原文 浏览器播放rtsp视频流解决方案 - 掘金
*请认真填写需求信息,我们会在24小时内与您取得联系。