1、ijkplayer 編碼
IjkPlayer支持硬解碼和軟解碼。 軟解碼時不會旋轉視頻角度這時需要你通過onInfo
的what == IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED
去獲取角度,自己旋轉畫面。或者開啟硬解硬解碼,不過硬解碼容易造成黑屏無聲(硬件兼容問題),下面是設置硬解碼相關的代碼
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1); mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1); mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1);
2、ijkplayer 倍速播放
目前ijkplayer最新版本支持倍速播放(版本號0.7.7.1)。在早期版本對倍速播放支持的不是很好,只有6.0及以上的手機才能進行倍速播放。但是目前雖然所有的機型都支持倍速,但是6.0以下的手機明顯有聲調變化,這樣用戶體驗不是很好(針對變調的文章會在以后更新)。下面是最新的倍速設置代碼:
public void setSpeed(float speed) { _setPropertyFloat(FFP_PROP_FLOAT_PLAYBACK_RATE, speed); }
老版本代碼:
@TargetApi(Build.VERSION_CODES.M) public void setSpeed(float speed) { _setPropertyFloat(FFP_PROP_FLOAT_PLAYBACK_RATE, speed); }
老版本代碼只能設置速度,不能獲取,所以基本上不能用(而且機型方面只支持6.0以上的機型)。
更新:當前最新版本為0.8.8,倍速功能能夠在所有android機型上正常使用,倍速時可能也存在聲調問題,但是可以通過設置參數來解決:
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1);
此問題,本人也專門寫了一篇文章做了詳細的說明,文章地址為:https://www.cnblogs.com/renhui/p/6510872.html
3、ijkplayer的一些重要的視頻返回碼
int MEDIA_INFO_VIDEO_RENDERING_START = 3;//視頻准備渲染 int MEDIA_INFO_BUFFERING_START = 701;//開始緩沖 int MEDIA_INFO_BUFFERING_END = 702;//緩沖結束 int MEDIA_INFO_VIDEO_ROTATION_CHANGED = 10001;//視頻選擇信息 int MEDIA_ERROR_SERVER_DIED = 100;//視頻中斷,一般是視頻源異常或者不支持的視頻類型。 int MEDIA_ERROR_IJK_PLAYER = -10000,//一般是視頻源有問題或者數據格式不支持,比如音頻不是AAC之類的 int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;//數據錯誤沒有有效的回收
4、Ijkplayer調用seekTo存在的問題
ijkplyer 在播放部分視頻時,調用seekTo的時候,會跳回到拖動前的位置,這是因為視頻的關鍵幀的問題(GOP導致的),視頻壓縮比較高,而seek只支持關鍵幀,出現這個情況就是原始的視頻文件中i幀比較少,播放器會在拖動的位置找最近的關鍵幀。所以,目前針對此問題ijkPlayer無解。
注:目前最新版0.8.8相對於之前的版本來說,seekTo的問題應該會小很多,但是不可避免的還是會存在。
相關代碼:
setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
5. Ijkplayer音視頻不同步問題
在開始使用過程當中對rtmp視頻流進行播放,會出現嚴重的視頻音頻不同步現象,並且隨着播放的時間越長,視頻與音頻的差距越大。具體原因是CPU在處理視頻幀的時候處理得太慢,默認的音視頻同步方案是視頻同步到音頻, 導致了音頻播放過快,視頻跟不上。
{ "framedrop", "drop frames when cpu is too slow", OPTION_OFFSET(framedrop), OPTION_INT(0, -1, 120) },
framedrop 控制着允許丟幀的范圍。可以通過修改 framedrop 的數值來解決不同步的問題,framedrop 是在視頻幀處理不過來的時候丟棄一些幀達到同步的效果。具體設置:
player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 5);
framedrop 的具體大小根據實際情況而定, 一般丟太多幀也不好,會影響用戶的觀看體驗。
6、如何支持https鏈接播放?
如果你的項目要進行加密播放HLS協議的視頻,要想支持https,須要在普通編譯的基礎上,進行一些配置。
接下來我們來編譯openssl
a). init openssl
$ cd .. 進入到ijkplayer的目下 $ ./init-android-openssl.sh 去遠程倉庫拉取openssl的遠程代碼,如果是iOS的,這里是init-ios-openssl.h
b). compile openssl
$ cd android/contrib $ ./compile-openssl.sh clean $ ./compile-openssl.sh all
經過以上步驟已經編譯好openssl了,然后我們執行一下方法
$./compile-ffmpeg.sh clean 編譯ffmpeg軟解碼庫,這個過程會生成各種架構的ffmpeg 這個過程比較耗時 $./compile-ffmpeg.sh all
7、Ijkplayer使用小技巧
a. 下載速度可以通過IjkMediaPlayer的 getTcpSpeed
獲取。
b. 高分辨率開啟硬解碼,不支持的話會自動切換到軟解,就算開啟mediacodec,如果設備不支持,顯示的解碼器也是avcodec軟解。
c. IjkMediaPlayer.setOption可配置的對應頭文件參考:ff_ffplay_options。
d. 設置cookie 可以通過ijkPlayer的public void setDataSource(String path, Map<String, String> headers) 的header實現設置,參考ijkPlayer的issues-1150,headers也是在內部被轉化為何issuses一樣的setOption方法