gsy-live-and-ads
直播接入要点
setUp(url, false, title)——cacheWithPlay必须false。onResume/player.onVideoResume(false):seek=false避免拉流跳变(见 GSYVideoView#L549)。- 内核选择:
- RTMP / RTSP:必须 IJK;System / Exo / Aliyun 各有兼容性差异。
- HLS:Exo 更稳;Ijk 需要开启硬解
GSYVideoType.enableMediaCodec()才顺。
- 关键参数:
builder.setNeedShowWifiTip(false)(后台 App 不打断)builder.setReleaseWhenLossAudio(false)(丢音频焦点不释放)builder.setSurfaceErrorPlay(true)
对 IJK 加 low-latency:通过 VideoOptionModel 注入 ffmpeg option,见 BasePlayerManager 与 GSYVideoManager.instance().setOptionModelList(list)。常用 option:analyzemaxduration=100、probesize=10240、flush_packets=1、fflags=nobuffer、packet-buffering=0、framedrop=1。
广告 AD
- 双 Manager 双 Player:
GSYVideoADManager.instance()负责广告 player,GSYVideoManager.instance()负责主片;两者共存不打架。 - 组件 GSYADVideoPlayer 与"广告示例"GSYSampleADVideoPlayer 都继承
StandardGSYVideoPlayer。 - Activity 基类:GSYBaseADActivityDetail,提供
getGSYVideoADPlayer()/initADVideo()/startAD(String adUrl, String url)/onADEnd。
startAD(...) 关键调用序
- Activity 里持有主 player + AD player 两个 View;
initADVideo()装配(内部会连锁OrientationUtils);startAD(adUrl, mainUrl)播广告;- AD complete → SDK 内部隐藏 AD player、start 主 player;
- 用户点"跳过"→
getGSYVideoADPlayer().onAutoCompletion()。
无缝切源 / 切码率
Exo 内核用 Exo2PlayerManager.setCurrentMediaSource(...) 或 Demo 里的 GSYExo2MediaPlayer.setMediaSources(...);Ijk 则重新 setUp + startPlayLogic。切换的过程中要求"不闪黑",用:
- KeepLastFrameVideo(Demo 组件)+ KeepLastFrameDemoActivity;
- 原理见 doc/KEEP_LAST_FRAME.md:新 player 拿到首帧前,把旧 SurfaceTexture 内容以 Bitmap 覆盖在上层。
广告 / 主片全屏切换的两个陷阱
- 主片全屏 → 广告插入:
GSYVideoADManager无内部OrientationUtils;GSYBaseADActivityDetail已处理,但自定义子类需重写getGSYVideoADPlayer()返回 AD player 才能被基类的旋转/回退纳管。 - 广告全屏返回 → 直接销毁 AD player:
onBackPressed需要判断GSYVideoManager.backFromWindowFull(this) || GSYVideoADManager.backFromWindowFull(this)。
Demo 对照
- 单主片:DetailPlayer
- 前贴片 + 主片:DetailADPlayer / DetailADPlayer2
- 列表条目内广告:ListADVideoActivity / ListADVideoActivity2 / RequestListADVideoPlayer
- 智能硬解回退:SmartMediaCodecFallbackActivity
常见坑
- 直播卡顿升级 → 检查是否开启
cacheWithPlay(对直播来说必须关)。 - 广告
onAutoComplete后主片没自动 setUp → 检查是不是把setStartAfterPrepared(false)传给了主 builder。 - RTMP 断流回收后重连白屏 →
onVideoResume(false)+player.getCurrentPlayer().onVideoReset()再startPlayLogic()。