HLS直播技術方案及踩過的坑
一、為什麼是IJKPlayer
在基礎技術方面,後端有比較成熟的系統,就不再說了,這裡說說客戶端方面。
有直播就會有彈幕,基本上是標配了。
字幕方面bilibili開源了一個Android的專案,不過IOS卻沒有,這個只能自己寫了,不過本身這個東西技術方案沒有什麼太高深的東西,建立一個HTTP連線,不停地讀資料就好了,如果關閉字幕,就把連線斷掉。在顯示方面可能要考慮一些細節問題,像速度、位置、字數限制、之類的。
播放器方面,Android和IOS理論上是原生支援HLS播放的,不過實際應用過程中適配問題比較多,所以業內一般都使用bilibili開源出來的IJKPlayer,像鬥魚TV之類的都是自己基於IJKPlayer改造的,技術方案比較成熟,穩定性方面比較可靠,使用起來也很簡單,專案的編譯指令碼做的比較簡單、靈活。
二、IJKPlayer的使用。
把專案Clone下來之後,首先要做的就是配置一下Codec,因為IJKPlayer使用ffmpeg做Codec,如果不裁剪一下,編出來的庫會大的驚人。看一下config/module.sh,把不需要的codec注掉就OK了,我只使用了aac、H264兩種。最後兩個平臺上面編出來都是大概有1M多,作為一個播放器來說,Size絕對很小了。
Android目前主流機器都支援ARMV7了,只編這一種也足夠了,對IOS來說,ARMV7、ARMV7s、ARM64這幾種都得支援,除錯時還需要使用i386,所以為了簡單起見,測試階段,我生成了支援ARMV7、ARMV7s、ARM64、i386這四種CPU架構的庫,等到釋出階段再去掉i386架構的程式碼,進一步縮小包大小。
下面以IOS為例說一下整個編譯過程。
1、修改config/module.sh,裁剪需要的codec等配置,把不用的去掉,減少最終生成的包大。
1、執行init-ios.sh,這裡主要是下載ffmpeg的程式碼。
2、執行ios/compile-ffmpeg.sh,這裡主要編譯ffmpeg的程式碼。可以修改裡面的配置來決定編譯哪些CPU架構,可選的有arm7、arm7s、arm64、i386、386_64等。
3、編譯完成之後,開啟IJKMediaPlayer,進行Build。IJKMediaPlayer是個.a專案。Build時,IJKMediaPlayer的build setting中,Architectures和Valid Architectures兩個設定項中的CPU架構列表都是armv7,armv7s,arm64這三種。如果Schema中的target選擇模擬器,則最終生成的.a庫檔案有i386,x86_64兩個CPU架構的指令,把.a整合到我的專案中,使用xcodebuild進行打包時,會報找不到armv7,armv7s,arm64等幾種架構指令的錯誤;如果Schema中的target選擇iOS device,則最終生成的.a庫檔案只有armv7、armv7s、arm64這幾種CPU架構的指令,整合到我的專案中使用XCode進行編譯時由於找不到i386架構的指令,也同樣會報錯。最後使用lipo create,所以兩個.a庫檔案進行Merge,問題解決,不過.a庫比較大,只好等釋出時再把i386,x86_64兩種CPU架構的指令裁剪掉了。
4、把編譯生成的libIJKMediaPlayer.a,以及對應的include檔案放到專案中就可以使用了。庫檔案和標頭檔案的位置在這裡:開啟finder,在選單中開啟“前往”,按住Alt,點選選單中出現的“資源庫”,Developer->Xcode->DerivedData,找到IJKMediaPlayer打頭的資料夾,點選進入,裡面的每個子資料夾分別對應Debug/Release、IOS裝置/模擬器四種情況下生成的.a庫和標頭檔案。
5、.a檔案生成時特別大,我這裡有20多M,但專案整體打包後包大小隻增加了1M多。這個數字差別如此之大,著實讓人吃驚。大家知道老碼農是好奇心最強的,把網際網路翻得底朝天,終於確認了原因如下:
三、.a的壓縮優化
1、編譯優化選項沒有設定,後來我在編譯libIJKMediaPlayer.a時,對Build Setting中的優化項進行了設定(具體設定了些什麼,看第六條),生成的libIJKMediaPlayer.a到了7M+。
2、打包App時,會把.a和App中的程式碼進行Link,在Link完成後會刪除很多.a中存在的在Link時使用的中間資訊,當Link完成之後這些資訊就被刪除了。
四、技術選型
關於直播實現方案的選擇,以及HLS優缺點的詳細分析,可以看下這篇文章:http://www.cnblogs.com/haibindev/archive/2013/01/30/2880764.html
五、生成.a時的CPU架構指令問題
IJKMediaPlayer編譯時的CPU架構指令生成問題,可以參考這裡:http://www.cocoachina.com/ios/20140915/9620.html
把兩種CPU架構指令的.a檔案進行Merge,可以參考這裡:http://blog.sina.com.cn/s/blog_916e0cff0102vb9c.html
六、編譯優化(Build Setting)
1、按照這兩篇文章裡提到的幾種優化方式進行優化:
2、strip style在非app的工程中使用non-global symbols,在app工程中使用all。
3、對於Build Settings最詳細的解釋,當然還是官方文件了:https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/0-Introduction/introduction.html#//apple_ref/doc/uid/TP40003931-CH1-SW1
4、比較極端的情況下,也可以試試write link map file:http://blog.cnbang.net/tech/2296/
補充於2016.7.8
2015.6月份的iOS版在前幾天執行時,發現偶爾有黑屏現象。場景是程式啟動,播放第一個視訊二、三十分鐘後,退出再播放第二個視訊。
拉取最新程式碼,編了tag為k0.5.1的版本後,該問題沒有再重現過。
另外,目前播放器以framework的形式提供,接入時直接加入原始碼中就OK。如果使用Build Phase中新增二進位制庫的方式會出現framework no found的問題。
相關文章
- Redis 叢集部署及踩過的坑Redis
- 我在秋招中踩過的那些坑|掘金技術徵文
- 使用 Markdown 寫技術部落格,我踩過的 6個坑
- 那些年你踩過的坑,都在這裡了~| 掘金技術徵文
- GeoServer 踩過的坑Server
- JasperReport 中踩過的坑
- Spring 4.2.2以上版本和swagger整合方案和踩過的坑SpringSwagger
- 解析資料踩過的坑
- 你踩過flutter的坑嗎Flutter
- 配置Nginx以支援RTMP直播及HLS流播放Nginx
- 親自踩過的vue的坑Vue
- golang定時任務踩坑及終極解決方案Golang
- wepy小程式踩過的坑(1)
- 安裝 Laravel/horizon 踩過的坑Laravel
- Compose 延遲列表踩過的坑
- uniapp之那些年踩過的坑APP
- 記:css繪製小豬佩奇的專案及踩過的坑CSS
- springboot升級過程中踩坑定位分析記錄 | 京東雲技術團隊Spring Boot
- 踩過的坑(一)——web容器升級Web
- linux環境壓測踩過的坑Linux
- vue+iframe使用及踩坑Vue
- PC端直播工具技術解決方案
- vue專案中踩過的element的坑Vue
- 小程式的這些坑你踩過嗎?
- 使用ABP框架中踩過的坑系列2框架
- 當年用httpclient時踩過的那些坑HTTPclient
- IDEA建立Maven專案中踩過的坑IdeaMaven
- 記錄自己在tensorflow中踩過的坑
- IT人,那些年,一起踩過的坑
- Android開發踩坑及最佳實踐(工作踩坑記錄 持續更新...)Android
- 小白程式設計師最容易踩的“坑”,你踩過幾個?程式設計師
- mpvue小程式以及微信直播踩坑總結Vue
- golang的踩坑Golang
- 容器映象倉庫-Harbor的安裝及踩坑
- 資料處理踩過的坑(不斷更新):
- nrf52832藍芽開發踩過的坑藍芽
- Charles在windows下的安裝以及踩過的坑Windows
- 技術方案設計的方法論及案例分享
- webpack入門及踩坑應對指南Web