1. 程式人生 > >PC瀏覽器播放m3u8

PC瀏覽器播放m3u8

 

 HLS(HTTP Live Streaming)是蘋果公司針對iPhone、iPod、iTouch和iPad等移動裝置而開發的基於HTTP協議的流媒體解決方案。在 HLS 技術中 Web 伺服器向客戶端提供接近實時的音視訊流。但在使用的過程中是使用的標準的 HTTP 協議,所以這時,只要使用 HLS 的技術,就能在普通的 HTTP 的應用上直接提供點播和直播。在App Store中的視訊相關的應用,基本都是應用的此種技術。該技術基本原理是將視訊檔案或視訊流切分成小片(ts)並建立索引檔案(m3u8)。支援的視訊流編碼為H.264,音訊流編碼為AAC。

 

Apple的動態位元速率自適應技術。主要用於PC和Apple終端的音視訊服務。包括一個m3u(8)的索引檔案,TS媒體分片檔案和key加密串檔案。
常用的流媒體協議主要有 HTTP 漸進下載和基於 RTSP/RTP 的實時流媒體協議,這二種基本是完全不同的東西,目前比較方便又好用的是用 HTTP 漸進下載方法。在這個中 apple 公司的 HTTP Live Streaming 是這個方面的代表。它最初是蘋果公司針對iPhone、iPod、iTouch和iPad等移動裝置而開發的流.現在見到在桌面也有很多應用了,HTML5 是直接支援這個。
但是HLS協議的小切片方式會生成大量的檔案,儲存或處理這些檔案會造成大量資源浪費。如果要實現數天的時移,索引量將會是個鉅額數字,並明顯影響請求速度。因此,HLS協議對儲存I/O要求相當苛刻。對此,也有公司提出了非常好的解決方案。
新型點播伺服器系統,獨創了記憶體快取資料實時切片技術,顛覆了這種傳統實現方法,從根本上解決了大量切片的碎片問題,使得單臺伺服器的切片與打包能力不再是瓶頸。其基本原理如下:
不將TS切片檔案存到磁碟,而是存在記憶體當中,這種技術使得伺服器的磁碟上面不再會有“數以噸計”的檔案碎片,極大減少了磁碟的I/O次數,延長了伺服器磁碟的使用壽命,極大提高了伺服器執行的穩定性。同時,由於使用這種技術,使得終端請求資料時直接從伺服器的記憶體中獲取,極大提高了對終端資料請求的反應速度,優化了視訊觀看體驗。

 

簡單歸納起來就是:首先將一個完整視訊分成多個TS視訊檔案,使用者下載m3u8檔案,通過m3u8檔案的索引地址  播放具體的每個小段視訊

 

1.   M3U8檔案概念
M3U8檔案是指UTF-8編碼格式的M3U檔案。M3U檔案是記錄了一個索引純文字檔案,開啟它時播放軟體並不是播放它,而是根據它的索引找到對應的音視訊檔案的網路地址進行線上播放。

 

2.   M3U8檔案舉例
例如使用雲圖TV點播直播節目時,傳送請求:
http://121.199.63.236:7613/m3u8/cckw1/szws.m3u8?from=bab&fun=yes&chk=y&chunk=xax&ppw=yuntutv&auth=yuntutvyuntutvyuntutv&auth=yuntutvyuntutvyuntutv&nwtime=1406515232&sign=033d5483609e6bc87987fc7d2f30a024
返回M3U8檔案,檔案內容如下

 

#EXTM3U
#EXT-X-MEDIA-SEQUENCE:140651513
#EXT-X-TARGETDURATION:10
#EXTINF:8,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651513[140651513].ts
#EXTINF:9,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651514[140651514].ts
#EXTINF:11,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651515[140651515].ts
#EXTINF:10,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651516[140651516].ts
#EXTINF:12,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651517[140651517].ts
#EXTINF:8,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651518[140651518].ts
#EXTINF:12,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651519[140651519].ts
#EXTINF:8,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651520[140651520].ts
#EXTINF:9,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651521[140651521].ts
#EXTINF:13,
http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651522[140651522].ts
然後根據索引的中連結請求下載音視訊並進行播放
3.   M3U檔案標籤及屬性說明
M3U檔案中可以包含多個tag,每個tag的功能和屬性如下:
#EXTM3U
每個M3U檔案第一行必須是這個tag,請標示作用
#EXT-X-MEDIA-SEQUENCE:140651513 
每一個media URI 在 PlayList中只有唯一的序號,相鄰之間序號+1, 一個media URI並不是必須要包含的,如果沒有,預設為0
#EXTINF:
 duration 指定每個媒體段(ts)的持續時間(秒),僅對其後面的URI有效,title是下載資源的url
#EXT-X-TARGETDURATION
指定最大的媒體段時間長(秒)。所以#EXTINF中指定的時間長度必須小於或是等於這個最大值。這個tag在整個PlayList檔案中只能出現一 次(在巢狀的情況下,一般有真正ts url的m3u8才會出現該tag)
#EXT-X-KEY
表示怎麼對media segments進行解碼。其作用範圍是下次該tag出現前的所有media URI,屬性為NONE 或者 AES-128。NONE表示 URI以及IV(Initialization Vector)屬性必須不存在, AES-128(Advanced EncryptionStandard)表示URI必須存在,IV可以不存在。
  對於AES-128的情況,keytag和URI屬性共同表示了一個key檔案,通過URI可以獲得這個key,如果沒有IV(Initialization Vector),則使用序列號作為IV進行編解碼,將序列號的高位賦到16個位元組的buffer中,左邊補0;如果有IV,則將改值當成16個位元組的16進位制數。
#EXT-X-PROGRAM-DATE-TIME
將一個絕對時間或是日期和一個媒體段中的第一個sample相關聯,只對下一個meida URI有效,格式如#EXT-X-PROGRAM-DATE-TIME:
For example: #EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00
#EXT-X-ALLOW-CACHE
是否允許做cache,這個可以在PlayList檔案中任意地方出現,並且最多出現一次,作用效果是所有的媒體段。格式如下:#EXT-X-ALLOW-CACHE:
#EXT-X-PLAYLIST-TYPE
提供關於PlayList的可變性的資訊, 這個對整個PlayList檔案有效,是可選的,格式如下:#EXT-X-PLAYLIST-TYPE::如果是VOD,則伺服器不能改變PlayList 檔案;如果是EVENT,則伺服器不能改變或是刪除PlayList檔案中的任何部分,但是可以向該檔案中增加新的一行內容。
#EXT-X-ENDLIST
表示PlayList的末尾了,它可以在PlayList中任意位置出現,但是隻能出現一個,格式如下:#EXT-X-ENDLIST
#EXT-X-MEDIA
被用來在PlayList中表示相同內容的不用語種/譯文的版本,比如可以通過使用3個這種tag表示3中不用語音的音訊,或者用2個這個tag表示不同角度的video在PlayLists中。這個標籤是獨立存在的,屬性包含:
  URI:如果沒有,則表示這個tag描述的可選擇版本在主PlayList的EXT-X-STREAM-INF中存在;
  TYPE:AUDIO and VIDEO;
  GROUP-ID:具有相同ID的MEDIAtag,組成一組樣式;
  LANGUAGE:確定使用的主要語言
  NAME:人類可讀的語言的翻譯
  DEFAULT:YES或是NO,預設是No,如果是YES,則客戶端會以這種選項來播放,除非使用者自己進行選擇。
  AUTOSELECT:YES或是NO,預設是No,如果是YES,則客戶端會根據當前播放環境來進行選擇(使用者沒有根據自己偏好進行選擇的前提下)。
#EXT-X-STREAM-INF
指定一個包含多媒體資訊的 media URI 作為PlayList,一般做M3U8的巢狀使用,它只對緊跟後面的URI有效,格式如下:#EXT-X-STREAM-INF:有以下屬性:
BANDWIDTH:頻寬,必須有。
PROGRAM-ID:該值是一個十進位制整數,惟一地標識一個在PlayList檔案範圍內的特定的描述。一個PlayList 檔案中可能包含多個有相同ID的此tag。
CODECS:不是必須的。
RESOLUTION:解析度。
AUDIO:這個值必須和AUDIO類別的“EXT-X-MEDIA”標籤中“GROUP-ID”屬性值相匹配。
VIDEO:同上

 

HLS歷史

 

HLS草案的第一個版本制定在2009年

 

最新的版18:https://tools.ietf.org/html/draft-pantos-http-live-streaming-18#userconsent#   2016年5月失效 會更新新的版本

 

參考文章:M3U8檔案簡介 http://blog.sina.com.cn/s/blog_6cf7acdf0102v0xv.html 

 

                    流媒體開發之--HLS--M3U8解析(1) http://blog.csdn.net/jwzhangjie/article/details/9743971

 

                   流媒體開發之--HLS--M3U8解析(2): HLS草案  http://blog.csdn.net/jwzhangjie/article/details/9744027

 

                    網路直播電視之M3U8解析篇(上)http://blog.csdn.net/matthew_fan/article/details/8365401

 

                  網路直播電視之M3U8解析篇 (下)http://blog.csdn.net/matthew_fan/article/details/8438384

 

 https://blog.csdn.net/m0_37263637/article/details/78836437

前一陣 解決了HLS 的Android和 IOS支援問題。 但PC端瀏覽器並沒有解決,在網上查閱了相關資料後,發現videojs 配合videojs-contrib-hls.js 可以實現呼叫flash播放器播放hls。

瀏覽器實測支援情況:

  前提:pc已安裝flash

  瀏覽器對hls支援情況 :

  Chorme :支援
  firefox:支援
  safiar: 支援
  ie: 不支援
1.html程式碼

<video id="example-video" width=600 height=300 class="video-js vjs-default-skin" controls>
  <source src="http://172.28.28.4:4017/hls/SHY3U1JCLNVBMUND111A/tslive.m3u8" type="application/x-mpegURL">
</video>
<script src="/javascripts/video-js/video.min.js"></script>
<script src="/javascripts/video-js/videojs-contrib-hls.js"></script>
<script>
  var player=videojs('#example-video');
  player.play();
</script>
  
2 使用的video.js和videojs-contrib-hls.js版本

video.js:Video.js 6.4.0 http://videojs.com/
git地址:https://github.com/videojs/video.js.git
videojs-contrib-hls.js:5.12.2
git地址:https://github.com/videojs/videojs-contrib-hls

3.使用中遇到的問題

3.1 使用nginx伺服器時,會遇到跨域問題導致無法播放。使用CORS解決. ###

(1)在nginx conf中該條location下 新增

location /hls/XXXX {
  add_header 'Access-Control-Allow-Origin' 'http://XXX.XX.XX.XXX';
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Access-Control-Allow-Methods' 'GET';

  types{
    application/vnd.apple.mpegurl m3u8;
    video/mp2t ts;
  }
  alias ./hls/XXX;
  add_header Cache-Control no-cache;
}

(2)在使用阿里雲OSS上的碼流時同樣要解決跨域,可以通過控制檯配置跨域規則解決。

3.2 videojs-contrib-hls.js 對hls 支援並不是完美的。

一些可以在蘋果和安卓上播放端的碼流,我們應該以蘋果為標準。然後videojs-contrib-hls.js 並不能解析

比如:
(1) 如果TS中有NIT 位元組,現在的版本是無法解除pmt的。導致不能播放。通過下層封裝程式碼去掉NIT 部分解決
(2)PC端有視訊但沒有音訊,是因為videojs-contrib-hls.js 對AAC解析也不完美,在蘋果上能解的AAC,在videojs-contrib-hls.js 解析中出現了標誌位長度和實際累計長度不一致的情況導致觸發異常處理不能播放聲音。通過修改videojs-contrib-hls.js AAC解算原始碼部分解決。

3.3 附上實測通過的程式碼pug版

extends ../layout
block head
link(rel='stylesheet',href='/stylesheets/video-js/video-js.css')
script(src='/javascripts/jquery/jquery.min.js' type='text/javascript')
script(src='/javascripts/bootstrap.min.js' type='text/javascript')
script(src='/javascripts/video-js/video.min.js' type='text/javascript')
script(src='/javascripts/video-js/videojs-contrib-hls.js' type='text/javascript')

block content
.container
span 播放測試#{description}
.row <strong>jw stream</strong>
<video id="example-video" width=960 height=540 class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto">
<source src="http://xxx.xx.xx.x:4017/hls/xxxxxxxx/tslive.m3u8" type="application/x-mpegURL">
</video>
script.
console.info("i want to konw happen");
var myPlayer=videojs('#example-video'); //自動播放
videojs("example-video").ready(function(){
var myPlayer = this;
myPlayer.play();

});