起播选档是指在视频开始播放前,根据用户的网络状况、设备信息及业务场景,智能选择一个最合适的清晰度进行播放。起播选档旨在优化视频的起播体验,在保障首帧速度的同时,尽可能提供更高的初始画质。本文指导您实现火山引擎自研协议视频的起播选档。
说明
本功能与自研协议 ABR 播放在 SDK 内部都依赖 ABR 模块,但应用场景有所不同:
如果您的业务场景不需要在播放中自动切换清晰度,或者希望获得最优的起播清晰度决策,推荐使用本文介绍的起播选档功能。如果需要播放中自动切换清晰度的能力,请使用 ABR 功能。
在集成起播选档功能前,请确保您已完成以下操作:
集成 SDK 和 ABR 模块:参考集成 SDK 文档集成 1.48.1.x 或之后版本的 SDK。
def ttsdk_version = "1.48.1.x" implementation "com.bytedanceapi:ttsdk-player_premium:$ttsdk_version" implementation "com.bytedanceapi:ttsdk-ttabr:$ttsdk_version"
完成基础的 SDK 初始化:参考快速开始文档完成基本的 SDK 初始化。
在 Application 中,除了 SDK 的常规初始化外,还需要初始化 ABR 模块的全局配置。
public class App extends Application { @Override public void onCreate() { super.onCreate(); initVodSDK(); } } public static void initVodSDK() { // 1. 初始化 SDK Env.init(/*省略*/); // 2. 初始化 ABR 全局配置,为起播选档所必需 TTVideoABRStrategy.init(); // 3. (可选)初始化预加载策略。若您使用自定义预加载,则无需调用 initPreloadStrategy(); // 4. (可选)初始化预渲染策略 initPreRenderStrategy(); }
在创建播放器实例并设置播放源(起播选档功能支持 Vid 和 VideoModel 播放源)后,首次调用 play() 方法前,为播放器配置起播选档策略。
构建选档配置:创建一个 TTVideoABRStartupConfig 对象,用于定义选档算法的行为。
public static TTVideoABRStartupConfig createStartupConfig() { TTVideoABRStartupConfig startupConfig = new TTVideoABRStartupConfig(); // 设置当前设备屏幕宽 startupConfig.screenWidth = screenWidth; // 设置当前设备屏幕高 startupConfig.screenHeight = screenHeight; // 设置在无网络测速信息时的默认清晰度(通常用于App冷启后的第一个视频) startupConfig.defaultResolution = Resolution.High; // 480P // 设置 Wi-Fi 网络下的清晰度上限 startupConfig.wifiMaxResolution = Resolution.ExtremelyHigh; // 1080P // 设置移动网络下的清晰度上限 startupConfig.mobileMaxResolution = Resolution.SuperHigh; // 720P // 传入用户上一次手动选择的清晰度,若非空,则会优先使用该清晰度 startupConfig.userSelectedResolution = getUserSelectedResolution(); // 根据业务场景设置视频的显示尺寸,算法会参考该尺寸选择最合适的清晰度 // 示例:类抖音竖版短视频场景 startupConfig.displayWidth = Math.min(screenWidth, screenHeight); startupConfig.displayHeight = (int) (startupConfig.displayWidth / 9f * 16); /* // 示例:类西瓜横版中视频场景 startupConfig.displayWidth = Math.min(screenWidth, screenHeight); startupConfig.displayHeight = (int) (startupConfig.displayWidth / 16f * 9); // 示例:横版视频全屏场景 startupConfig.displayHeight = Math.min(screenWidth, screenHeight); startupConfig.displayWidth = (int) (startupConfig.displayHeight / 9f * 16); */ return startupConfig; }
如果用户曾手动选择过清晰度,建议通过 userSelectedResolution 字段传入。策略会优先使用用户选择,这对于预加载和起播都有效。
// 例如,使用 SharedPreferences 从本地读取用户上一次的选择 startupConfig.userSelectedResolution = getUserSelectedResolution();
为播放器开启起播选档:调用 TTVideoABRStrategy.initEngine() 方法将配置应用到播放器实例。
if (mVideoEngine == null) { mVideoEngine = new TTVideoEngine(context); mVideoEngine.setIntOption(PLAYER_OPTION_USE_VIDEOMODEL_CACHE, 1); // 设置播放源 mVideoEngine.setStrategySource(source); // 创建起播选档配置 final TTVideoABRStartupConfig startupConfig = createStartupConfig(); // (可选)设置监听器,获取选档结果 startupConfig.mListener = new TTVideoABRStartupResolutionListener() { @Override public void onResolutionSelected(@NonNull IVideoModel videoModel, @NonNull Resolution resolution) { // 起播清晰度选择完成后的回调 } }; // 为播放器实例开启起播选档功能 TTVideoABRStrategy.initEngine(mVideoEngine, startupConfig); } // 开始播放,SDK 内部会自动执行选档逻辑 mVideoEngine.play();
如果您使用 SDK 提供的预加载策略,可以通过设置 PreloadTaskFactory,让起播选档策略参与预加载决策。
public static void initPreloadStrategy() { // 1. 全局开启预加载策略,需要在主线程调用 TTVideoEngine.enableEngineStrategy(StrategyManager.STRATEGY_TYPE_PRELOAD, StrategyManager.STRATEGY_SCENE_SMALL_VIDEO); // 2. 设置 PreloadTaskFactory,使用起播选档结果作为预加载清晰度 StrategyManager.instance().setPreloadTaskFactory(new PreloadTaskFactory() { @Override public PreloaderVidItem createVidItem(VidPlayAuthTokenSource source, long preloadSize) { final PreloaderVidItem item = PreloadTaskFactory.super.createVidItem(source, preloadSize); // 逻辑同自定义预加载 VidPlayAuthTokenSource item.setFetchEndListener((videoModel, error) -> { if (videoModel == null) { return; } item.mResolution = TTVideoABRStrategy.preloadSelect(videoModel, createStartupConfig()); }); return item; } @Override public PreloaderVideoModelItem createVideoModelItem(VideoModelSource source, long preloadSize) { final PreloaderVideoModelItem item = PreloadTaskFactory.super.createVideoModelItem(source, preloadSize); // 逻辑同自定义预加载 VideoModelSource item.mResolution = TTVideoABRStrategy.preloadSelect(source.getVideoModel(), createStartupConfig()); return item; } }); }
如果您使用自定义预加载,可以在创建预加载任务时,调用起播选档策略来决定预加载哪一路清晰度。
final PreloaderVidItem item = new PreloaderVidItem(vidSource, preloadSize); item.setFetchEndListener((videoModel, error) -> { if (videoModel == null) { return; } // 调用起播选档策略选择最合适的清晰度进行预加载 item.mResolution = TTVideoABRStrategy.preloadSelect(videoModel, createStartupConfig()); });
如果您使用 SDK 提供的预渲染策略,需要在创建预渲染播放器实例时,同样为其配置起播选档功能。
开启预渲染策略并配置预渲染引擎:
public static void initPreRenderStrategy() { // 1. 全局开启预渲染策略 TTVideoEngine.enableEngineStrategy(STRATEGY_TYPE_PRE_RENDER, STRATEGY_SCENE_SMALL_VIDEO); // 2. (推荐)开启预渲染 engine 根据 LRU 机制自动释放 StrategyManager.instance().enableReleasePreRenderEngineInstanceByLRU(true); // 3. 设置 EngineStrategyListener,在创建预渲染引擎时进行配置 TTVideoEngine.setEngineStrategyListener(new EngineStrategyListener() { @Override public TTVideoEngine createPreRenderEngine(StrategySource strategySource) { // 此处的配置逻辑,需要保证与正常播放时创建引擎的逻辑完全一致 TTVideoEngine videoEngine = new TTVideoEngine(context); videoEngine.setIntOption(PLAYER_OPTION_USE_VIDEOMODEL_CACHE, 1); videoEngine.setStrategySource(strategySource); final TTVideoABRStartupConfig startupConfig = createStartupConfig(); startupConfig.mListener = new TTVideoABRStartupResolutionListener() { @Override public void onResolutionSelected(@NonNull IVideoModel videoModel, @NonNull Resolution resolution) { // 起播清晰度选择后回调 } }; // 关键步骤:为预渲染的播放器实例同样开启起播选档 TTVideoABRStrategy.initEngine(videoEngine, startupConfig); return videoEngine; } }); }
处理预渲染命中逻辑:当预渲染命中时,直接使用预渲染的播放器实例即可。该实例内部已经完成了选档逻辑。
public void play() { if (mVideoEngine == null) { // 尝试从预渲染缓存中获取播放器实例 TTVideoEngine preRenderEngine = TTVideoEngine.removePreRenderEngine(vid); if (preRenderEngine == null) { // 未命中预渲染:按常规流程创建播放器并配置起播选档 mVideoEngine = new TTVideoEngine(context); mVideoEngine.setIntOption(PLAYER_OPTION_USE_VIDEOMODEL_CACHE, 1); mVideoEngine.setStrategySource(mStrategySource); final TTVideoABRStartupConfig startupConfig = createStartupConfig(); startupConfig.mListener = new TTVideoABRStartupResolutionListener() { @Override public void onResolutionSelected(@NonNull IVideoModel videoModel, @NonNull Resolution resolution) { // 起播清晰度选择后回调 Log.d("VideoPlay", "startupResolution = " + resolution); } }; // 开启起播选档 TTVideoABRStrategy.initEngine(mVideoEngine, startupConfig); } else { // 命中预渲染:直接使用预渲染好的播放器实例 mVideoEngine = preRenderEngine; // 此时可以通过 getCurrentResolution 获取已选定的清晰度 Log.d("VideoPlay", "Hit pre-render, startupResolution = " + mVideoEngine.getCurrentResolution()); } } mVideoEngine.play(); }