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
前不久抽空對目前比較火的視頻直播,做了下研究與探索,了解其整體實現流程,以及探討移動端HTML5直播可行性方案。
發現目前 WEB 上主流的視頻直播方案有 HLS 和 RTMP,移動 WEB 端目前以 HLS 為主(HLS存在延遲性問題,也可以借助 video.js 采用RTMP),PC端則以 RTMP 為主實時性較好,接下來將圍繞這兩種視頻流協議來展開H5直播主題分享。
1. HTTP Live Streaming
HTTP Live Streaming(簡稱 HLS)是一個基于 HTTP 的視頻流協議,由 Apple 公司實現,Mac OS 上的 QuickTime、Safari 以及 iOS 上的 Safari 都能很好的支持 HLS,高版本 Android 也增加了對 HLS 的支持。一些常見的客戶端如:MPlayerX、VLC 也都支持 HLS 協議。
HLS 協議基于 HTTP,而一個提供 HLS 的服務器需要做兩件事:
編碼:以 H.263 格式對圖像進行編碼,以 MP3 或者 HE-AAC 對聲音進行編碼,最終打包到 MPEG-2 TS(Transport Stream)容器之中;分割:把編碼好的 TS 文件等長切分成后綴為 ts 的小文件,并生成一個 .m3u8 的純文本索引文件;瀏覽器使用的是 m3u8 文件。m3u8 跟音頻列表格式 m3u 很像,可以簡單的認為 m3u8 就是包含多個 ts 文件的播放列表。播放器按順序逐個播放,全部放完再請求一下 m3u8 文件,獲得包含最新 ts 文件的播放列表繼續播,周而復始。整個直播過程就是依靠一個不斷更新的 m3u8 和一堆小的 ts 文件組成,m3u8 必須動態更新,ts 可以走 CDN。一個典型的 m3u8 文件格式如下:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000
gear1/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=311111
gear2/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=484444
gear3/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=737777
gear4/prog_index.m3u8
可以看到 HLS 協議本質還是一個個的 HTTP 請求 / 響應,所以適應性很好,不會受到防火墻影響。但它也有一個致命的弱點:延遲現象非常明顯。如果每個 ts 按照 5 秒來切分,一個 m3u8 放 6 個 ts 索引,那么至少就會帶來 30 秒的延遲。如果減少每個 ts 的長度,減少 m3u8 中的索引數,延時確實會減少,但會帶來更頻繁的緩沖,對服務端的請求壓力也會成倍增加。所以只能根據實際情況找到一個折中的點。
對于支持 HLS 的瀏覽器來說,直接這樣寫就能播放了:
<video src=”./bipbopall.m3u8″ height=”300″ width=”400″ preload=”auto” autoplay=”autoplay” loop=”loop” webkit-playsinline=”true”></video>
注意:HLS 在 PC 端僅支持safari瀏覽器,類似chrome瀏覽器使用HTML5 video
標簽無法播放 m3u8 格式,可直接采用網上一些比較成熟的方案,如:sewise-player、MediaElement、videojs-contrib-hls、jwplayer。
程序猿的生活:web前端全棧資料粉絲福利(面試題、視頻、資料筆記,進階路線)zhuanlan.zhihu.com/p/136454207
2. Real Time Messaging Protocol
Real Time Messaging Protocol(簡稱 RTMP)是 Macromedia 開發的一套視頻直播協議,現在屬于 Adobe。這套方案需要搭建專門的 RTMP 流媒體服務如 Adobe Media Server,并且在瀏覽器中只能使用 Flash 實現播放器。它的實時性非常好,延遲很小,但無法支持移動端 WEB 播放是它的硬傷。
雖然無法在iOS的H5頁面播放,但是對于iOS原生應用是可以自己寫解碼去解析的, RTMP 延遲低、實時性較好。瀏覽器端,HTML5 video
標簽無法播放 RTMP 協議的視頻,可以通過 video.js 來實現。
<link href=“http://vjs.zencdn.net/5.8.8/video-js.css” rel=“stylesheet”>
<video id=“example_video_1″ class=“video-js vjs-default-skin” controls preload=“auto” width=“640” height=“264” loop=“loop” webkit-playsinline>
<source src=“rtmp://10.14.221.17:1935/rtmplive/home” type=‘rtmp/flv’>
</video>
<script src=“http://vjs.zencdn.net/5.8.8/video.js”></script>
<script>
videojs.options.flash.swf = ‘video.swf’;
videojs(‘example_video_1′).ready(function() {
this.play();
});
</script>
3. 視頻流協議HLS與RTMP對比
目前直播展示形式,通常以YY直播、映客直播這種頁面居多,可以看到其結構可以分成三層:
① 背景視頻層
② 關注、評論模塊
③ 點贊動畫
而現行H5類似直播頁面,實現技術難點不大,其可以通過實現方式分為:
① 底部視頻背景使用video視頻標簽實現播放
② 關注、評論模塊利用 WebScoket 來實時發送和接收新的消息通過DOM 和 CSS3 實現
③ 點贊利用 CSS3 動畫
了解完直播形式之后,接下來整體了解直播流程。
相關學習資料推薦,點擊下方鏈接免費報名,先碼住不迷路~】
音視頻免費學習地址:FFmpeg/WebRTC/RTMP/NDK/Android音視頻流媒體高級開發
【免費分享】音視頻學習資料包、大廠面試題、技術視頻和學習路線圖,資料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點擊788280672加群免費領取~
直播整體流程大致可分為:
視頻采集端:可以是電腦上的音視頻輸入設備、或手機端的攝像頭、或麥克風,目前以移動端手機視頻為主。
直播流視頻服務端:一臺Nginx服務器,采集視頻錄制端傳輸的視頻流(H264/ACC編碼),由服務器端進行解析編碼,推送RTMP/HLS格式視頻流至視頻播放端。
視頻播放端:可以是電腦上的播放器(QuickTime Player、VLC),手機端的native播放器,還有就是 H5 的video標簽等,目前還是以手機端的native播放器為主。
(web前端學習交流群:328058344 禁止閑聊,非喜勿進!)
對于H5視頻錄制,可以使用強大的 webRTC (Web Real-Time Communication)是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,缺點是只在 PC 的 Chrome 上支持較好,移動端支持不太理想。
使用 webRTC 錄制視頻基本流程
① 調用 window.navigator.webkitGetUserMedia()
獲取用戶的PC攝像頭視頻數據。
② 將獲取到視頻流數據轉換成 window.webkitRTCPeerConnection
(一種視頻流數據格式)。
③ 利用 WebScoket
將視頻流數據傳輸到服務端。
注意:
雖然Google一直在推WebRTC,目前已有不少成型的產品出現,但是大部分移動端的瀏覽器還不支持 webRTC(最新iOS 10.0也不支持),所以真正的視頻錄制還是要靠客戶端(iOS,Android)來實現,效果會好一些。
WebRTC支持度
WebRTC支持度
iOS原生應用調用攝像頭錄制視頻流程
① 音視頻的采集,利用AVCaptureSession和AVCaptureDevice可以采集到原始的音視頻數據流。
② 對視頻進行H264編碼,對音頻進行AAC編碼,在iOS中分別有已經封裝好的編碼庫(x264編碼、faac編碼、ffmpeg編碼)來實現對音視頻的編碼。
③ 對編碼后的音、視頻數據進行組裝封包。
④ 建立RTMP連接并上推到服務端。
安裝nginx、nginx-rtmp-module
① 先clone nginx項目到本地:
brew tap homebrew/nginx
② 執行安裝nginx-rtmp-module
brew install nginx-full –with-rtmp-module
2. nginx.conf配置文件,配置RTMP、HLS
查找到nginx.conf配置文件(路徑/usr/local/etc/nginx/nginx.conf),配置RTMP、HLS。
① 在http節點之前添加 rtmp 的配置內容:
② 在http中添加 hls 的配置
3. 重啟nginx服務
重啟nginx服務,瀏覽器中輸入 http://localhost:8080,是否出現歡迎界面確定nginx重啟成功。
nginx -s reload
當服務器端接收到采集視頻錄制端傳輸過來的視頻流時,需要對其進行解析編碼,推送RTMP/HLS格式視頻流至視頻播放端。通常使用的常見編碼庫方案,如x264編碼、faac編碼、ffmpeg編碼等。鑒于 FFmpeg 工具集合了多種音頻、視頻格式編碼,我們可以優先選用FFmpeg進行轉換格式、編碼推流。
1.安裝 FFmpeg 工具
brew install ffmpeg
2.推流MP4文件
視頻文件地址:/Users/gao/Desktop/video/test.mp4
推流拉流地址:rtmp://localhost:1935/rtmplive/home,rtmp://localhost:1935/rtmplive/home
//RTMP 協議流
ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -acodec aac -f flv rtmp://10.14.221.17:1935/rtmplive/home
//HLS 協議流
ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://10.14.221.17:1935/hls/test
注意:
當我們進行推流之后,可以安裝VLC、ffplay(支持rtmp協議的視頻播放器)本地拉流進行演示
3.FFmpeg推流命令
① 視頻文件進行直播
ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://192.168.1.101:1935/hls/test
ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://10.14.221.17:1935/hls/test
② 推流攝像頭+桌面+麥克風錄制進行直播
ffmpeg -f avfoundation -framerate 30 -i “1:0″ \-f avfoundation -framerate 30 -video_size 640x480 -i “0” \-c:v libx264 -preset ultrafast \-filter_complex ‘overlay=main_w-overlay_w-10:main_h-overlay_h-10′ -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://192.168.1.101:1935/hls/test
更多命令,請參考:
FFmpeg處理RTMP流媒體的命令大全
FFmpeg常用推流命令
移動端iOS和 Android 都天然支持HLS協議,做好視頻采集端、視頻流推流服務之后,便可以直接在H5頁面配置 video 標簽播放直播視頻。
<video controls preload=“auto” autoplay=“autoplay” loop=“loop” webkit-playsinline>
<source src=“http://10.14.221.8/hls/test.m3u8″ type=“application/vnd.apple.mpegurl” />
<p class=“warning”>Your browser does not support HTML5 video.</p>
</video>
本文從視頻采集上傳,服務器處理視頻推流,以及H5頁面播放直播視頻一整套流程,具體闡述了直播實現原理,實現過程中會遇到很多性能優化問題。
① H5 HLS 限制必須是H264+AAC編碼。
② H5 HLS 播放卡頓問題,server 端可以做好分片策略,將 ts 文件放在 CDN 上,前端可盡量做到 DNS 緩存等。
③ H5 直播為了達到更好的實時互動,也可以采用RTMP協議,通過video.js 實現播放。
原文 https://zhuanlan.zhihu.com/p/146323842
web技術將成為移動設備上的開發平臺,只是目前該技術可能尚未成熟。基于HTML5的開發方式有兩種:一種是混合式開發,一種是移動網頁應用。怎么在移動互聯網中應用html5,現在 渥瑞達HTML5培訓老師在這里提醒大家幾點:
1. 目前主流的都是混合開發,所以對團隊、技術人員的要求比較高,需要掌握多種不同的技術(JAVA、Obejective-c、HTML5、JAVASCRIPT、CSS/CSS3),這種混合的開發模式。
2. 混合應用是一種需要下載,但有部分或者所有用戶界面植入了瀏覽器元素的應用程序。對用戶來說,混合應用與原生應用并無二致——它們都需要通過應用商店渠道下載,都可以保存的在手機,運行方式與原生應用并無差別。
3. 混合應用的HTML頁面可通過網絡服務器傳送,但這一點并非必備條件。如果要提高運行性能,混合應用還可以植入一個包含其所需的網頁資源的副本,以便用戶快速訪問內容,而不必等待網絡服務器將內容傳送過來。
4. 混合應用必須通過應用商店下載。
支持混合開發的javascript框架:JavaScript工具包
移動網頁應用
1. 必須連網
2. 在瀏覽器運行,用戶不需要下載安裝就可以。
3. 需要等待網絡服務器將內容傳送到手機才可以
4.目前還不能訪問攝像頭、麥克風、通訊錄等手機功能。
這是渥瑞達老師為大家總結的應用問題,相信大家對于如何在移動互聯網應用html5已經有了初步的了解了吧。想要了解更多html5在移動互聯網的應用問題可以關注渥瑞達培訓課程。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。