You need to enable JavaScript to run this app.
视频点播

视频点播

复制全文
进阶功能
客户端超分
复制全文
客户端超分

客户端超分(Super Resolution, SR)功能,是利用设备端的高性能 AI 模型,实时增强视频画质的技术。该功能通过智能超分辨率算法,不仅能提升视频的分辨率,更能大幅增强画面的清晰度、锐度和内容细节,在不增加网络带宽消耗的前提下,为用户带来媲美原生高分辨率视频的观看体验。客户端超分主要适用于以下场景:

  • 增强超分,提升原生画质:对于本身清晰度较低的视频源(如用户上传的 UGC 内容),可在播放端进行实时画质增强。
  • 降档超分,优化传输成本:对于已有的高清视频,可在服务端先进行降档处理(如将 720p 降为 540p),从而降低视频传输的带宽和流量成本。在客户端播放时,再利用超分技术将其还原至接近原生 720p 的高清画质,实现在保证画质体验的同时降低成本。

效果体验

您可以前往官方 Demo 下载页面下载并安装 App。在播放设置页面开启超分功能后,即可直观体验该功能的效果。
Image

前提条件

在实现客户端超分功能前,请确保您已完成以下操作:

  • 获取 License:客户端超分为增值功能。请确保您购买的 License 为高级版,且已开通超分增值服务。详细步骤请见 License 管理
  • 集成高级版 SDK:参考集成 SDK 文档集成 1.45.3 或之后版本的高级版 SDK。
  • 完成基础的 SDK 初始化:参考集成 SDK快速开始文档完成项目的基本配置和 SDK 初始化。

核心实现流程

步骤 1:添加高级版 SDK 和超分模块依赖

在您 App 模块的 build.gradle 文件的 dependencies 代码块中,除了确保已集成高级版SDK 外,还需添加超分功能所必需的 ttbmf_lite 模块。

// app/build.gradle
dependencies {
    // 添加高级版 SDK 1.45.3 或之后版本
    // 将 x.x.x.x 替换为具体的版本号
    // implementation "com.bytedanceapi:ttsdk-player_premium:x.x.x.x"
    
    // 添加超分模块依赖
    // 将 x.x.x.x 替换为具体的版本号,需与高级版 SDK 保持一致
    implementation "com.bytedanceapi:ttsdk-ttbmf_lite:x.x.x.x" 
}

步骤 2:添加混淆规则

在您的 ProGuard 混淆配置文件中,添加以下规则,防止超分模块的相关类被混淆。

-keep class com.bytedance.bmf.** {*;}
-keep class com.bytedance.bmf_mods.** {*;}
-keep class com.bytedance.bmf_mods_api.** {*;}
-keep class com.bytedance.bmf_mods_lite_api.** {*;}
-keep class com.bytedance.bmf_mods_lite.** {*;}

步骤 3:初始化超分模块

超分模块的初始化是与播放器实例 TTVideoEngine 绑定的。您需要在创建播放器实例后、调用 play() 之前,为该实例完成超分的初始化配置。建议将初始化逻辑封装成一个独立的函数以便复用。

/**
 * 初始化指定播放器实例的超分功能
 *
 * @param context     应用上下文
 * @param videoEngine 需要开启超分的播放器实例
 * @param enableSr    起播时是否自动开启超分
 */
private static void initSuperResolution(Context context, TTVideoEngine videoEngine, boolean enableSr) {
    // 1. 创建超分模型所需的本地缓存目录
    final File root = new File(context.getCacheDir(), "bmf");    
    final File binDir = new File(root, "bin");
    final File cacheDir = new File(root, "cache");
    if (!binDir.exists()) binDir.mkdirs();
    if (!cacheDir.exists()) cacheDir.mkdirs();

    // 2. 构建超分配置 Bundle
    final Bundle bundle = new Bundle();
    bundle.putInt(TextureRenderKeys.KEY_IS_ACTION, TextureRenderKeys.TEXTURE_OPTION_INIT_EFFECT);
    bundle.putInt(TextureRenderKeys.KEY_IS_EFFECT_TYPE, TextureRenderKeys.TYPE_EFFECT_SUPPER_RESOLUTION);
    bundle.putInt(TextureRenderKeys.KEY_IS_USE_BMF_DIRECTINVOKE, 1);
    bundle.putInt(TextureRenderKeys.KEY_IS_USE_BMF_COMPONENT, 1);
    bundle.putInt(TextureRenderKeys.KEY_SR_ALG_TYPE, VideoSurface.SUPER_RES_STAT_BMF_SR_HP_V3_6);
    bundle.putInt(TextureRenderKeys.KEY_SR_BMF_BACKEND, VideoSurface.SUPER_RES_STAT_BMF_BACKEND_OPENGL);
    
    // 设置超分倍数:
    // 1.5 倍超分:VideoSurface.SUPER_SCALE_TYPE_1_5 (推荐)
    // 2.0 倍超分:VideoSurface.SUPER_SCALE_TYPE_2_0
    bundle.putInt(TextureRenderKeys.KEY_BMF_SCALE_TYPE, VideoSurface.SUPER_SCALE_TYPE_1_5);
    
    bundle.putInt(TextureRenderKeys.KEY_BMFSR_POOLSIZE, 2);
    bundle.putString(TextureRenderKeys.KEY_KERNEL_BIN_PATH, binDir.getAbsolutePath());
    bundle.putString(TextureRenderKeys.KEY_BMF_PROGRAM_CACHE_DIR, cacheDir.getAbsolutePath());
    
    // 3. 将配置应用到播放器实例
    // 注意:此方法必须在 openTextureSR 之前调用
    videoEngine.setEffect(bundle);
    
    // 4. 配置超分的行为限制和开关
    // 当视频分辨率的长边超过 1440 时,不开启超分,以避免性能问题
    videoEngine.setSrMaxTextureSize(1440, 1440);
    videoEngine.asyncInitSR(false);
    videoEngine.ignoreSRResolutionLimit(true);
    videoEngine.dynamicControlSR(true);
    
    // 5. 开启超分功能
    // SDK 内部有机型白名单限制,不在名单内的机型即使调用了此接口也不会实际开启超分
    // enableSr 参数决定了在调用 play() 后,是否立即应用超分效果
    videoEngine.openTextureSR(true, enableSr);
}

步骤 4:在播放场景中使用超分

在您的业务播放逻辑中,创建播放器实例后,调用上一步封装的 initSuperResolution 方法即可。

private Context mContext;
private TTVideoEngine mVideoEngine;

/**
 * 业务播放方法
 */
public void play() {
    if (mVideoEngine == null) {
        // 创建播放器实例
        mVideoEngine = new TTVideoEngine(mContext);
        // 设置播放源
        mVideoEngine.setStrategySource(source);
        // 为该实例初始化超分,并设置起播时自动开启
        initSuperResolution(mContext, mVideoEngine, true);
    }
    mVideoEngine.play();
}

/**
 * 检查当前视频是否已成功开启超分
 * @return true 表示正在使用超分,false 表示未使用
 */
public boolean isSuperResolutionEnabled() {
    if (mVideoEngine != null) {
        return mVideoEngine.isplaybackUsedSR();
    }
    return false;
}

/**
 * 在播放开始后,动态切换超分的开启状态
 * @param enabled true 开启超分, false 关闭超分
 */
public void setSuperResolutionEnabled(boolean enabled) {
    if (mVideoEngine != null) {
        // 第二个参数 `true/false` 决定了是开启还是关闭
        mVideoEngine.openTextureSR(true, enabled);
    }
}

进阶使用

结合预渲染策略使用

如果您使用 SDK 提供的预渲染策略,超分功能需要与预渲染流程正确结合,才能确保在命中预渲染缓存时也能正常工作。

为预渲染实例开启超分

通过实现 EngineStrategyListener,您可以在 SDK 创建预渲染播放器实例时,立即为其初始化超分。

/**
 * 初始化预渲染策略,并为预渲染的播放器实例开启超分
 * @param context 应用上下文
 */
public static void initPreRenderStrategy(final Context context) {
    TTVideoEngine.setEngineStrategyListener(new EngineStrategyListener() {
        @Override
        public TTVideoEngine createPreRenderEngine(final StrategySource source) {
             // SDK 回调此方法,要求创建一个用于预渲染的播放器实例
             final TTVideoEngine videoEngine = new TTVideoEngine(context);
             videoEngine.setStrategySource(source);
             
             // 关键:为这个即将用于预渲染的实例初始化超分
             initSuperResolution(context, videoEngine, true);
             
             return videoEngine;
        }
    });
}

未命中预渲染时为新实例开启超分

在您的业务播放逻辑中,需要判断是否命中了预渲染。在未命中预渲染、需要创建新播放器实例时,为播放器实例初始化超分。如果命中了预渲染,说明已为该实例开启过超分,无需重复操作。

private Context mContext;
private TTVideoEngine mVideoEngine;
private StrategySource mSource;
private VideoEngineCallback mCallback;

/**
 * 业务播放方法,实现了预渲染实例的复用逻辑,并正确处理超分初始化
 */
public void play() {
    if (mVideoEngine == null) {
        // 尝试从预渲染缓存中获取播放器实例
        final TTVideoEngine preRenderedEngine = TTVideoEngine.removePreRenderEngine(mSource.vid());
        
        if (preRenderedEngine == null) {
            // 场景:未命中预渲染
            // 创建一个新的播放器实例
            mVideoEngine = new TTVideoEngine(mContext);
            mVideoEngine.setStrategySource(mSource);
            // 关键:为这个新实例初始化超分
            initSuperResolution(mContext, mVideoEngine, true);
        } else {
            // 场景:命中预渲染
            // 直接复用已经配置好超分的预渲染实例
            mVideoEngine = preRenderedEngine;
            // 预渲染的播放器已处于 prepared 状态,这里可以手动补发一个 onPrepared 回调(如果业务逻辑依赖该回调)
            if (mCallback != null) {
                mCallback.onPrepared(mVideoEngine);
            }
        }
        mVideoEngine.setVideoEngineCallback(mCallback);
    }
    mVideoEngine.play();
}
最近更新时间:2026.01.05 11:06:25
这个页面对您有帮助吗?
有用
有用
无用
无用