一、視頻技術
1. 簡介
視頻是一種有結構的數據。直播的時候傳的是數據,是視頻的一個小單元。
視頻 = 圖像 + 音頻
-
視頻里邊的原始圖像數據 通常會采用“H.264編碼格式” 進行壓縮。
-
音頻采樣數據 通常會采用“AAC編碼格式” 進行壓縮。
2. 視頻的實時傳輸
-
-
實時發生的事(直播)肯定是有延遲的。我們要提高直播的質量就需要減小延遲。
3.
-
-
在直播的時候傳輸的視頻數據通常都要壓縮(編碼),傳輸數據的量是越少越好,播放的時候需要解壓(解碼/還原)。
4. 視頻解碼壓縮
-
-
編碼和解碼之前,需要約定一種編碼器和解碼器都可以理解的約定。
- 例如,視頻圖像編碼和解碼過程:
編碼器將多張圖像進行編碼后生成一段一段的GOP(Group of Pictures),傳輸的是GOP(Group of Pictures),解碼器在播放時則是讀取一段一段的GOP進行解碼后讀取畫面再渲染顯示。
GOP:表示一組圖片(即一組連續的畫面),是視頻圖像編碼器和解碼器存取的基本單位,由一張I幀和數張B/P幀組成(I幀又叫關鍵幀,B/P幀又叫參考幀過渡幀),它的排列順序將會一直重復到影像結束。
5. 視頻怎么傳輸?
-
-
將視頻分成分子(GOP),再將分子分成原子(I幀、B幀、P幀)。
——— 這種體驗就類似於直播。
6.
7.
主播端
——RTMP協議——》直播流媒體服務器
——RTMP/HLS協議——》觀眾(粉絲)
- RTMP協議:延時比較小,傳輸速度比較快。(主播錄視頻用這個協議,把視頻數據即時傳到服務器上)
- HLS協議:把主播已經傳好的視頻流切片,切片之后再給粉絲傳輸。(根據時間點去播放,粉絲播放視頻用這個協議,回看也用這個協議)
協議差異:
- RTMP(Real Time Messaging Protocol)協議:是一個TCP協議(長連接),每個時刻的數據,收到后立刻轉發,延時 1~3秒。
- HLS(HTTP Live Streaming)協議:是一個HTTP協議(短連接),集合一段時間數據,生成ts切片文件,更新m3u8,延時大於10秒。
- RTMP-FLV(RTMP over HTTP)協議:是一個HTTP協議(長連接),同RTMP,使用HTTP協議,延時1~3秒。
8. 延遲(Delay)
- 物理延遲
- 延遲指穩定網絡下,發送和接收時差。
- 轉發環節越多,延遲越大。
- 可計算。
- 延遲跟服務器的轉發數 / 主播與粉絲直接的距離有關。
- 抖動(Jitter)延遲
- 抖動,信號會不好。
9. 直播過程
從推流到播放,再經過中間轉發環節,延遲越低,則用戶體驗越好。
10.
軟編的意思是,資源消耗的是CPU,通過一些軟件代碼的模式去編碼。(一般用軟編)
硬編的意思是,資源消耗的是GPU,GPU就相當於是顯卡/顯示的功能。(好手機不卡,壞手機很卡)
二、直播/
視頻端的播放用 ijkplayer,ijkplayer 是B站(bilibili)開源的第三方框架。ijkplayer 已經幫我們集成好了 FFmpeg。
- FFmpeg 是音視頻處理工具,既有音視頻編碼解碼功能,又可以作為播放器使用。
- 任何播放器都是基於FFmpeg的。蘋果提供的AVPlayer,播放不了直播文件/播放不了直播格式(如,RTMP的播放不了,可以用 ijkplayer 去播放)。所以真正的要基於 FFmpeg 去播放,B站幫我們封裝好了,所以我們使用 ijkplayer。
- 斗魚也用的這個,到公司如果不想花錢也可以用這個(ijkplayer)。
- ijkplayer 只能播放,不能推流。
VLC:視頻播放器,編碼格式多(支持的格式多,可以播直播格式的 rtmp://,一般可以用來測試直播地址)。
測試地址:rtmp://live.hkstv.hk.lxdns.com/live/hks (提示:用Safari打開,會自動加入到VLC播放列表中去)
2. ijkplayer 的使用
-
第一步:配置好依賴環境:下載 FFmpeg,編譯FFmpeg。(即如何把 ijkplayer自帶的 IJKMediaDemo 運行起來)
2) 來到README.md文檔的 Build iOS 處,按步驟進行操作
3) 克隆項目:git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios
4) 先進入ijkplayer-ios目錄: cd ijkplayer-ios
,執行: git checkout -B latest k0.7.7.1
5) 再執行: ./init-ios.sh
(意思是去下載 FFmpeg)
(ijkplayer 是基於FFmpeg的,由於FFmpeg比較大,所以要單獨去下載,下載比較慢)
6) 下載完后,進入ios目錄: cd ios
,准備編譯FFmpeg。
7) 編譯FFmpeg,需執行以下命令:
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
8) 編譯成功后,我們就可以運行 IJKMediaDemo 了。
-
第二步:將 IJKMediaPlayer(播放器)項目打包成 framework(方便集成到自己的項目中去)
如何把視頻播放器集成到自己的項目中去?
把一個工程集成到另一個工程一般有兩種方法:
1)工程里集成工程。(這種方法比較麻煩、重量級,不推薦使用)
2)把要集成的工程所有的源碼打包成一個framework,我們只需要集成這個framework到其它項目即可。(推薦)
生成framework的步驟:
1)打開 IJKMediaPlayer 項目
2)修改工程的編譯模式為 Release (因為framework不需要調試,他的代碼已經寫好了的,不需要去修改,所以直接生成release版的framework)
3)編譯一個模擬器版本的framework
4)再編譯一個模擬器版本的framework
5)最后將這兩個framework合並成一個framework,這樣就能保證這個framework既可以在模擬器上運行,又可以在真機上運行。
合並文件命令: lipo -create "真機版本路徑" "模擬器版本路徑" -output "合並后文件的路徑"
6)替換文件:復制合並后的IJKMediaFramework文件到模擬器版/真機版framework中進行替換。
3. 導入 ijkplayer 播放器的 framework
1)直接拖拽framework進行導入
2)添加 ijkplayer 的一些依賴庫
########################################################
AudioToolbox.framework
AVFoundation.framework
CoreGraphics.framework
CoreMedia.framework
CoreVideo.framework
libbz2.tbd
libz.tbd
MediaPlayer.framework
MobileCoreServices.framework
OpenGLES.framework
QuartzCore.framework
UIKit.framework
VideoToolbox.framework
########################################################
如果編譯報以下錯誤:
This is a linker error. You can resolve it by adding "-lc++" to Other Linker Flags in your Build Settings.
解決辦法:Build Settings —》Other Linker Flags —》 添加 -lc++
4. 集成ijkplayer
初始化播放器,設置相關屬性。
5. 創建直播播放界面和直播聊天界面