You need to enable JavaScript to run this app.
文档中心
文档控制台
注册
视频点播

视频点播

复制全文
下载 pdf
ABR 播放
自研协议 ABR 播放
复制全文
下载 pdf
自研协议 ABR 播放

自适应码流(Adaptive Bitrate Streaming, ABR)播放是指在播放过程中根据用户的网络状况动态地、无缝地切换到最合适的清晰度,从而在保障视频流畅播放的同时,为用户提供最佳的观看体验。播放器 SDK 支持以下两种视频源的 ABR 播放:

  • Vid 模式:适用于播放火山引擎点播服务生成的自研协议 DASH 和 HLS 视频。
  • DirectUrl 模式:适用于播放标准协议的 HLS Master M3U8 视频。URL 可来自火山引擎或第三方服务。

本文指导您以 Vid 播放模式实现火山引擎自研协议 DASH 和 HLS 视频的 ABR 播放。

前提条件

在集成 ABR 播放功能前,请确保您已完成以下操作:

  • 获取 License:ABR 播放为增值功能。请确保您的 License 已包含 ABR 播放功能,详细步骤请见 License 管理

  • 集成高级版 SDK 和 ABR 模块:参考集成 SDK 文档集成 1.47.2.8 或之后版本的高级版 SDK。

    def ttsdk_version = "1.47.3.6"
    implementation "com.bytedanceapi:ttsdk-player_premium:$ttsdk_version"
    implementation "com.bytedanceapi:ttsdk-ttabr:$ttsdk_version"
    
  • 完成基础的 SDK 初始化:参考集成 SDK快速开始文档完成项目的基本配置和 SDK 初始化。

  • 完成自适应码流转码:请确保您已通过火山引擎视频点播的自适应码流转码功能生成了 DASH 或 HLS 格式的视频流。详细信息,请参见自适应码流转码

核心接入流程

步骤 1:初始化 ABR 策略

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();
}

步骤 2:配置 ABR 策略

为播放器实例 TTVideoEngine 设置 ABR 配置 TTVideoABRConfig。具体步骤如下:

  1. 创建一个 TTVideoABRConfig 对象定义 ABR 的行为。您可以根据不同的业务场景(如短视频、中视频、全屏播放)和网络条件(Wi-Fi、移动网络)来配置不同的显示尺寸和清晰度上限。

    public static TTVideoABRConfig createABRConfig() {
        TTVideoABRConfig abrConfig = new TTVideoABRConfig();
        // 设置当前设备屏幕宽高,用于 ABR 算法计算最佳清晰度
        abrConfig.screenWidth = screenWidth;
        abrConfig.screenHeight = screenHeight;
        // 设置默认清晰度,在无网络测速信息时使用
        abrConfig.defaultResolution = Resolution.High; // 480P
        // 设置 Wi-Fi 网络下的最高清晰度
        abrConfig.wifiMaxResolution = Resolution.ExtremelyHigh; // 1080P
        // 设置移动网络下的最高清晰度
        abrConfig.mobileMaxResolution = Resolution.SuperHigh; // 720P
        
        // 根据业务场景设置视频的显示尺寸,以下为短视频场景示例
        abrConfig.displayWidth = Math.min(screenWidth, screenHeight);
        abrConfig.displayHeight = (int) (abrConfig.displayWidth / 9f * 16);
        
        /*
        // 示例:中视频场景
        abrConfig.displayWidth = Math.min(screenWidth, screenHeight);
        abrConfig.displayHeight = (int) (displaySizeConfig.displayWidth / 16f * 9);
        
        // 示例:横版全屏播放场景
        abrConfig.displayHeight = Math.min(screenWidth, screenHeight);
        abrConfig.displayWidth = (int) (abrConfig.displayHeight / 9f * 16);
        */
        return abrConfig;
    }
    
  2. 将 ABR 配置应用到播放器:在创建 TTVideoEngine 实例并设置 Vid 播放源后、首次调用 play() 方法前,调用 TTVideoABRStrategy.initEngine() 方法将 ABR 配置应用到播放器。

    if (mVideoEngine == null) {
        mVideoEngine = new TTVideoEngine(context);
        mVideoEngine.setIntOption(PLAYER_OPTION_USE_VIDEOMODEL_CACHE, 1);
        // 设置播放源,必须为 VidPlayAuthTokenSource
        mVideoEngine.setStrategySource(source);
        TTVideoABRStrategy.initEngine(mVideoEngine, createABRConfig());
    }
    mVideoEngine.play();
    

步骤 3:设置起播清晰度

为了在视频开始播放时选择最合适的清晰度,您需要实现一套逻辑来决定起播清晰度。以下是一个起播清晰度的决策逻辑示例:

  • 优先使用用户选择:如果用户之前手动选择过清晰度,则优先使用该选择。
  • 支持 ABR 则自动档:如果视频支持 ABR(即视频是 BASH 或 HLS 格式),则使用 Resolution.Auto,让 ABR 策略自动选择。
  • 不支持 ABR 则使用默认值:如果视频不支持 ABR,则根据预设的默认值 DEFAULT_RESOLUTION 选择一个最接近的可用清晰度。
// 定义默认的起播清晰度
public static final Resolution DEFAULT_RESOLUTION = Resolution.SuperHigh; // 720P

public static Resolution getStartPlayResolution(IVideoModel videoModel) {
    // 1. 优先使用用户已选择的清晰度
    Resolution userSelectedResolution = getUserSelectedResolution();
    if (userSelectedResolution == null) {
        if (videoModel != null && (videoModel.isSupportBash() || videoModel.isSupportHLSSeamlessSwitch())) {
            // 2. 如果视频支持 ABR,则设置为自动挡
            return Resolution.Auto;
        } else {
            // 3. 如果视频不支持 ABR,则根据默认值选择最接近的清晰度
            return BestResolution.findDefaultResolution(videoModel, DEFAULT_RESOLUTION);
        }
    }
    return userSelectedResolution;
}

步骤 4:应用起播清晰度

在播放器 onFetchedVideoInfo 回调中,调用步骤 3 中的方法获取起播清晰度,并配置给播放器。

// 在 onFetchedVideoInfo 回调中设置起播清晰度
if (mVideoEngine == null) {
    // ...  
    mVideoEngine.setVideoInfoListener(new VideoInfoListener() {
        @Override
        public boolean onFetchedVideoInfo(VideoModel videoModel) {
            Resolution startResolution = getStartPlayResolution(videoModel);
            mVideoEngine.configResolution(startResolution);
            return false;
        }
    });
}
mVideoEngine.play();

播放中的交互与监听

在播放过程中,您需要向用户展示可用的清晰度列表,并处理用户的手动切换操作。同时,您也可以在特定场景下(如全屏切换)动态更新 ABR 的配置。

更新 ABR 配置

如果播放过程中场景发生变化(例如,从列表页进入全屏播放),您可能需要更新 ABR 的配置以适应新的 View 大小或调整清晰度策略。调用 TTVideoABRStrategy.setABRConfig() 方法可以动态更新配置。

// 当播放场景变化时(如全屏切换),更新 ABR 配置
TTVideoABRStrategy.setABRConfig(mVideoEngine, newABRConfig);

获取并展示清晰度列表

在播放器 onFetchedVideoInfo 回调中获取到 VideoModel 之后,您可以获取当前视频支持的所有清晰度,并在 UI 上展示给用户。如果视频支持 ABR,建议在列表的开头添加“自动”选项。

List<Resolution> mResolutions = new ArrayList<>();

// 在 onFetchedVideoInfo 回调之后,获取支持的清晰度列表
Resolution[] supportedResolutions = mVideoEngine.supportedResolutionTypes();
if (supportedResolutions != null && supportedResolutions.length > 0) {
    VideoModel videoModel = mVideoEngine.getVideoModel();
    // 如果支持 ABR,在列表首位添加“自动”选项
    if (videoModel != null && (videoModel.isSupportBash() || videoModel.isSupportHLSSeamlessSwitch())) {
        mResolutions.add(Resolution.Auto);
    }
    for (Resolution r : supportedResolutions) {
        mResolutions.add(r);
    }
}
// 更新 UI 以展示清晰度列表

处理用户手动切换清晰度

当用户从清晰度列表中选择一个选项时,调用 mVideoEngine.configResolution() 方法来切换清晰度。同时,建议将用户的选择持久化存储,以便下次播放时使用。

public void setResolution(Resolution resolution) {
    if (mCurrentSelectedResolution == resolution) return;
    
    mCurrentSelectedResolution = resolution;
    mVideoEngine.configResolution(resolution);
    // 持久化用户选择,以便下次播放时使用
    setUserSelectedResolution(resolution);
}

监听清晰度变化

通过 VideoEngineCallbackonVideoStreamBitrateChanged 回调监听清晰度变化,包括 ABR 自动切换和用户手动切换两种情况。

// 记录用户选择的清晰度(手动选择或自动)
Resolution mCurrentSelectedResolution;

mVideoEngine.setVideoEngineCallback(new VideoEngineCallback() {
    @Override
    public void onVideoStreamBitrateChanged(Resolution newResolution, int bitrate) {
        if (mCurrentSelectedResolution == Resolution.Auto) {
            // 在自动模式下,ABR 会根据网络状况自动切换清晰度
            Log.d("VideoPlay", "[ABR] onVideoStreamBitrateChanged: auto switch to " + newResolution);
        } else {
            // 用户手动切换清晰度完成
            Log.d("VideoPlay", "[ABR] onVideoStreamBitrateChanged: user switch to " + newResolution);
        }
    }
});

获取当前播放清晰度

调用 mVideoEngine.getCurrentResolution() 可以获取当前正在播放的视频流的实际清晰度。注意,此方法不会返回 Resolution.Auto

// 获取当前正在播放的实际清晰度(非 Resolution.Auto)
Resolution currentResolution = mVideoEngine.getCurrentResolution();

进阶使用

结合自定义预加载

如果您使用的是自定义预加载逻辑,可以在创建预加载任务时,让 ABR 策略参与选择预加载的清晰度。

final PreloaderVidItem item = new PreloaderVidItem(vidSource, preloadSize);
item.setFetchEndListener((videoModel, error) -> {
    if (videoModel == null) {
        return;
    }
    Resolution resolution = getStartPlayResolution(videoModel);
    if (resolution == Resolution.Auto) {
        resolution = TTVideoABRStrategy.preloadSelect(videoModel, createABRConfig());
    }
    item.mResolution = resolution;
});

结合预加载策略

如果您使用 SDK 提供的预加载策略,可以通过设置 PreloadTaskFactory 来让 ABR 参与决策。

public static void initPreloadStrategy() { 
    // 1. 全局开启预加载策略,需要在主线程调用 
    TTVideoEngine.enableEngineStrategy(StrategyManager.STRATEGY_TYPE_PRELOAD, StrategyManager.STRATEGY_SCENE_SMALL_VIDEO); 

    // 2. 设置 PreloadTaskFactory,使用 ABR 选档结果作为预加载清晰度 
    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; 
                } 
                Resolution resolution = getStartPlayResolution(videoModel); 
                if (resolution == Resolution.Auto) { 
                    resolution = TTVideoABRStrategy.preloadSelect(videoModel, createABRConfig()); 
                } 
                item.mResolution = resolution; 
            }); 
            return item; 
        } 
    }); 
} 

结合预渲染策略

如果您使用 SDK 提供的预渲染策略,在创建用于预渲染的 TTVideoEngine 实例时,也需要像正常播放一样,为其初始化 ABR 配置。这样,当预渲染的播放器转为实际播放时,ABR 功能才能无缝衔接。

public static void initPreRenderStrategy() {
    // 开启预渲染策略
    TTVideoEngine.enableEngineStrategy(STRATEGY_TYPE_PRE_RENDER, STRATEGY_SCENE_SMALL_VIDEO);
    StrategyManager.instance().enableReleasePreRenderEngineInstanceByLRU(true);

    // 设置 EngineStrategyListener,在创建预渲染引擎时进行 ABR 初始化
    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);
            
            // 关键步骤:为预渲染的播放器实例初始化 ABR
            TTVideoABRStrategy.initEngine(videoEngine, createABRConfig());
            
            // 设置起播清晰度,逻辑与正常播放时一致
            videoEngine.setVideoInfoListener(new VideoInfoListener() {
                @Override
                public boolean onFetchedVideoInfo(VideoModel videoModel) {
                    Resolution resolution = getStartPlayResolution(videoModel);
                    videoEngine.configResolution(resolution);
                    return false;
                }
            });
            
            return videoEngine;
        }
    });
}

当命中预渲染并转为正式播放时,需要正确同步清晰度状态。

public void play() {
    if (mVideoEngine == null) {
        TTVideoEngine preRenderEngine = TTVideoEngine.removePreRenderEngine(vid);
        if (preRenderEngine != null) {
            // 命中预渲染,预渲染的播放器已经设置清晰度,并且当前清晰度已经回调
            // 所以这里需要给 mCurrentSelectedResolution 和 mCurrentResolution 赋值。
            mVideoEngine = preRenderEngine;
            // 同步清晰度相关状态
            mCurrentSelectedResolution = getStartPlayResolution(mVideoEngine.getVideoModel());
            mCurrentResolution = mVideoEngine.getCurrentResolution();
        } else {
            // 未命中预渲染,按常规流程创建播放器
            // ...
        }
    }
    // ...
    mVideoEngine.play();
}

最近更新时间:2025.09.12 15:52:09
这个页面对您有帮助吗?
有用
有用
无用
无用