首頁  >  文章  >  web前端  >  H5做視訊直播

H5做視訊直播

大家讲道理
大家讲道理原創
2017-05-28 10:56:444917瀏覽

為了跟上潮流,本文將向大家介紹一下影片直播中的基本流程和主要的技術點,包括但不限於前端技術。

1 H5到底能不能做影片直播?

當然可以, H5火了這麼久,涵蓋了各方面的技術。

對於視訊錄製,可以使用強大的webRTC(Web Real-Time Communication)是一個支援網頁瀏覽器進行即時語音對話或視訊對話的技術,缺點是只在PC的chrome上支援較好,行動端支援不太理想。

 

對於視訊播放,可以使用HLS(HTTP Live Streaming)協議播放直播串流,iOS和Android都自然支援這種協議,配置簡單,直接使用video標籤即可。

webRTC相容性:

video標籤播放hls協定影片:


Your browser


1

#2

3

4


<video controls autoplay>  

    #<source src="http://10.66.69.77:8080/hls/mystream.m3u8" type="application/ vnd.apple.mpegurl" />  

    

<pclass="warning"

>

 ###does### ###not# ##### ###support### ######HTML5####### ###video###.###<###/###p###> ;###  ###################################################################################################################### ########################################################### <###/###video###>###########################


2 到底什麼是HLS協定?

簡單講就是把整個流分成一個個小的,基於HTTP的文件來下載,每次只下載一些,前面提到了用於H5播放直播視頻時引入的一個.m3u8的文件,這個文件就是基於HLS協議,存放視訊流元資料的文件。

每一個.m3u8文件,分別對應若干個ts文件,這些ts文件才是真正存放視頻的數據,m3u8文件只是存放了一些ts文件的配置信息和相關路徑,當視頻播放時, .m3u8是動態改變的,video標籤會解析這個文件,並找到對應的ts文件來播放,所以一般為了加快速度,.m3u8放在web伺服器上,ts文件放在cdn上。

.m3u8文件,其實就是以UTF-8編碼的m3u文件,這個文件本身不能播放,只是存放了播放訊息的文本文件:



#1

2

##3

#4

5

6

7


#EXTM3U                     m3u檔案頭

1 ##MEDIA-SEQUENCE       第一個TS分片的序號

##EXT

-X##-TARGETDURATION#EXT-X-TARGETDURATION        每個分片TS的最大的長度

#EXT -X-ALLOW-CACHE          是否允許

########################################################1 #######################################EXT###-###X###- ######END######LIST###              ###m3u8文件結束符########################## ########EXTINF###              關於################################mystream###-###12.ts####### #################


ts檔案:

HLS的請求流程是:
1 http請求m3u8的url。
2 服務端回傳一個m3u8的播放列表,這個播放列表是即時更新的,一般一次給出5段資料的url。
3 客戶端解析m3u8的播放列表,再依序請求每一段的url,取得ts資料流。

簡單流程:

3 HLS直播延時

我們知道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

4 視訊直播的整個流程是什麼?

當視訊直播可大致分為:

1 錄影端:一般是電腦上的音訊輸入裝置或手機端的攝影機或麥克風,目前以移動端的手機影片為主。

2 影片播放端:可以是電腦上的播放器,手機端的native播放器,還有就是h5的video標籤等,目前還是已手機端的native播放器為主。

3 視訊伺服器端:一般是一台nginx伺服器,用來接受錄影端提供的視訊來源,同時提供給視訊播放端串流服務。

簡單流程:

 

 

5 怎麼進行音訊視訊擷取?

當先明確幾個概念:

視訊編碼:所謂視訊編碼就是指透過特定的壓縮技術,將某個視訊格式的檔案轉換成另一種視頻格式文件的方式,我們使用的iphone錄製的視頻,必須要經過編碼,上傳,解碼,才能真正的在用戶端的播放器裡播放。

編解碼標準:視訊串流傳輸中最重要的編解碼標準有國際電聯的H.261、H.263、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

關於如果想為影片增加一些特殊效果,例如增加濾鏡等,一般在編碼前給使用濾鏡庫,但是這樣也會造成一些耗時,導致上傳視訊資料有一定延時。

簡單流程:

6 前面提到的ffmpeg是什麼?

和之前的x264一樣,ffmpeg其實也是一套編碼庫,類似的還有Xvid,Xvid是基於MPEG4協定的編解碼器,x264是基於H.264協定的編碼器, ffmpeg集合了各種音頻,視頻編解碼協議,透過設定參數可以完成基於MPEG4,H.264等協議的編解碼,demo這裡使用的是x264編碼庫。

7 什麼是RTMP?

Real Time Messaging Protocol(簡稱 RTMP)是 Macromedia 開發的一套視訊直播協議,現在屬於 Adob​​​​e。和HLS一樣都可以應用於視訊直播,差別在於RTMP基於flash無法在ios的瀏覽器裡播放,但是即時性比HLS好。所以一般使用這種協定來上傳視訊串流,也就是視訊串流推送到伺服器。

這裡列舉hls和rtmp對比:

#8 推流

##簡所謂推流,就是將我們已經編碼好的音視頻資料發送到視訊串流伺服器中,一般常用的是使用rtmp推流,可以使用第三方函式庫

librtmp-iOS進行推流,librtmp封裝了一些核心的api供用戶調用,如果覺得麻煩,可以使用現成的ios視訊推流sdk,也是基於rtmp的,https://github.com/runner365/LiveVideoCoreSDK

# 9 推流伺服器搭建

簡簡單的推流伺服器搭建,由於我們上傳的視訊串流都是基於rtmp協定的,所以伺服器也必須要支援rtmp才行,大概需要以下幾個步驟:

1 安裝一台nginx伺服器。

2 安裝nginx的rtmp擴展,目前使用比較多的是https://github.com/arut/nginx-rtmp-module

#3 設定nginx的conf檔:



4 重啟nginx,將rtmp的推流位址寫為rtmp://ip:1935/hls/mystream,其中hls_path表示產生的.m3u8和ts檔案所存放的位址,hls_fragment表示切片時長,mysteam表示一個實例,即將要產生的檔案名稱可以先自己隨便設定一個。更多配置可以參考:https://github.com/arut/nginx-rtmp-module/wiki/

根據上述步驟基本上已經實現了一個支援rtmp的視訊伺服器了。

10 在HTML5頁面進行直播影片?

簡單來說,直接使用video標籤即可播放hls協定的直播影片:



1

2

3

4

#5

6

7

8

9

10

#11

12

13

14

15

16

17


## rtmp

 {  

  

##server {  

#  

############################### ######        ###listen###### ###1935###;###  ####監聽的端口################ #################  #############        ###chunk###_size###### ###4000### ;###  #################################        #############       #############   #####

        applicationhls {  ##  

             #;  

#            因hls 

            hls_path / ##local/var/www/hls;              

hls

_ ## 5s;  ##        

##        

}  

    

}  

##}

  


1

2

3

4


#<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等。

11 坑點總結

簡根據上述步驟,筆者寫了一個demo,從實現ios視訊錄製,採集,上傳,nginx伺服器下發直播串流, h5頁面播放直播影片者一整套流程,總結出以下幾點比較坑的地方:

1 在使用AVCaptureSession進行擷取影片時,需要實作AVCaptureVideoDataOutputSampleBufferDelegate協議,同時在- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection捕獲到視訊流,要注意的是didOutputSampleBuffer這個方法不是didDropSampleBuffer方法,後者只會觸發半天才發現方法呼叫錯了。

2 使用rtmp推流時,rmtp位址要以rtmp://開頭,ip位址要寫實際ip位址,不要寫成localhost,同時要加上連接埠號,因為手機端上傳時是無法識別localhost的。

這裡後續會補充上一些坑點,有的需要貼程式碼,這裡先列這麼多。

12 業界支援

目前,騰訊雲,百度雲,阿里雲都已經有了基於視訊直播的解決方案,從視訊錄製到視訊播放,推流,都有一系列的sdk可以使用,缺點就是需要收費,如果可以的話,自己實現一套也並不是難事哈。

 

demo網址:https://github.com/lvming6816077/LMVideoTest/


以上是H5做視訊直播的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn