1. 程式人生 > >ijkplayer視訊秒開優化指北

ijkplayer視訊秒開優化指北

1.在對ijkplayer進行使用除錯的時候(使用FFMoviePlayer),我發現輸出欄中有:

===== options =====
player-opts : start-on-prepared            = 1
player-opts : overlay-format               = fcc-i420
player-opts : max-fps                      = 60
player-opts : framedrop                    = 0
player-opts : videotoolbox-max-frame-width = 960
player-opts : videotoolbox                 = 1
player-opts : video-pictq-size             = 3
format-opts : ijkinject-opaque             = 140449007406288
format-opts : user-agent                   = ijkplayer
format-opts : auto_convert                 = 0
format-opts : timeout                      = 30000000
format-opts : reconnect                    = 1
format-opts : safe                         = 0
codec-opts  : skip_frame                   = 0
codec-opts  : skip_loop_filter             = 0

這就是當前player的一些選項,那麼我們再看看ffoptions中包含的東西:

typedef enum IJKFFOptionCategory {
    kIJKFFOptionCategoryFormat = 1,
    kIJKFFOptionCategoryCodec  = 2,
    kIJKFFOptionCategorySws    = 3,
    kIJKFFOptionCategoryPlayer = 4,
} IJKFFOptionCategory;

這裡的category就是對應上面的option的,那麼我們怎麼改變這些引數呢,我們繼續往下看FFoptions:我們可以看到,作者提供了這樣的設定介面給我們可以看到,作者提供了這樣的設定介面給我們:

- (void)setOptionValue:(NSString *)value
                forKey:(NSString *)key
            ofCategory:(IJKFFOptionCategory)category;

- (void)setOptionIntValue:(int64_t)value
                   forKey:(NSString *)key
               ofCategory:(IJKFFOptionCategory)category;

那麼根據這個我們就可以在初始化播放器時對options進行調整:比如這樣:

IJKFFOptions *options = [IJKFFOptions optionsByDefault];

[options setOptionIntValue:IJK_AVDISCARD_DEFAULT forKey:@”skip_frame” ofCategory:kIJKFFOptionCategoryCodec];

[options setOptionIntValue:IJK_AVDISCARD_DEFAULT forKey:@”skip_loop_filter” ofCategory:kIJKFFOptionCategoryCodec];

[options setOptionIntValue:1 forKey:@”videotoolbox” ofCategory:kIJKFFOptionCategoryPlayer];

[options setOptionIntValue:60 forKey:@”max-fps” ofCategory:kIJKFFOptionCategoryPlayer];

_player = [[IJKFFMoviePlayerController alloc] initWithContentURL:self.url withOptions:options];

這裡要注意幾個地方:
Options初始化不能少[IJKFFOptions optionsByDefault],然後可能由於一些誤解可能會使用錯函式:setvalue forkey,然後忽略了category,導致設定不成功。

至於ffmpeg內部的options呢就只能自己去configure裡面設定了

2.ijkplayer和ffplay在開啟rtmp串流視訊時,大多數都會遇到5~10秒的延遲,在ffplay播放時,如果加上-fflags nobuffer可以縮短播放的rtmp視訊延遲在1s內,而在IjkMediaPlayer中加入

mediaPlayer.setOption(1, "analyzemaxduration", 100L);  
mediaPlayer.setOption(1, "probesize", 10240L);  
mediaPlayer.setOption(1, "flush_packets", 1L);  
mediaPlayer.setOption(4, "packet-buffering", 0L);  
mediaPlayer.setOption(4, "framedrop", 1L);  

1: 設定是否開啟變調

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"soundtouch",isModifyTone?0:1);
2:設定是否開啟環路過濾: 0開啟,畫面質量高,解碼開銷大,48關閉,畫面質量差點,解碼開銷小

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC,"skip_loop_filter",isSkipLoopFilter?0:48L);
3:設定播放前的最大探測時間

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"analyzemaxduration",100L);
4:設定播放前的探測時間 1,達到首屏秒開效果

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"analyzeduration",1);
5:播放前的探測Size,預設是1M, 改小一點會出畫面更快

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"probesize",1024*10);
6:每處理一個packet之後重新整理io上下文

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"flush_packets",1L);
7: 是否開啟預緩衝,一般直播專案會開啟,達到秒開的效果,不過帶來了播放丟幀卡頓的體驗

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"packet-buffering",isBufferCache?1:0);
8:播放重連次數

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"reconnect",5);
9:最大緩衝大小,單位kb

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"max-buffer-size",maxCacheSize);
10:跳幀處理,放CPU處理較慢時,進行跳幀處理,保證播放流程,畫面和聲音同步

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"framedrop",5);
11:最大fps

mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"max-fps",30);
12:設定硬解碼方式

jkPlayer支援硬解碼和軟解碼。 軟解碼時不會旋轉視訊角度這時需要你通過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);

13.SeekTo設定優化

某些視訊在SeekTo的時候,會跳回到拖動前的位置,這是因為視訊的關鍵幀的問題,通俗一點就是FFMPEG不相容,視訊壓縮過於厲害,seek只支援關鍵幀,出現這個情況就是原始的視訊檔案中i 幀比較少
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);

3.iOS端使用例項程式碼:

    IJKFFOptions *options = [IJKFFOptions optionsByDefault];
    // Set param
    [options setFormatOptionIntValue:1024 * 16 forKey:@"probsize"];
    [options setFormatOptionIntValue:50000 forKey:@"analyzeduration"];
    [options setPlayerOptionIntValue:0 forKey:@"videotoolbox"];
    [options setCodecOptionIntValue:IJK_AVDISCARD_DEFAULT forKey:@"skip_loop_filter"];
    [options setCodecOptionIntValue:IJK_AVDISCARD_DEFAULT forKey:@"skip_frame"];
    if (_isLive) {
        // Param for living
        [options setPlayerOptionIntValue:3000 forKey:@"max_cached_duration"];   // 最大快取大小是3秒,可以依據自己的需求修改
        [options setPlayerOptionIntValue:1 forKey:@"infbuf"];  // 無限讀
        [options setPlayerOptionIntValue:0 forKey:@"packet-buffering"];  //  關閉播放器緩衝
    } else {
        // Param for playback
        [options setPlayerOptionIntValue:0 forKey:@"max_cached_duration"];
        [options setPlayerOptionIntValue:0 forKey:@"infbuf"];
        [options setPlayerOptionIntValue:1 forKey:@"packet-buffering"];
    }
    ```


  

>  iOS開發者交流群:①群:446310206 ②群:426087546 (付費群, 介意勿加! 手機加群)