iOS基於B站的IJKPlayer架構的流媒體探究
一.流媒體
流媒體技術從傳輸形式上可以分為:漸進式下載和實施流媒體。
1.漸進式下載
它是介於即時播放和本地播放之間的一種播放方式,漸進式下載不必等到全部下載完成後在播放,可以邊下載邊播放,播放完成後,整個檔案會儲存下來。從使用者的體驗上合播放方的效果來看,漸進式下載和即時資料流媒體沒有什麼區別,不過是漸進式下載保留有檔案在本地。下面來介紹下漸進式下載的開發 漸進式下載的API和本地播放的API沒有什麼太大的區別,可以使用MediaPlayer架構中得MediaPlayerController和MediaPlayerViewController進行播放,亦可以使用AVFoundation架構中得AVPlayer進行播放。在mac os系統下都有一個Apache HTTP伺服器,首先開啟服務,使用命令列:sudo apachectl -v 輸入密碼後 接著輸入 sudo apachectl start 就可以了 然後把要播放的檔案放到/Library/WebServer/documents下就可以了 .
2.即時資料流媒體
即時資料流媒體是一邊接收資料包一邊進行播放,本地不保留檔案副本,資料總是即時傳送的。使用者可以快進快退,不過,即時資料流媒體播放必須保證資料包的傳輸速度大於檔案的播放速度,否則影響播放效果。
即時資料流媒體傳輸的協議有:RTSP和HLS、MMS。HLS是蘋果公司提出的,它只請求基本的HTTP報文,與RTSP和MMS不同,HLS可以穿過任何允許HTTP資料通過的防火牆。而且,HLS對伺服器沒有特殊要求,只要能夠提供HTTP服務就可以了。
HLS的解決方案:首先通過音頻或視頻採集裝置採集資料,然後將資料傳遞給Server對音頻或者視頻進行編碼,編碼要求採用MPEG-2格式,編碼完成之後再通過媒體檔案分隔工具進行分割,然後再講這些分割好的檔案和他們的索引檔案發布到發行伺服器上,然後用戶端就可以訪問了。
二.HLS
HTTP Live Streaming(HLS)是蘋果公司(Apple Inc.)實現的基於HTTP的流媒體傳輸協議,可實現流媒體的直播和點播,主要應用在iOS系統,為iOS裝置(如iPhone、iPad)提供音ApsaraVideo for Live和點播方案。HLS點播,基本上就是常見的分段HTTP點播,不同在於,它的分段非常小。要實現HLS點播,重點在於對媒體檔案分段,目前有不少開源工具可以使用,這裡我就不再討論,只談HLS直播技術。
HLS實現方式原理圖
vczlzsS8/qOoTVBFRy1UU7jxyr2jqaOstvi/zbuntsvU8rK7ts+1xM/C1NiyorKlt8XV4tCp0KHOxLz+o6zS8s6qt/7O8cb3tsvX3MrHu+G9q9fu0MK1xNaxsqXK/b7dyfqzydDCtcTQoc7EvP6jrNXi0fm/zbuntsvWu9KqsrvNo7XEsLTLs9DysqW3xbTTt/7O8cb3u/HIobW9tcTOxLz+o6y+zcq1z9bBy9axsqWho9PJtMu/ybz7o6y7+bG+yc+/ydLUyM/OqqOsSExTysfS1LXjsqW1xLy8yvW3vcq9wLTKtc/W1rGypaGj08nT2sr9vt3NqLn9SFRUUNCt0um0q8rko6zL+dLUzerIq7K708O/vMLHt8C78Me9u/LV37T6wO21xM7KzOKjrLb4x9K31rbOzsS8/rXEyrGzpLrctsyjrL/Nu6e2y7/J0tS63L/stcTRodTxus3H0Lu7wuvCyqOs0tTKytOmsrvNrLT4v+3M9bz+z8K1xLKlt8Who7K7uf1ITFO1xNXi1ta8vMr1zNi146Osvva2qMHLy/y1xNHTs9nSu7Dj19zKx7vhuN/T2sbVzai1xMH3w73M5daxsqXQrdLpoaM8L3A+DQo8cD64+b7d0tTJz7XEwcu94tKqyrXP1khUVFAgTGl2ZSBTdHJlYW1pbmfWsbKlo6zQ6NKq0dC+v7KiyrXP1tLUz8K8vMr1udi8/LXjPC9wPg0KPHA+KDEpssm8r8rTxrXUtLrN0vTGtdS0tcTK/b7dPGJyIC8+DQooMim21NStyrzK/b7dvfjQ0EgyNjSx4MLrus1BQUOx4MLrPGJyIC8+DQooMynK08a1us3S9Ma1yv2+3bfi17DOqk1QRUctVFOw/DxiciAvPg0KKDQpSExTt9a2zsn6s8my38LUvLBtM3U4y/fS/c7EvP48YnIgLz4NCig1KUhUVFC0q8rk0K3S6TwvcD4NCjxoMyBpZD0="三基於b站的流媒體解決方案ijkplayer架構">三.基於B站的流媒體解決方案Ijkplayer架構
最近在關注流媒體直播這塊兒,經過技術老大的推薦B站的ijkplayer架構,開始了一段爬坑曆程……
(1)第一步到github上下載B站開源的ijkplayer架構
(2)根據說明文檔進行編譯前的各種操作,其實不難就三大步驟
注意: 帶有#號標註的是注釋,不用在控制台中輸入
第一步:運行環境的搭建(需要ruby,home-brew,git,yams等環境),開啟終端將以下沒有#號開頭的語句進行輸入.
# install homebrew, git, yasm
ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”
brew install git
brew install yasm
# add these lines to your ~/.bash_profile or ~/.profile# export ANDROID_SDK=# export ANDROID_NDK=# on Cygwin (unmaintained)# install git, make, yams
第二步: 將ijkplayer項目複製到本地並且將ffmpeg整合到ijkplayer中(這一步驟比較耗時,需要耐心等待),在終端輸入以下命令..
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios
cd ijkplayer-ios
git checkout -B latest
./init-ios.sh
cd ios
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
第三步: 開啟ijkplayer-ios下的iOS檔案下的IJKMedioDemo
官方上的以下兩句的意思是將IJKMediaPlayer匯入到你的項目中
#import ios/IJKMediaPlayer for MediaPlayer.framework-like interface (recommended)#open ios/IJKMediaDemo/IJKMediaDemo.xcodeproj with Xcode
然後將IJKMediaPlayer拖到此檔案中.
這樣就可以開啟官方給出的demo樣本程式了.
運行出來的:
以上是官方給出的demo,仿照demo裡面很多功能都是可以實現的.那麼問題來了,如何將IJKPlayer整合到自己的項目中呢?本人在整合的時候遇到了很大的坑……
將ijkplayer整合到自己的項目中:
建立自己的項目:
第一步:將IJKMediaFrameWork.framework靜態庫和IJKMediaPlayer入到專案檔中
第二不:開啟項目添加到這兩個檔案到主目錄,然後開啟Build Phases添加以下庫
這樣就完美了,run以下就可以輕鬆加愉快的進行流媒體的相關開發了……..
四.M3U8
做流媒體開發必須接觸的一種檔案叫M3U8檔案,那麼什麼是M3U8呢?
M3U8檔案是指UTF-8編碼格式的M3U檔案。M3U檔案是記錄了一個索引純文字檔案,開啟它時播放軟體並不是播放它,而是根據它的索引找到對應的音視頻檔案的網路地址進行線上播放。
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:同上