章來源:http://geek.csdn.net/news/detail/95188php
分享內容簡介:
目前視頻直播,尤爲是移動端的視頻直播已經火到不行了,基本上各大互聯網公司都有了本身的直播產品,因此對於直播的一些基本知識和主要技術點也要有所瞭解,本次分享就向你們介紹一下其中的奧祕。html
內容大致框架:
1. 怎樣利用 HTML5 來播放直播視頻
2. 怎樣錄製直播視頻
3. 怎樣實時上傳直播視頻
4. 直播中的用戶交互前端
分享人介紹:html5
呂鳴 目前在騰訊SNG擔任手Q的web前端開發工做
博客:http://www.nihaoshijie.com.cn/android
下面是本期分享內容整理ios
Hello, 你們好,我是呂鳴,目前是在騰訊 SNG 的即通應用部負責手Q的興趣部落 Web 前端開發工做。nginx
針對目前比較火的視頻直播,我作了一些研究和探索,同時咱們的項目將會用到直播爲此打下技術基礎,下面就向你們分享一下直播的整個流程和一些技術點。git
你們首先來看下面這張圖:github
能夠看到,直播從 PC 到一直髮展到移動端,愈來愈多的直播類 App 上線,同時移動直播進入了史無前例的爆發階段,可是對於大多數移動直播來講,仍是要以 Native 客戶端實現爲主,可是 HTML5 在移動直播端也承載着不可替代的做用,例如 HTML5 有着傳播快,易發佈的優點,同時最爲關鍵的時 HTML5 一樣能夠播放直播視頻。web
你們能夠看下面這張大概的實現圖
完整的直播能夠分爲如下幾塊:
video
標籤等,目前仍是已手機端的 Native 播放器爲主。你們能夠看下大體的結構圖:
對於HTML5視頻錄製,可使用強大的 webRTC (Web Real-Time Communication)是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,缺點是隻在 PC 的 Chrome 上支持較好,移動端支持不太理想。
使用 webRTC 錄製視頻基本流程是:
window.navigator.webkitGetUserMedia()
獲取用戶的PC攝像頭視頻數據。window.webkitRTCPeerConnection
(一種視頻流數據格式)。因爲許多方法都要加上瀏覽器前綴,因此不少移動端的瀏覽器還不支持 webRTC,因此真正的視頻錄製仍是要靠客戶端(iOS,Android)來實現,效果會好一些。
對於視頻播放,可使用 HLS(HTTP Live Streaming)協議播放直播流,iOS和 Android 都自然支持這種協議,配置簡單,直接使用 video
標籤便可。
下面是簡單的代碼使用 video
播放直播視頻:
簡單講就是把整個流分紅一個個小的,基於 HTTP 的文件來下載,每次只下載一些,前面提到了用於 HTML5 播放直播視頻時引入的一個 .m3u8 的文件,這個文件就是基於 HLS 協議,存放視頻流元數據的文件。
每個 .m3u8 文件,分別對應若干個 ts 文件,這些 ts 文件纔是真正存放視頻的數據,m3u8 文件只是存放了一些 ts 文件的配置信息和相關路徑,當視頻播放時,.m3u8 是動態改變的,video
標籤會解析這個文件,並找到對應的 ts 文件來播放,因此通常爲了加快速度,.m3u8 放在 Web 服務器上,ts 文件放在 CDN 上。
.m3u8 文件,其實就是以 UTF-8 編碼的 m3u 文件,這個文件自己不能播放,只是存放了播放信息的文本文件。
打開以後就是這個樣子:
下面這個是 ts 文件,就是存放視頻的文件:
大概是這個流程:
咱們知道 hls 協議是將直播流分紅一段一段的小段視頻去下載播放的,因此假設列表裏面的包含5個 ts 文件,每一個 TS 文件包含5秒的視頻內容,那麼總體的延遲就是25秒。由於當你看到這些視頻時,主播已經將視頻錄製好上傳上去了,因此時這樣產生的延遲。固然能夠縮短列表的長度和單個 ts 文件的大小來下降延遲,極致來講能夠縮減列表長度爲1,而且 ts 的時長爲1s,可是這樣會形成請求次數增長,增大服務器壓力,當網速慢時回形成更多的緩衝,因此蘋果官方推薦的 ts 時長時10s,因此這樣就會大改有30s的延遲。因此服務器接收流,轉碼,保存,切塊,再分發給客戶端,這裏就延時的根本緣由。
更多關於延遲的問題能夠參考蘋果官方地址:
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html
可是 HTML5 直播視頻卻有一些不可替代的優點:
關於音視頻採集錄製,首先明確下面幾個概念:
利用 iOS 上的攝像頭,進行音視頻的數據採集,主要分爲如下幾個步驟:
下面是具體的採集音視頻數據的流程:
Real Time Messaging Protocol(簡稱 RTMP)是 Macromedia 開發的一套視頻直播協議,如今屬於 Adobe。和 HLS 同樣均可以應用於視頻直播,區別是 RTMP 基於 flash 沒法在 iOS 的瀏覽器裏播放,可是實時性比 HLS 要好。因此通常使用這種協議來上傳視頻流,也就是視頻流推送到服務器。
下面是 HLS 和 RTMP 的對比:
所謂推流,就是將咱們已經編碼好的音視頻數據發往視頻流服務器中,在 iOS 代碼裏面通常經常使用的是使用 RTMP 推流,可使用第三方庫 librtmp-iOS 進行推流,librtmp 封裝了一些核心的 API 供使用者調用。例如推流 API 等等,配置服務器地址,便可將轉碼後的視頻流推往服務器。
那麼如何搭建一個推流服務器呢?
簡單的推流服務器搭建,因爲咱們上傳的視頻流都是基於 RTMP 協議的,因此服務器也必需要支持 RTMP 才行,大概須要如下幾個步驟:
更多配置能夠參考:https://github.com/arut/nginx-rtmp-module/wiki/
下面是 nginx 的配置文件
對於直播中的用戶交互大體能夠分爲:
對於送禮物,在 HTML5 端能夠利用 DOM 和 CSS3 實現送禮物邏輯和一些特殊的禮物動畫,實現技術難點不大。
對於彈幕來講,要稍微複雜一些,可能須要關注如下幾點:
目前較爲成熟的直播產品,大體都是以 Server 端和 HTML5 和 Native(android,ios)搭配實現直播:
基本是下圖這個套路:
因此 HTML5 在整個直播中,仍是有着重要的地位的!
最後,根據本次分享的內容,我這邊實現了一個 iOS 端錄製,推流,NGINX 接收流,同時分發的 HLS 直播流的一整套 Demo,感興趣的同窗能夠看下面這個連接:
https://github.com/lvming6816077/LMVideoTest
好了,本次分享先到這裏了,謝謝你們~
Q1: Demo 包含 iOS 端的 RTMP 播放不?
答:Demo 裏面沒有 RTMP 的播放,Demo 主要是提供錄製,推流的。
Q2: 對於 HTML5 HLS 播放 卡頓問題,前端與 server 端,有什麼配置上的優化嗎?
答:server 端要作好分片策略,同時要將 ts 文件放在 CDN 上,前端這邊能夠儘可能作到 DNS 緩存等,因爲HTML5是使用的 video 標籤,因此要修改 video 的播放優化,仍是不那麼容易。
Q3: 在手機推流時的碼率是根據怎樣的策略作選擇的?不一樣機型和網絡下如何保持流暢?
答:能夠提供不一樣的視頻碼率來供用戶選擇,例如網速差的能夠選擇較爲低清晰度的碼率,網絡好的用戶能夠選擇更加清晰的碼率,同時作好視頻播放端的容錯和異常處理等等。
Q4: RTMP 比起 HTTP 他的優點主要是幾種在哪裏?
答:RTMP 是基於 TCP 的保持的是長鏈接,而 HTTP 是一次性的,每次都要三次握手,因此對於直播來講仍是 RTMP 好一些
Q5: 據我所知 nginx rtmp-module 好像性能不是很高…..爲何會採用這個來做爲後端服務?
答:這裏只是 Demo 用了這個 nginx rtmp-module,其實也可已選擇 SRS(simple-rtmp-server)都是能夠的哈
Q6: 移動端這邊怎麼進行編碼轉碼?用 ffmpeg 編譯時很麻煩
答:關於 iOS 這邊,其實不用關心轉碼問題,由於已經有了不少開源的庫提供給咱們了例如:
x264 編碼:https://github.com/kewlbear/x264-ios
faac 編碼:https://github.com/fflydev/faac-ios-build
Q7: 您介紹的都是 Native 播放和還有 HTML5 的 video 標籤播放, iOS 端有沒有考慮過整個用原生的 OC 或者 Swift 實現?
答:關於播放端,其實真正體驗好的仍是要用 native 來實現的,並且 native 實現能夠用 RTMP 來播放直播,延遲會好不少,HTML5 來播直播主要是考慮到易傳播性好。
Q8: 在用戶很是多的狀況下,或者網絡慢的狀況下,有什麼策略能夠保證質量?
答:能夠提供不一樣的視頻碼率來供用戶選擇,例如網速差的能夠選擇較爲低清晰度的碼率,網絡好的用戶能夠選擇更加清晰的碼率,同時作好視頻播放端的容錯和異常處理等等。
Q9: 請問直播這塊的測試中關注的幾個指標是什麼,有什麼比較好的測試方法呢?
答:主要就是:
1. 首次打開的白屏時間
2. 直播中的卡頓和緩衝
3. 直播的延時
Q10: 您提供的 Demo 爲何不是 HTML5 的呢 iOS 推流和 nginx 服務器都有,能不能提供一個前面第二張葉子美女直播那個頁面的 Demo?
答:這個 Demo 你下載下拉運行的話,根據配置就可直接本身實現一個利用 HTML5 直播的頁面,很簡單,就像使用 video 標籤同樣,其餘的樣式你能夠本身定製的。
Q11: HLS 的延時有沒有比較好的方法解決?
答:HLS 確實是會有延遲,相對比較優的策略是調整好分片策略,在保證性能的狀況下,和延遲達到平衡。
Q12: 若是加入視頻電話功能,上面的結構須要做什麼改變?視頻電話的目的大概是:直播能夠選擇某一觀衆或者多個觀衆視頻對話
答:視頻電話,也就是說做爲視頻錄製端的同時也做爲視頻播放端,因此實現實時電話簡單就是:我在直播的同時觀看別人的直播視頻,別人在直播的同時觀看個人直播視頻,能夠這樣理解,上面的結構複製一份對調便可。
Q13: 如何實現濾鏡功能?
答:通常是在視頻錄製以後,在轉碼前給視頻數據增長濾鏡功能,在 iOS 裏可使用一些濾鏡庫等等實現濾鏡功能
Q14: 在 App 端若是不利用 HTML5 能實現直播嗎?
答:能夠啊,app 有更加豐富的播放接口,和開源播放器能夠實現直播的。
Q15: 既然 HLS 有較高的延遲 爲何蘋果推薦的的方式倒是 HLS?
答:並非說蘋果主要推薦使用 HLS,對於 HTML5 來講目前只有這一種比較好的方式來播放直播視頻,因此仍是很期待蘋果能對延遲問題作一些改進的。
Q16: 同濾鏡問題,音頻變聲是如何實現的?
答:一樣是能夠在對音頻轉碼前操做。
Q17: 若是針對網絡較差的觀看用戶,是須要直播推流到服務器後作多份不一樣分辨率的拷貝,以適應不一樣網絡的用戶觀看?若是是這樣的話,對延遲會不會影響很大? 畢竟編解碼也是須要時間的.
答:這個其實自己就應該作的,對於網絡差的用戶,徹底能夠提供給他們較低碼率的直播流來減小卡頓問題,延遲問題的話仍是要根據具體使用哪一種協議來定。
Q18: 推流目前大部分都是第三方在作,難度點在哪?而後目前業內比較成熟的主要哪些?
答:難點主要是服務器端的性能壓力和分發直播流的效率,業界都已經有了較成熟的方案,例如騰訊雲的直播。
騰訊 Bugly是一款專爲移動開發者打造的質量監控工具,幫助開發者快速,便捷的定位線上應用崩潰的狀況以及解決方案。智能合併功能幫助開發同窗把天天上報的數千條Crash 根據根因合併分類,每日日報會列出影響用戶數最多的崩潰,精準定位功能幫助開發同窗定位到出問題的代碼行,實時上報能夠在發佈後快速的瞭解應用的質量狀況,適配最新的 iOS、Android 官方操做系統。
下面是H5相關掃盲方面的知識:
文章來源:https://www.nihaoshijie.com.cn/index.php/archives/615
視頻直播這麼火,再不學就out了。
爲了緊跟潮流,本文將向你們介紹一下視頻直播中的基本流程和主要的技術點,包括但不限於前端技術。
固然能夠, H5火了這麼久,涵蓋了各個方面的技術。
對於視頻錄製,可使用強大的webRTC(Web Real-Time Communication)是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,缺點是隻在PC的chrome上支持較好,移動端支持不太理想。
對於視頻播放,可使用HLS(HTTP Live Streaming)協議播放直播流,ios和android都自然支持這種協議,配置簡單,直接使用video標籤便可。
webRTC兼容性:
video標籤播放hls協議視頻:
<video controls autoplay> <source src="http://10.66.69.77:8080/hls/mystream.m3u8" type="application/vnd.apple.mpegurl" /> <p class="warning">Your browser does not support HTML5 video.</p> </video>
當簡單講就是把整個流分紅一個個小的基於HTTP的文件來下載,每次只下載一些,前面提到了用於H5播放直播視頻時引入的一個.m3u8的文件,這個文件就是基於HLS協議,存放視頻流元數據的文件。
每個.m3u8文件,分別對應若干個ts文件,這些ts文件纔是真正存放視頻的數據,m3u8文件只是存放了一些ts文件的配置信息和相關路徑,當視頻播放時,.m3u8是動態改變的,video標籤會解析這個文件,並找到對應的ts文件來播放,因此通常爲了加快速度,.m3u8放在web服務器上,ts文件放在cdn上。
.m3u8文件,其實就是以UTF-8編碼的m3u文件,這個文件自己不能播放,只是存放了播放信息的文本文件:
#EXTM3U m3u文件頭 #EXT-X-MEDIA-SEQUENCE 第一個TS分片的序列號 #EXT-X-TARGETDURATION 每一個分片TS的最大的時長 #EXT-X-ALLOW-CACHE 是否容許cache #EXT-X-ENDLIST m3u8文件結束符 #EXTINF 指定每一個媒體段(ts)的持續時間(秒),僅對其後面的URI有效 mystream-12.ts
ts文件:
HLS的請求流程是:
1 http請求m3u8的url
2 服務端返回一個m3u8的播放列表,這個播放列表是實時跟新的,通常一次給出3段數據的url
3 客戶端解析m3u8的播放列表,再按序請求每一段的url,獲取ts數據流
簡單流程:
當咱們知道hls協議是將直播流分紅一段一段的小段視頻去下載播放的,因此假設列表裏面的包含5個TS文件,每一個TS文件包含5秒的視頻內容,那麼總體的延遲就是25秒。由於當你看到這些視頻時,主播已經將視頻錄製好上傳上去了,因此時這樣產生的延遲。固然能夠縮短列表的長度和單個TS文件的大小來下降延遲,極致來講能夠縮減列表長度爲1,而且TS的時長爲1s,可是這樣會形成請求次數增長,增大服務器壓力,當網速慢時回形成更多的緩衝,因此蘋果官方推薦的ts時長時10s,因此這樣就會大改有30s的延遲。參考資料:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html
當視頻直播可大體分爲:
1 視頻錄製端:通常是電腦上的音視頻輸入設備或者手機端的攝像頭或者麥克風,目前已移動端的手機視頻爲主。
2 視頻播放端:能夠是電腦上的播放器,手機端的native播放器,還有就是h5的video標籤等,目前仍是已手機端的native播放器爲主。
3 視頻服務器端:通常是一臺nginx服務器,用來接受視頻錄製端提供的視頻源,同時提供給視頻播放端流服務。
簡單流程:
當首先明確幾個概念:
視頻編碼:所謂視頻編碼就是指經過特定的壓縮技術,將某個視頻格式的文件轉換成另外一種視頻格式文件的方式,咱們使用的iphone錄製的視頻,必需要通過編碼,上傳,解碼,才能真正的在用戶端的播放器裏播放。
編解碼標準:視頻流傳輸中最爲重要的編解碼標準有國際電聯的H.26一、H.26三、H.264,其中HLS協議支持H.264格式的編碼。
音頻編碼:同視頻編碼相似,將原始的音頻流按照必定的標準進行編碼,上傳,解碼,同時在播放器裏播放,固然音頻也有許多編碼標準,例如PCM編碼,WMA編碼,AAC編碼等等,這裏咱們HLS協議支持的音頻編碼方式是AAC編碼。
下面將利用ios上的攝像頭,進行音視頻的數據採集,主要分爲如下幾個步驟:
1 音視頻的採集,ios中,利用AVCaptureSession和AVCaptureDevice能夠採集到原始的音視頻數據流。
2 對視頻進行H264編碼,對音頻進行AAC編碼,在ios中分別有已經封裝好的編碼庫來實現對音視頻的編碼。
3 對編碼後的音、視頻數據進行組裝封包;
4 創建RTMP鏈接並上推到服務端。
ps:因爲編碼庫大多使用c語言編寫,須要本身使用時編譯,對於ios,可使用已經編譯好的編碼庫。
x264編碼:https://github.com/kewlbear/x264-ios
faac編碼:https://github.com/fflydev/faac-ios-build
ffmpeg編碼:https://github.com/kewlbear/FFmpeg-iOS-build-script
關於若是想給視頻增長一些特殊效果,例如增長濾鏡等,通常在編碼前給使用濾鏡庫,可是這樣也會形成一些耗時,致使上傳視頻數據有必定延時。
簡單流程:
和以前的x264同樣,ffmpeg其實也是一套編碼庫,相似的還有Xvid,Xvid是基於MPEG4協議的編解碼器,x264是基於H.264協議的編碼器,ffmpeg集合了各類音頻,視頻編解碼協議,經過設置參數能夠完成基於MPEG4,H.264等協議的編解碼,demo這裏使用的是x264編碼庫。
Real Time Messaging Protocol(簡稱 RTMP)是 Macromedia 開發的一套視頻直播協議,如今屬於 Adobe。和HLS同樣均可以應用於視頻直播,區別是RTMP基於flash沒法在ios的瀏覽器裏播放,可是實時性比HLS要好。因此通常使用這種協議來上傳視頻流,也就是視頻流推送到服務器。
這裏列舉一下hls和rtmp對比:
簡所謂推流,就是將咱們已經編碼好的音視頻數據發往視頻流服務器中,通常經常使用的是使用rtmp推流,可使用第三方庫librtmp-iOS進行推流,librtmp封裝了一些核心的api供使用者調用,若是以爲麻煩,可使用現成的ios視頻推流sdk,也是基於rtmp的,https://github.com/runner365/LiveVideoCoreSDK
簡簡單的推流服務器搭建,因爲咱們上傳的視頻流都是基於rtmp協議的,因此服務器也必需要支持rtmp才行,大概須要如下幾個步驟:
1 安裝一臺nginx服務器。
2 安裝nginx的rtmp擴展,目前使用比較多的是https://github.com/arut/nginx-rtmp-module
3 配置nginx的conf文件:
rtmp { server { listen 1935; #監聽的端口 chunk_size 4000; application hls { #rtmp推流請求路徑 live on; hls on; hls_path /usr/local/var/www/hls; hls_fragment 5s; } } }
4 重啓nginx,將rtmp的推流地址寫爲rtmp://ip:1935/hls/mystream,其中hls_path表示生成的.m3u8和ts文件所存放的地址,hls_fragment表示切片時長,mysteam表示一個實例,即未來要生成的文件名能夠先本身隨便設置一個。更多配置能夠參考:https://github.com/arut/nginx-rtmp-module/wiki/
根據以上步驟基本上已經實現了一個支持rtmp的視頻服務器了。
簡單來講,直接使用video標籤便可播放hls協議的直播視頻:
<video autoplay webkit-playsinline> <source src="http://10.66.69.77:8080/hls/mystream.m3u8" type="application/vnd.apple.mpegurl" /> <p class="warning">Your browser does not support HTML5 video.</p> </video>
須要注意的是,給video標籤增長webkit-playsinline屬性,這個屬性是爲了讓video視頻在ios的uiwebview裏面能夠不全屏播放,默認ios會全屏播放視頻,須要給uiwebview設置allowsInlineMediaPlayback=YES。業界比較成熟的videojs,能夠根據不一樣平臺選擇不一樣的策略,例如ios使用video標籤,pc使用flash等。
簡根據以上步驟,筆者寫了一個demo,從實現ios視頻錄製,採集,上傳,nginx服務器下發直播流,h5頁面播放直播視頻者一整套流程,總結出如下幾點比較坑的地方:
1 在使用AVCaptureSession進行採集視頻時,須要實現AVCaptureVideoDataOutputSampleBufferDelegate協議,同時在- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection捕獲到視頻流,要注意的是didOutputSampleBuffer這個方法不是didDropSampleBuffer方法,後者只會觸發一次,當時開始寫的是didDropSampleBuffer方法,差了半天才發現方法調用錯了。
2 在使用rtmp推流時,rmtp地址要以rtmp://開頭,ip地址要寫實際ip地址,不要寫成localhost,同時要加上端口號,由於手機端上傳時是沒法識別localhost的。
這裏後續會補充上一些坑點,有的須要貼代碼,這裏先列這麼多。
目前,騰訊雲,百度雲,阿里雲都已經有了基於視頻直播的解決方案,從視頻錄製到視頻播放,推流,都有一系列的sdk可使用,缺點就是須要收費,若是能夠的話,本身實現一套也並非難事哈。
demo地址:https://github.com/lvming6816077/LMVideoTest/
更多直播相關知識:http://lib.csdn.net/base/liveplay