1.問(wèn)題場(chǎng)景
業(yè)務(wù)場(chǎng)景上使用ijkplayer 播放rtsp直播流 標(biāo)清地址:192.168.2.2:A? 高清地址 192.168.2.2:B? 兩個(gè)直播流ip地址相同但是端口不同
出現(xiàn)的問(wèn)題就是 單獨(dú)播放任一個(gè)播放源都是沒(méi)問(wèn)題的攒暇,但是播放過(guò)A后再播放B? ?或 播放B后再播放A 都會(huì)報(bào)10000 錯(cuò)誤
經(jīng)查找很多文章后如:http://www.reibang.com/p/61ba6bea1d6e 提供的解決辦法
ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"dns_cache_clear",1);
并未解決這個(gè)問(wèn)題,起初是懷疑自己設(shè)置的option 未生效
遂使用反射的方式來(lái)設(shè)置:
Method method = Class.forName("tv.danmaku.ijk.media.player.IjkMediaPlayer")
.getDeclaredMethod("setOption", int.class, String.class, long.class);
method.invoke(ijkMediaPlayer, IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1);
然并卵了。
后來(lái)去官方issues查閱?3700??4510? 發(fā)現(xiàn)類似問(wèn)題?
有人提供了修改ffmpeg編譯的方法入偷,可是觀看到最新版ffmpeg 有些方法已經(jīng)修改了
因?yàn)槲冶旧硎褂玫膕o 是從GSYVideoPlayer里提的城侧,(Win黨編譯打腦殼)一時(shí)間陷入僵局
后面翻GSY的issues 查看到?2112?作者已經(jīng)重新打了so? 解決了這個(gè)問(wèn)題愚屁,非常感謝截型。特此記錄蚕泽。(有能力還是自己編譯這樣邁過(guò)門檻以后也方便點(diǎn)陶冷。)
附完整的配置供參考
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 0);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
// 視頻幀處理不過(guò)來(lái)的時(shí)候丟棄一些幀達(dá)到同步的效果
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 2);
// 需要準(zhǔn)備好后自動(dòng)播放0 否 1 是
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);
// 不額外優(yōu)化(使能非規(guī)范兼容優(yōu)化钙姊,默認(rèn)值0 )
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "fast", 1);
// 設(shè)置播放前的探測(cè)時(shí)間 1,達(dá)到首屏秒開(kāi)效果
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1);
//0軟解碼 1 硬解碼
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "videotoolbox", 1);
// 支持硬解 1:開(kāi)啟 O:關(guān)閉
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-hevc", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");//如果是rtsp協(xié)議,可以優(yōu)先用tcp(默認(rèn)是用udp)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 1024 *1024);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 3000);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1);
// 是否開(kāi)啟預(yù)緩沖埂伦,一般直播項(xiàng)目會(huì)開(kāi)啟煞额,達(dá)到秒開(kāi)的效果,不過(guò)帶來(lái)了播放丟幀卡頓的體驗(yàn)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0L);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);//開(kāi)啟硬解碼
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1);
// 縮短播放的rtmp視頻延遲在1s內(nèi)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer");
// 默認(rèn)最小幀數(shù)2
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 2);
// 設(shè)置播放前的最大探測(cè)時(shí)間 (100未測(cè)試是否是最佳值)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzemaxduration", 100L);
// 播放前的探測(cè)Size沾谜,默認(rèn)是1M, 改小一點(diǎn)會(huì)出畫面更快
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 200);
// 播放重連次數(shù)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "reconnect", 5);
// 每處理一個(gè)packet之后刷新io上下文
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1L);
//清空dns緩存 防止播放切換的時(shí)候 DNS的問(wèn)題(關(guān)鍵代碼)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 0);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_timeout", -1);
完膊毁。