You need to enable JavaScript to run this app.
导航
进阶功能
最近更新时间:2025.02.18 10:42:47首次发布时间:2024.10.17 11:29:26

本文为您介绍如何使用 Flutter 点播 SDK 的进阶功能。

短视频场景预加载和预渲染策略

为了帮助您快速搭建“抖音”同款短视频场景,点播 SDK 基于抖音亿级日活跃用户的真实反馈和大规模实践经验,提供两大最佳策略:预加载策略预渲染策略。详细功能介绍,请见抖音同款短视频最佳实践

注意

该功能仅高级版或企业版支持。请确保您已购买高级版或企业版的 License,详见 License 包管理

接入预加载策略

// 方法定义见 TTVideoEngineStrategy
// 开启预加载策略,建议在进入短视频页面开启
TTVideoEngineStrategy.enableEngineStrategy(
          strategyType: TTVideoEngineStrategyType.preload, scene: TTVideoEngineStrategyScene.smallVideo);
          
// 设置预加载列表
static Future<void> setStrategyVideoSources({required List<TTVideoEngineMediaSource> videoSources})

// 更新预加载列表
static Future<void> addStrategyVideoSources({required List<TTVideoEngineMediaSource> videoSources})
    
// 关闭全部策略
TTVideoEngineStrategy.clearAllEngineStrategy();

接入预渲染策略

// 方法定义见 TTVideoEngineStrategy
// 开启预渲染策略,建议在进入短视频页面开启
TTVideoEngineStrategy.enableEngineStrategy(
          strategyType: TTVideoEngineStrategyType.preRender, scene: TTVideoEngineStrategyScene.smallVideo);
          
// 设置和更新预渲染列表和预加载列表。仅需设置一次

// (可选)监听预渲染播放器完成回调,在回调内对预渲染播放器进行起播前配置(如 HLS 选档、硬解配置等),示例如下:
TTVideoEngineStrategy.init();
TTVideoEngineStrategy.onCreatePreRenderEngine = ((source) async {
        VodPlayerFlutter player = VodPlayerFlutter();
        String coreHashHex = await player.createPlayer(vid: source.getVid, preCreated: true);
        player.setUrlSource(source as TTVideoEngineUrlSource);
        player.setHLSMultiBitrateConfig(
          selectHlsVideoStream: () {
            return 800 * 1024;
          },
          selectHlsRendition: (variantIndex) {
            return 0;
          },
        );
        player.setHardwareDecode(GlobalConfiguration.isHardwareDecode);
        player.setTrackVolumeEnabled(GlobalConfiguration.isTrackVolume);
        player.setCustomHeader('x-tt-flutter-test-demo', '1');
        return player;
});

自定义预加载

预加载是指在开始播放之前提前下载即将播放视频的头部数据,以实现快速起播,从而显著优化播放体验。详细功能介绍,请见 Android 自定义预加载

注意

该功能仅高级版或企业版支持。请确保您已购买高级版或企业版的 License,详见 License 包管理

实现自定义预加载的步骤如下:

  1. 构造播放源并添加预加载任务。Vid 模式和 DirectUrl 模式的示例代码具体如下:

    // 使用vid和playAuthToken初始化vid source, resolution为期望预加载的档位
       TTVideoEngineVidSource source = TTVideoEngineVidSource.init(
               vid: <vid>,
               playAuthToken: <playAuthToken>,
               resolution: <TTVideoEngineResolutionType>);
       
       // 使用sourcec和preloadSize初始化PreloaderVidItem, 预加载字节数preloadSize默认800K 
       TTVideoEnginePreloaderVidItem item = TTVideoEnginePreloaderVidItem.vidItemWithVideoSource(source, 800 * 1024);
       
       // 添加预加载任务
       TTVideoEnginePreload.addTaskWithVidItem(item);
    
  2. 取消预加载任务:

    // 取消全部预加载任务
    TTVideoEnginePreload.cancelAllTask();
    
    // 根据key取消一个预加载任务,key为创建预加载任务使用的cacheKey
    TTVideoEnginePreload.cancelTaskByKey(Key);
    
  3. 监听预加载任务状态:

    // 对已添加的预加载任务PreloaderURLItem,监听item的cancel和end回调
    // 预加载任务取消
    item.onPreloadCancel = () {
        print('TTF --  预加载cancel 回调到dart');
    };
     
    // 预加载任务完成
    // taskInfo - 预加载任务的文件信息和下载信息
    // error - 预加载任务的error信息
    item.onPreloadEnd = (TTVideoEngineLocalServerTaskInfo? taskInfo, TTError? error) {
        Map<dynamic, dynamic>? map = taskInfo?.toJson();
        String errorStr = error.toString();
        print('TTF --  预加载end 回调到dart end = $map error = $errorStr');
    };
    

master.m3u8 档位切换

注意

该功能仅 Android 支持。

起播前档位选择

// 方法定义在 VodPlayerFlutter
/* 
  master-m3u8 起播前档位选择
  getHlsStreamInfos - 档位回调
  selectHlsVideoStream - 视频档位选择, 返回视频stream的bandwidth
  selectHlsRendition - 音轨选择,返回音频rendition的infoId
  switchHlsVideoBitrate - 档位选择回调, 如发生档位切换,回调选择档位的bandwidth
 */
Future<void> setHLSMultiBitrateConfig(
    {void Function(TTMasterPlaylist playlist)? getHlsStreamInfos,
    int? Function()? selectHlsVideoStream,
    int? Function(int variantIndex)? selectHlsRendition,
    void Function(int bitrate)? switchHlsVideoBitrate})
      
// 示例代码 (以随机档位为例,仅做参考)
_player?.setHLSMultiBitrateConfig(
    getHlsStreamInfos: (TTMasterPlaylist playlist) {
      _playlist = playlist;
      print('HLS档位回调:${playlist.toJson()}');
    },
    selectHlsVideoStream: () {
      // 示例选择档位随机
      if (_playlist!.variantStreams!.isNotEmpty) {
        int index = Random().nextInt(_playlist!.variantStreams!.length);
        TTMasterVariantStream stream = _playlist!.variantStreams![index];
        print('HLS视频起播档位选择, 随机index=$index, resolution-${stream.resolution} bandwidth-${stream.bandwidth}');
        return stream.bandwidth;
      }
      return -1;
    },
    selectHlsRendition: (int variantIndex) {
      // 示例选择音轨 'en'
      for (TTMasterRendition rendition in _playlist!.renditions!) {
        if (rendition.variantIndex != variantIndex) {
          continue;
        }
        if (rendition.language == 'en') {
          print('HLS音频起播档位选择, rendition.language=${rendition.language}, rendition.infoId-${rendition.infoId}');
          return rendition.infoId;
        }
      }
      return -1;
    },
    switchHlsVideoBitrate: (int bitrate) {
      print("HLS选择档位完成 最终bitrate = $bitrate");
    },
);

播放中档位选择

// 播放中切换 hls 视频档位,如传入的bitrate档位不存在,选择最接近的档位
Future<void> switchHlsVideoBitrate({required int bitrate})

// 播放中切换 hls 音轨,如传入的 audioInfoId 不存在,不切换
Future<void> switchHlsAudioRendition({required audioInfoId})

预加载档位选择

// 方法定义在 TTVideoEnginePreload
/* 
  master-m3u8起播前档位选择
  getHlsStreamInfos - 档位回调
  selectHlsVideoStream - 视频档位选择, 返回视频stream的bandwidth
  selectHlsRendition - 音轨选择,返回音频rendition的infoId
  switchHlsVideoBitrate - 档位选择回调, 如发生档位切换,回调选择档位的bandwidth
 */
Future<void> setHLSMultiBitrateConfig(
    {void Function(TTMasterPlaylist playlist)? getHlsStreamInfos,
    int? Function()? selectHlsVideoStream,
    int? Function(int variantIndex)? selectHlsRendition,
    void Function(int bitrate)? switchHlsVideoBitrate})
      
      
// 示例代码 (以随机档位为例,仅做参考)
TTVideoEnginePreload.setMasterPlaylistPreloaderCallback(
    onMasterM3U8PlaylistSelectPreloadUrls: (TTMasterPlaylist playlist) {
  if (playlist.variantStreams!.isEmpty) {
    return null;
  }
  List<TTMasterPreloadURLInfo> urlInfos = [];

  // 预加载视频流
  int index = Random().nextInt(playlist.variantStreams!.length);
  TTMasterVariantStream stream = playlist.variantStreams![index];
  TTMasterPreloadURLInfo urlInfo = TTMasterPreloadURLInfo(uri: stream.uri, preloadSize: 800 * 1024);
  urlInfos.add(urlInfo);
  print('预加载playlist 随机视频流uri=${stream.uri}, resolution=${stream.resolution} bandwidth=${stream.bandwidth}');

  // 预加载音频流
  if (playlist.renditions == null) {
    return urlInfos;
  }

  for (TTMasterRendition rendition in playlist.renditions!) {
    if (rendition.groupId == stream.audioGroupId) {
      TTMasterPreloadURLInfo urlInfo = TTMasterPreloadURLInfo(uri: rendition.uri, preloadSize: 500 * 1024);
      urlInfos.add(urlInfo);
      print('预加载playlist音频流uri=${rendition.uri}');
    }
  }
  return urlInfos;
});

外挂字幕

外挂字幕是指字幕文件与视频文件分开存储,用户在播放视频时按需导入字幕文件。点播 SDK 当前支持添加 WebVTT (Web Video Text Tracks) 格式的字幕文件。这种方式的优势在于其灵活性,用户可以根据实际需求选择是否导入字幕文件,或者选择加载不同语言的字幕。更重要的是,您无需进行额外的视频转码,只需要在播放端进行适当设置,便可显示字幕。本文为您介绍使用点播 SDK 时如何添加外挂字幕。

注意

该功能仅高级版或企业版支持。请确保您已购买高级版或企业版的 License,详见 License 包管理

前提条件

如果您通过 Vid 方式播放视频,需要准备字幕文件:

  • 如果您已有单独的字幕文件,可选择在视频点播控制台指定空间内的视频管理 > 视频详情页面上传字幕文件,如下图所示:
    Image
  • 如果您没有单独的字幕文件,可通过视频点播媒体处理服务生成字幕文件,具体请见生成和使用字幕

开启外挂字幕功能

参考以下示例代码开启外挂字幕功能:

// 开启外挂字幕
Future<void> setSubtitleEnabled(bool enabled) // prepare 之前调用

设置字幕源

点播 SDK 支持以下两种方式设置字幕源。您需根据实际情况选择。

使用 Vid + SubtitleToken 方式

使用 Vid + SubtitleToken 方式设置字幕源的示例代码如下:

说明

您可在应用服务端通过视频点播服务端 SDK 签发字幕鉴权 Token

// 设置  Vid 字幕源
Future<void> setSubtitleAuthToken(String subtitleAuthToken)

使用 DirectURL 方式

使用 DirectURL 方式设置字幕源的示例代码如下:

// 设置  DirectURL 字幕源
// createPlayer 之后,prepare 之前调用
Future<void> setSubtitles(List<TTSubtitle> subtitles)

控制字幕

开启/关闭字幕输出

参考以下示例代码在起播时或者播放过程中控制开启或者关闭字幕输出:

// 开启或者关闭字幕
// createPlayer 之后调用
Future<void> setSubtitleShow(bool enabled)

切换字幕

参考以下示例代码在起播时或者播放过程中切换字幕:

// 切换字幕
// createPlayer 之后调用
Future<void> setSelectedSubtitle(int subtitleId); 

设置字幕回调

参考以下示例代码接收字幕回调。设置字幕回调前需要先调用 setSubtitleShow(true) 开启字幕显示。

// vid + subTitleToken 播放,字幕列表信息回调
Future<void> Function(bool success, List<TTSubtitle>? subtitles, TTError? error)? onSubtitlesFetched;

// 字幕文件加载结果回调
Future<void> Function(bool success)? onSubtitleFileLoadResult;

// 字幕语言切换回调
Future<void> Function(bool success, int subtitleId)? onSubtitleSelected;

// 字幕信息回调
Future<void> Function(String? content, double pts, double duration)? onSubtitleShow;