KontextVideo.initialize 在启动时运行。
每种格式都遵循同样的四个步骤:
VideoAds(content),对应观众正在看的视频。ads.format()向服务器请求并返回一个VideoAd。ad.load()在屏幕外渲染素材,之后展示即时完成。或者ad.reject(),如果你不会使用它。- 在你选的时刻
ad.show()。结束时一个onAdEnded回调。
format() 和 load() 是 suspend 函数;下面的代码片段从 lifecycleScope 调用它们。在 Java 中使用它们的回调版本;见从 Java 调用。
1. 创建视频的广告对象
每个视频(剧集)一个VideoAds。创建它不发送任何请求。在你使用它的广告期间一直保留它,例如作为播放器 Activity 或 Fragment 的属性,并在页面离开时调用 destroy():丢掉引用并不会结束它的广告。
id 和 language 是必填的;其余字段都能改善定向,有什么就发什么。
把播放器交给 SDK,这样事件会带上内容播放位置,叠加广告也会跟随播放:
track(Player) 来自 so.kontext:video-media3。如果播放器不是 Media3 Player,实现 VideoAdsPlayer,以同样方式传入。
2. 获取广告
format() 向服务器请求你传入的格式的广告。在剧集打开时就请求,而不是等到你想展示广告的那一刻:请求和加载需要一点时间,而广告应该立即出现。
服务器没有广告时它抛出 VideoAdException.NoFill。这是正常的,不是故障;稍后再请求。
3. 加载它,或拒绝它
load() 在屏幕外渲染素材,就绪后返回,所以 show() 是即时的。如果你决定不用这个广告,调用 overlayAd?.reject(),广告主会收到通知。
4. 展示它
每种格式有自己的时刻和自己的show()。
- 叠加
- 暂停
- 线性
剧集播放时,在你选的时刻出现在播放器上的一条条幅。几秒后,或观众一暂停,它就会自行消失。请在内容播放时展示:在暂停的内容上 想提前移除,对它调用
show(container) 会抛出 ContentPaused。dismiss()。如果你自己的控件覆盖在播放器上,用 insets 让广告避开它们;见让广告避开你的控件。show() 要么抛错且什么都没发生,要么广告已在屏幕上。从那以后由 SDK 运行它直到结束。
5. 响应结束
实现VideoAdListener。每个方法都有空的默认实现;你需要的是 onAdEnded。每个已展示的广告它恰好到达一次,无论是谁结束了它,所以把恢复逻辑放在这里,别处不放,并从这里请求下一个广告,让它提前就绪。
- 叠加
- 暂停
- 线性
你的内容一直在播放,所以无需恢复。
6. 清理
观众离开视频时调用destroy():在 Activity 的 onDestroy()、Fragment 的 onDestroyView(),或 Compose 中 DisposableEffect 的 onDispose 里。它丢弃所有持有的广告,告诉服务器哪些没有被使用,并结束屏幕上的那个。
完整代码
每集一个 Activity,在ExoPlayer 中播放。选择与你的格式对应的标签页:
- 叠加
- 暂停
- 线性