You need to enable JavaScript to run this app.
文档中心
视频点播

视频点播

复制全文
下载 pdf
不含 UI 集成方案
基础功能
复制全文
下载 pdf
基础功能

本文为您介绍如何使用 Android 播放器 SDK 的基础功能。

播放控制

TTVideoEngine 提供了类似于 Android 系统 MediaPlayer 的播放控制的方法。

开始播放

调用 play 方法开始或恢复播放视频:

ttVideoEngine.play(); // 开始播放或恢复播放

暂停播放

调用 pause 方法暂停播放视频。再次调用 play 方法,状态可由暂停恢复到播放。示例代码如下:

ttVideoEngine.pause(); // 暂停播放
ttVideoEngine.play(); // 播放器由暂停恢复到播放状态

从指定时间起播

在调用 play 前通过 setStartTime 方法指定开始播放时间点,用于实现从指定时间开始播放或跳过片头等功能。示例代码如下:

注意

如果您使用预渲染功能,需在 prepare 前设置起播时间。

int startPlayPositionMS = 1000; // 单位 MS
ttVideoEngine.setStartTime(startPlayPositionMS); // 从 1 秒钟起播
ttVideoEngine.play();

Seek 到指定位置播放

调用 play 后,通过 seekTo 方法 Seek 到指定位置进行播放,实现拖拽进度条到指定时间开始播放的功能。示例代码如下:

/** 演示 seek 到 1 秒的位置 */
ttVideoEngine.seekTo(1000, new SeekCompletionListener() {
    @Override
    public void onCompletion(boolean success) {
        // seek 操作完成后回调。success 参数标识本次 seek 是否成功。true:成功
    }
});

ttVideoEngine.setVideoEngineInfoListener(new VideoEngineInfoListener() {
    @Override
    public void onVideoEngineInfos(VideoEngineInfos videoEngineInfos) {
        if (TextUtils.equals(videoEngineInfos.getKey(), VideoEngineInfos.USING_RENDER_SEEK_COMPLETE)) {
            // seek 渲染完成回调。
        }
    }
});

停止播放

调用 stop 方法停止播放视频:

ttVideoEngine.stop(); // 停止播放

说明

暂停播放和停止播放的区别在于:暂停播放后,调用 play 会恢复播放;停止播放后,调用 play 会重新起播。

释放播放器实例

调用 releaseAsync 方法异步释放播放器实例:

ttVideoEngine.releaseAsync(); // 异步释放播放器实例
boolean isReleased = ttVideoEngine.isReleased(); //获取释放状态
ttVideoEngine = null; // 防止再次调用

说明

  • 当播放器释放后,不应该再调用任何方法。
  • 释放后可以将 TTVideoEngine 设置为 null,防止再次调用。

纯音频播放

播放器 SDK 支持在播放视频时,只解码音频而不解码视频,适用于纯音频播放场景。相比您根据自身业务逻辑实现的纯音频播放,SDK 只解码音频会更省电。

注意

该功能仅高级版支持。请确保您已购买高级版的 License,详见播放器 License

// 开启纯音频播放
ttVideoEngine.setRadioMode(true);
// 恢复音视频播放
ttVideoEngine.setRadioMode(false);

播放 BASH 视频

SDK 支持 BASH(经火山引擎优化的升级版 DASH 协议)视频流的播放。播放前需开启以下 option:

ttVideoEngine.setIntOption(TTVideoEngineInterface.PLAYER_OPTION_ENABLE_DASH, 1);
ttVideoEngine.setIntOption(TTVideoEngineInterface.PLAYER_OPTION_ENABLE_BASH, 1);

开启 Texture Render

初始化播放器后,调用 play 前,通过 setIntOption 开启 Texture Render。示例代码如下:

ttvideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_USE_TEXTURE_RENDER, 1);

设置显示模式

Android 播放器 SDK 支持填充、旋转和镜像等显示设置。

填充模式

视频的比例播放控件的比例不一致,就会造成视频拉伸变形的问题。你可以通过设置 displayModedisPlayView 的参数来设置不同的显示模式。

方案 1:调整 View 尺寸(推荐)

注意

若采用此方案,disPlayView 的父布局必须采用 FrameLayout

// 无变形;等比例缩放;画面不被裁剪;可能有黑边
int displayMode1 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FIT;
// 可能会变形;画面宽高都充满控件;画面不被裁剪;无黑边
int displayMode2 = TTVideoEngineInterface.IMAGE_LAYOUT_TO_FILL;
// 无变形;等比例缩放;画面可能被裁剪;无黑边
int displayMode3 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FILL;
// 无变形;画面宽充满控件,高按视频比例适配;画面可能被裁剪;可能有黑边。
int displayMode4 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FILL_X;
// 无变形;画面高充满控件,宽按视频比例适配;画面可能被裁剪;可能有黑边。
int displayMode5 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FILL_Y;

// 即使开启 texturerender,也使用调整 View 尺寸
ttvideoEngine.setUseEngineDisplayMode(true);
View disPlayView = findViewById(R.id.textureView);
// View disPlayView = findViewById(R.id.surfaceView);

// 参数 disPlayView 传入显示画面的 TextureView 或 SurfaceView
ttvideoEngine.setDisplayMode(disPlayView, displayMode1);

横竖屏切换等视图尺寸变化时

// 横竖屏切换等 View 尺寸变化时,需在系统回调 onSizeChanged 里再次触发 View 尺寸调整。
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
   ttvideoEngine.setDisplayMode(disPlayView, displayMode1);
}

方案 2:调整纹理尺寸

注意

若采用此方案,必须开启 Texture Render

// 无变形;等比例缩放;画面不被裁剪;可能有黑边
int displayMode1 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FIT;
// 可能会变形;画面宽高都充满控件;画面不被裁剪;无黑边
int displayMode2 = TTVideoEngineInterface.IMAGE_LAYOUT_TO_FILL;
// 无变形;等比例缩放;画面可能被裁剪;无黑边
int displayMode3 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FILL;

ttvideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_USE_TEXTURE_RENDER, 1);
ttvideoEngine.setIntOption(TTVideoEngineInterface.PLAYER_OPTION_IS_RENDER_WHEN_SIZE_CHANGE, 1);
View disPlayView = findViewById(R.id.textureView);
// View disPlayView = findViewById(R.id.surfaceView);

// 参数 disPlayView 传入显示画面的 TextureView 或 SurfaceView
ttvideoEngine.setDisplayMode(disPlayView, displayMode1);

横竖屏切换等视图尺寸变化时

// 横竖屏切换等 View 尺寸变化时,需在系统回调 onSizeChanged 里再次触发纹理尺寸修改。
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
   ttvideoEngine.forceDraw();
}

旋转

按照以下步骤实现旋转功能:

  1. 初始化播放器后,调用 play 前,开启 Texture Render
  2. 调用 play 后,调用 setRotation 设置视频显示时的旋转角度。设置后,视频会顺时针旋转。示例代码如下:
    int rotation = 90; // 旋转角度仅支持 0°/90°/180°/270°,其他值无效
    ttvideoEngine.setRotation(rotation); // 设置视频显示时的旋转角度,在调用 `play` 后设置
    

镜像

调用 setMirrorHorizontalsetMirrorVertical 方法设置水平和垂直镜像。

// 设置水平镜像
boolean  mirrorHorizontal = true;
ttVideoEngine.setMirrorHorizontal(mirrorHorizontal);// 开启水平镜像
ttVideoEngine.setMirrorHorizontal(!mirrorHorizontal);// 关闭水平镜像
// 设置垂直镜像
boolean  mirrorVertical = true;
ttVideoEngine.setMirrorVertical(mirrorVertical);// 开启垂直镜像
ttVideoEngine.setMirrorVertical(!mirrorVertical);// 关闭垂直镜像

获取视频宽高

TTVideoEngine 触发 onPrepared 回调之后,调用 getVideoWidthgetVideoHeight 方法获取视频的宽高:

int videoWidth = ttVideoEngine.getVideoWidth();  //获取视频的宽
int videoHeight = ttVideoEngine.getVideoHeight(); // 获取视频的高

截图

  1. 初始化播放器后、调用 play 前,开启 Texture Render
  2. 调用 play 后,通过 snapshot 设置截图回调通知;调用 SnapshotListener 接口中定义的 onSnapShot 方法,通过回调函数来获取并处理视频截图位图、截图的宽度和高度。示例代码如下:
    mVideoEngine.snapshot(new SnapshotListener() {
        @Override
        public void onSnapShot(final Bitmap bitmap, final int with, final int height) {
    
            }
       });
    

获取播放信息

Android 播放器 SDK 支持获取当前播放进度、视频时长和缓存进度等信息。

获取当前播放进度

  • 调用 getCurrentPlaybackTime 方法获取当前播放位置:

    说明

    建议该方法的调用时间间隔 >= 200 ms。

    // 获取当前播放位置,单位 MS
    int currentPostion = ttVideoEngine.getCurrentPlaybackTime();
    
  • 通过 onCurrentPlaybackTimeUpdate 回调获取定时进度:

    // 通过设置进度回调间隔开启回调,play 之前设置
    ttVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_POSITION_UPDATE_INTERVAL, 200); 
    ttVideoEngine.setVideoEngineCallback(new VideoEngineCallback() {
        // ...省略其余实现方法
        @Override
        public void onCurrentPlaybackTimeUpdate(TTVideoEngine engine, int currentPlaybackTime) {
            Log.v("VideoPlay", "onCurrentPlaybackTimeUpdate " + engine + " " + currentPlaybackTime);
        }
    });
    

获取视频时长

TTVideoEngine 触发 onPrepared 回调之后,调用 getDuration 方法获取当前播放视频总时长。示例代码如下:

// 获取视频时长,单位 MS
int duration = ttVideoEngine.getDuration();

获取缓存进度

  • 调用 getLoadedProgress 方法获取缓存进度。示例代码如下:

    // 获取缓存进度,取值 1-100
    int loadedProgress = ttVideoEngine.getLoadedProgress();
    
  • 通过 onBufferingUpdate 回调获取缓存进度。示例代码如下:

    ttVideoEngine.setListener(new VideoEngineListener() {
      // ...省略其余实现方法
      @Override
      public void onBufferingUpdate(TTVideoEngine engine, int percent) {
          Log.v("VideoPlay", "onBufferingUpdate " + engine + " " + percent);
          // 缓存进度回调,可用于展示播放进度条上的二级缓存进度,取值 1-100
      }
    });
    

循环播放

调用 setLooping 方法并取值为 true 开启循环播放:

ttVideoEngine.setLooping(true); // 开启循环播放
ttVideoEngine.setLooping(false); // 关闭循环播放
boolean isLooping = ttVideoEngine.isLooping(); // 查询是否开启循环播放

倍速播放

调用 setPlaybackParams 方法设置倍速。默认值为 1,取值范围为 (0,3]。示例代码如下:

PlaybackParams params = new PlaybackParams();
params.setSpeed(1f); // 默认为 1 倍速,取值范围(0, 3]
ttVideoEngine.setPlaybackParams(params);

若需要播放倍速大于 3,需开启高倍速开关

// 请在 play/prepare 前设置
ttVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_ENABLE_PLAY_SPEED_EXTEND, 1);

设置音量

Android 播放器 SDK 支持音频焦点、调节音量和静音等音量设置的功能。

静音

调用 setIsMute 方法并取值为 true 实现静音。示例代码如下:

ttVideoEngine.setIsMute(true); // 静音
boolean isMute = ttVideoEngine.isMute(); // 获取是否静音

调节音量

调节音量包含调节系统音量、调节播放音量方式。

调用 setVolume 方法设置系统左右声道音量。示例代码如下:
float maxVolume = ttVideoEngine.getMaxVolume();  // 获取最大音量
float currentVolume = ttVideoEngine.getVolume(); // 获取当前音量
ttVideoEngine.setVolume(1f, 1f); // 设置左右声道音量,取值范围为 [0,maxVolume]

音频焦点

播放器 SDK 内部不处理音频焦点,需接入方需监听 AudioManager.OnAudioFocusChangeListener 来处理音频焦点的获取和释放。参考官方文档:管理音频焦点

Vid 播放源的多清晰度管理

Vid 模式下播放视频时,视频点播服务会下发多个清晰度的播放地址。播放器 SDK 通过 Resolution 枚举(详见清晰度枚举参考)来统一管理所有清晰度档位。

获取可用清晰度列表

在播放器成功获取视频信息后(即 onFetchedVideoInfo 回调触发后),可调用 supportedResolutionTypes() 方法获取当前视频支持的所有清晰度档位。

Resolution[] supportedResolutions;

ttVideoEngine.setVideoInfoListener(new VideoInfoListener() {
    @Override
    public boolean onFetchedVideoInfo(VideoModel videoModel) {
        if (videoModel != null) {
            // 获取清晰度数组,用于在 UI 上构建清晰度选择列表
            supportedResolutions = ttVideoEngine.supportedResolutionTypes();
        }
        return false;
    }
});

获取清晰度信息

在播放过程中的任何时刻,您都可以调用 getCurrentResolution() 获取当前正在播放的实际清晰度。
调用 getCurrentResolution 获取当前清晰度:

Resolution currentResolution = ttVideoEngine.getCurrentResolution();

切换清晰度

无论是设置起播清晰度,还是在播放中进行切换,都是通过调用 configResolution 方法实现。

设置起播清晰度

onFetchedVideoInfo 回调中,您可以根据业务逻辑(例如,优先使用用户上次的选择,或使用默认值)来设置初始播放的清晰度。

// 在 onFetchedVideoInfo 回调中设置起播
@Override
public boolean onFetchedVideoInfo(VideoModel videoModel) {
    // 假设我们希望以 360p 起播
    Resolution defaultResolution = Resolution.Standard;
    
    // 由于播放源不一定包含 360p,调用 findDefaultResolution 找到最接近的一个可用清晰度
    Resolution startResolution = TTVideoEngine.findDefaultResolution(videoModel, defaultResolution);
    
    if (startResolution != null) {
        ttVideoEngine.configResolution(startResolution);
    }
    return false;
}

播放中切换清晰度

当用户在 UI 界面上选择了一个新的清晰度时,直接调用 configResolution 即可。

// 假设用户从 UI 上点击了 resolutions 列表中的第 i 项
Resolution selectedResolution = supportedResolutions[i];

// 直接调用接口切换
ttVideoEngine.configResolution(selectedResolution);

// 监听切换结果
ttVideoEngine.setVideoEngineCallback(new VideoEngineCallback() {
    @Override
    public void onVideoStreamBitrateChanged(Resolution newResolution, int bitrate) {
        // 清晰度切换成功
        Log.d("VideoPlay", "Switched to " + newResolution);
    }

    @Override
    public void onError(Error error) {
        // 如果切换失败,可能会收到相关错误回调
    }
});

清晰度平滑切换

清晰度平滑切换(或称无缝切换)是指播放器在不同清晰度之间切换时,画面过渡平滑、无黑屏、无明显卡顿的技术。该功能依赖于视频源本身是帧对齐的。对于火山引擎视频点播服务转码生成的 MP4 和 HLS 视频,默认已实现帧对齐。

注意

如需了解如何转码生成帧对齐视频以及在 DirectUrl 模式下开启平滑切换功能,可提交工单联系火山引擎技术支持。

以下示例代码演示如何在 Vid 模式下开启平滑切换:

// 开启 HLS 平滑切换的核心开关
ttVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_ENABLE_HLS_SEAMLESS_SWITCH, 1); 
// 建议同时开启,以获得最佳的 Master M3U8 解析和调度性能
ttVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_ENABLE_MASTER_M3U8_OPTIMIZE, 1);

// MP4 播放源平滑切换
ttVideoEngine.setIntOption(PLAYER_OPTION_SEGMENT_FORMAT_FLAG, (1 << SEGMENT_FORMAT_FMP4) | (1 << SEGMENT_FORMAT_MP4));
ttVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_ENABLE_BASH, 1);

ttVideoEngine.setVideoEngineCallback(new VideoEngineCallback() {
    /**
     * 当码率(清晰度)发生变化时回调
     * @param resolution 切换后的清晰度枚举
     * @param bitrate 切换后的码率
     */
    @Override
    public void onVideoStreamBitrateChanged(Resolution resolution, int bitrate) {
        Log.d("VideoPlay", "Stream switched successfully to: " + resolution + ", bitrate: " + bitrate);
    }
});

播放 HLS 视频

设置过期时间

如果您通过 DirectUrl 方式播放 HLS 视频,在设置播放源和预加载时均可以通过 urlExpiredTimes 参数设置过期时间。

  • 设置播放源:在设置 DirectUrl 播放源时,创建 StrategySource 时传入过期时间,然后调用 setStrategySource 播放。示例代码如下所示:

    StrategySource directUrlSource = new DirectUrlSource.Builder()
            .setVid(vid)
            .addItem(new DirectUrlSource.UrlItem.Builder()
                    .setUrl(url)
                    .setCacheKey(cacheKey)
                    .setUrlExpires(new String[]{"xxx"}) // 单位为秒
                    .build())
            .build();
    mEngine.setStrategySource(directUrlSource); 
    
  • 预加载:在预加载播放场景下,您可在创建 DirectUrlSource 时,通过 setUrlExpires 传入过期时间,然后按照预加载流程调用 addTask 进行预加载。示例代码如下所示:

    DirectUrlSource directUrlSource = new DirectUrlSource.Builder()
        .setVid(vid)
        .addItem(new DirectUrlSource.UrlItem.Builder()
                .setUrl(url)
                .setCacheKey(cacheKey)
                .setUrlExpires(new String[]{"xxx"}) // 单位为秒
                .build())
        .build();
    PreloaderURLItem preloaderUrlItem =
            mFactory.createUrlItem(directUrlSource, preloadSize);
    preloaderUrlItem.setCallBackListener(new PreloadCallback(vid, this));
    TTVideoEngine.addTask(preloaderUrlItem);
    
  • 判断过期时间是否设置成功:可通过 Debug 调试状态下查看日志,确认播放地址中是否包含 hlsproxyQuery 关键字。示例如下:

    hlsproxyQuery=expirteTime%03Dxxxxxxxxxx
    

播放 HLS 标准加密视频

服务端配置

在实现客户端播放逻辑前,请确保已满足以下服务端配置:

  1. 完成服务端配置:已参照 HLS 标准加密文档完成解密服务搭建、加密转码等所有准备工作。
  2. 设置正确的 FileType:与播放普通视频的关键不同在于,您的应用服务端在调用 GetPlayInfo 接口获取播放地址或签发 PlayAuthToken 时,必须将 FileType 参数设置为 standard_evideo(加密视频)或 standard_eaudio(加密音频)。

客户端实现

在确保已满足上述服务端要求后,您可以根据播放方式和是否开启 HLS 加密改写,参考以下客户端实现。

在此场景下,客户端的播放代码与播放普通 Vid 视频完全相同,SDK 内部会自动处理解密流程。若您开启了 HLS 标准加密改写功能,需要额外设置 UrlExtendParams 参数传入鉴权参数 AppAuthToken

说明

若您开启 HLS 标准加密改写功能,在播放、下载和预加载的全链路中,都可以通过 urlExtendParams 参数传递 AppAuthToken

  • 播放时:在 VidPlayAuthTokenSource.Builder 中通过 setUrlExtendParams() 方法设置。
  • 下载时:在 DownloadVidTask 对象上通过 setUrlExtendParams() 方法设置。
  • 预加载时
    • 自定义预加载:在 PreloaderVidItem 对象上通过 setUrlExtendParams() 方法设置。
    • 预加载策略:您传递给预加载策略的 VidPlayAuthTokenSource 实例也必须设置 urlExtendParams 属性。策略会读取此属性并将其应用到内部创建的预加载任务中。
// 1. (按需配置) 准备您的鉴权参数 Map
// 如果开启了“HLS 标准加密改写”,请创建并填充此 Map。
// Map<String, String> authParams = new HashMap<>();
// authParams.put("AppAuthToken", "<your_token>");

// 2. 构造 Vid 播放源
VidPlayAuthTokenSource.Builder builder = new VidPlayAuthTokenSource.Builder()
        .setVid("your_hls_encrypted_vid")
        .setPlayAuthToken("your_play_auth_token");

// 3. (按需配置) 将鉴权参数设置给播放源
// 如果开启了“HLS 标准加密改写”,则执行此步骤。
// SDK 会自动将 Map 中的键值对转换为 URL 查询参数拼接到 M3U8 请求中。
// builder.setUrlExtendParams(authParams);

// 4. 构建播放源并播放
StrategySource vidSource = builder.build();
ttVideoEngine.setStrategySource(vidSource);
ttVideoEngine.play();

设置业务类型

业务类型(tag)用于区分同一应用(appid)内不同类型的音视频。可以根据业务需要按视频场景、视频时长等划分,比如沉浸式 feed 流、短视频视频、长视频等。调用 setTag 方法设置业务类型,代码示例如下所示。

ttVideoEngine.setTag("tag"); // 设置 Tag

设置子业务类型

子业务类型(subtag)用于区分同一业务类型下更为细分的音视频类型,比如加密视频、非加密视频、音频等。调用 setSubTag 方法设置子业务类型,代码示例如下所示。

ttVideoEngine.setSubTag("subtag"); //设置 SubTag

屏幕常亮

调用 View#setKeepScreenOn(boolean) 设置屏幕保持常亮,View#getKeepScreenOn 获取是否保持常亮。示例代码如下所示。

textureView.setKeepScreenOn(true); // 设置屏幕保持常亮
boolean isKeepScreenOn = textureView.getKeepScreenOn(); // 是否保持屏幕常亮

监听播放器事件

您可以通过设置 VideoEngineCallback 来监听播放器在整个生命周期中的各种状态和事件。设置监听的示例代码:

ttVideoEngine.setVideoEngineCallback(new VideoEngineCallback() {
    @Override
    public void onPlaybackStateChanged(TTVideoEngine engine, int playbackState) {
        Log.v("VideoPlay", "onPlaybackStateChanged " + engine + " " + playbackState);
        // 播放状态改变回调
        switch (playbackState) {
            case TTVideoEngine.PLAYBACK_STATE_PLAYING:
                // 开始播放
                break;
            case TTVideoEngine.PLAYBACK_STATE_ERROR:
                // 播放出错
                // Note:
                // 1.本消息不代表本次播放失败,内部重试后可能会恢复播放
                // 2.若最终播放失败,会在 VideoEngineListener#onError() 中回调
                break;
            case TTVideoEngine.PLAYBACK_STATE_STOPPED:
                // 播放停止
                break;
            case TTVideoEngine.PLAYBACK_STATE_PAUSED:
                // 播放暂停
                break;
            default:
                break;
        }
    }

    @Override
    public void onLoadStateChanged(TTVideoEngine engine, int loadState) {
        Log.v("VideoPlay", "onLoadStateChanged " + engine + " " + loadState);
        switch (loadState) {
            case TTVideoEngine.LOAD_STATE_PLAYABLE:
                // buffer end or renderStart
                break;
            case TTVideoEngine.LOAD_STATE_STALLED:
                // buffer start
                break;
            case TTVideoEngine.LOAD_STATE_ERROR:
                // load error
                break;
            default:
                break;
        }
    }

    @Override
    public void onVideoSizeChanged(TTVideoEngine engine, int width, int height) {
        Log.v("VideoPlay", "onVideoSizeChanged " + engine + " " + width + " " + height);
        // 播放器解析到视频宽高变化时回调
        // 对于像素比不是 1:1 的视频而言,width/height 不是最终渲染的宽高比
        // 最终渲染的宽高比需要结合 onSARChanged 回调中的 num 和 den 计算
        // displayAspectRatio = (num/(float)den) * (width/(float)height)
    }

    @Override
    public void onBufferingUpdate(TTVideoEngine engine, int percent) {
        Log.v("VideoPlay", "onBufferingUpdate " + engine + " " + percent);
        // 缓存进度回调,可用于展示播放进度条上的二级缓存进度
    }

    @Override
    public void onPrepare(TTVideoEngine engine) {
        Log.v("VideoPlay", "onPrepare " + engine);
        // prepare 时立刻回调
    }

    @Override
    public void onPrepared(TTVideoEngine engine) {
        Log.v("VideoPlay", "onPrepared " + engine + " isSystem " + engine.isSystemPlayer());
        // prepare 完成后回调
    }

    @Override
    public void onRenderStart(TTVideoEngine engine) {
        Log.v("VideoPlay", "onRenderStart " + engine);
        // 开始渲染时回调,可以认为此刻视频画面已经展示
    }

    @Override
    public void onStreamChanged(TTVideoEngine engine, int type) {
        Log.v("VideoPlay", "onStreamChanged " + engine + " " + type);
        // 音视频流变化通知
        // type 枚举:TTVideoEngine.VIDEO_STREAM/TTVideoEngine.AUDIO_STREAM
    }

    @Override
    public void onCompletion(TTVideoEngine engine) {
        Log.v("VideoPlay", "onCompletion " + engine);
        // 播放完成回调
    }

    @Override
    public void onError(Error error) {
        Log.v("VideoPlay", "onError " + error);
        // 播放失败回调
        // 错误码文档:https://www.volcengine.com/docs/4/66441/
        //播放失败后,内部会自动释放播放器
    }

    /**
     * 卡顿开始回调
     *
     * @param code 类型:
     * {@link VideoBufferDetailListener#BUFFERING_TYPE_NET} 网络卡顿
     * {@link VideoBufferDetailListener##BUFFERING_TYPE_DECODER} 解码卡顿
     *
     * @param afterFirstFrame 卡顿发生时机:
     * {@link VideoBufferDetailListener#BEFORE_FIRST_FRAME} 首帧前卡顿
     * {@link VideoBufferDetailListener#AFTER_FIRST_FRAME} 首帧后卡顿
     *
     * @param action 造成卡顿的 action:
     * {@link VideoBufferDetailListener#BUFFER_START_ACTION_NONE} 正常播放过程中卡顿
     * {@link VideoBufferDetailListener#BUFFER_START_ACTION_SEEK} seek
     * {@link VideoBufferDetailListener#BUFFER_START_ACTION_CHANG_RESOLUTION} 切换分辨率
     */
    @Override
    public void onBufferStart(int code, int afterFirstFrame, int action) {
        Log.v("VideoPlay", "onBufferStart " + code + ", " + afterFirstFrame + ", " + action);
        // buffer 开始,展示 loading
    }

    /**
     * 视频加载进度百分比回调
     * @param percent 缓冲进度百分比(0-99) 
     */
    public void onBufferPercentUpdate(int percent) {
    // 更新加载进度,percent 加载进度
    }
    
    /**
     * 卡顿结束回调
     * @param code
     * {@link VideoBufferDetailListener#BUFFERING_TYPE_NET} 网络卡顿
     * {@link VideoBufferDetailListener##BUFFERING_TYPE_DECODER} 解码卡顿
     */
    @Override
    public void onBufferEnd(int code) {
        Log.v("VideoPlay", "onBufferEnd " + code);
        // buffer 结束,隐藏 loading
    }

    @Override
    public void onSARChanged(int num, int den) {
        Log.v("VideoPlay", "onSARChanged " + num + ", " + den);
        // 视频 sample aspect ratio 回调,用于控制显示模式
        float sampleAspectRatio = num / (float) den;
    }
});

展示当前视频下载速度

播放器 SDK 支持回调当前视频一段时间内获取的视频数据大小,可用来在视频的起播、Seek、卡顿等情况下展示当前视频下载速度。实现的步骤和示例代码如下所示。

注意

该功能仅高级版支持。请确保您已购买高级版的 License,详见播放器 License

  1. 在初始化 SDK 前全局开启实时下载速度监听。

    // 全局开启实时下载速度监听,在初始化 SDK 前调用 
    TTVideoEngine.setIntValue(DATALOADER_KEY_INT_NEED_SPEED_TEST_BY_TIMEINTERNAL, 1);
    
    // 初始化 SDK
    Env.start(...);
    
  2. 设置单个实例测速时间间隔。

    // value 为测速时间间隔,单位 MS 推荐值 500 MS
    // 调用时机:设置播放源后调用
    ttVideoEngine.setCustomHeader("X-SpeedTest-TimeInternal", "500");
    
  3. 设置回调监听。

    // 设置回调监听
    TTVideoEngine.setDataLoaderListener(new DataLoaderListener());
    
    interface DataLoaderListener {
        ...
        /**
         * 
         * @param what == DATALOADER_KEY_NOTIFY_SPEEDINFO 时为网速回调
         * 此时:
         * code 为 netReadLen(单位 Byte)
         * parameter 为 netReadTime(单位 ms)
         * info 字段无需关注
         */
        public void  onNotify(int  what, long  code, long  parameter, String info) {
            if  (what == DataLoaderHelper.DATALOADER_KEY_NOTIFY_SPEEDINFO) {
                float  dataSize = code / 1024;
                float  time = (float) (parameter / 1000.0);
                float  speed = dataSize / time; // 单位 KB/s
                Log.d(TAG, "download speed = "  + speed);
            }
        }
    }
    

清除视频缓存

调用 clearAllCaches 方法清除视频缓存:

TTVideoEngine.clearAllCaches(true); // true 清除所有缓存;false LRU 保留最近 10 条缓存。

Seek 到最后一帧

在播放过程中,如果用户拖动进度条将视频快进到视频总时长 3 秒以内的位置,播放器会直接回调播放完成。如果您需要支持 Seek 到最后一帧,可通过如下方法配置:

mVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_ENABLE_SEEK_LASTFRAME,1);
mVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_ENABLE_SEEK_END,1);

主备地址容灾

为提升播放的稳定性和可靠性,播放器 SDK 提供 DirectUrl 模式的主备地址容灾功能。您可以设置一个主播放地址和一个备用播放地址。当主播放地址播放失败(如 DNS 解析失败、连接超时、收到 4xx/5xx 响应等)时,播放器内部会自动尝试切换到备用地址进行播放。

注意

1.35.1 及以上版本支持该功能。

  1. 在初始化前开启 DATALOADER_KEY_INT_ALLOW_TRY_THE_LAST_URL

    // 在 SDK 初始化之前,开启主备地址容灾的全局开关
    TTVideoEngine.setIntValue(DataLoaderHelper.DATALOADER_KEY_INT_ALLOW_TRY_THE_LAST_URL, 1);
    // 初始化 SDK
    Env.start(/* 省略 */);
    
  2. 构造包含主备地址的播放源:

    注意

    您提供的主地址和备用地址,都必须指向内容完全相同的视频文件。如果文件内容不一致,可能导致切换后出现播放花屏、进度错乱等异常。

    final String vid = "video id"; // 视频源与 vid 必须一一对应
    final String mainUrl = "http://www.example.com/h264.mp4"; // 主 URL
    final String backUpUrl = "http://www.examplebackup.com/h264.mp4"; // 备 URL
    // cacheKey 建议用 url 中不变的不分的 md5,比如 path 部分的 md5
    final String cacheKey = TTVideoEngine.computeMD5(mainUrl); 
    
    StrategySource directUrlSource = new DirectUrlSource.Builder()
            .setVid(vid)
            .addItem(new DirectUrlSource.UrlItem.Builder()
                    .setUrls(new String[]{mainUrl, backUpUrl})
                    .setCacheKey(cacheKey)
                    .build())
            .build();
    

设置播放失败重试次数

当播放发生错误时,播放器将尝试重新播放,直到达到最大重试次数。如果所有重试均失败,最终会触发 onError 回调。自 1.50.2.8 版本起,您可以通过 setIntOption 方法并设置 PLAYER_OPTION_MAX_ERROR_COUNT 的值来配置当前播放失败后的最大重试次数。如果未进行设置,播放器默认最多重试 3 次。

// 设置当前播放失败后最大重试次数为 3 次
ttVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_MAX_ERROR_COUNT, 3);

获取设备 ID

默认情况下,播放器 SDK 会自动生成唯一的设备 ID,您可在质量平台追查该设备 ID 的播放记录。参考以下代码获取设备 ID:

// 获取设备 ID
TTVideoEngine.getDeviceID()

说明

如果您自己已有一套独立的用户 ID 体系,希望通过用户 ID 来追查单个用户的单次播放行为,则可自定义用户 ID

设置网络超时时间

支持设置 SDK 的网络超时时间,推荐 10 秒。示例如下:

// 1. 打开全局开关,启用网络超时检测功能
// 设置 ALGO_OPTION_USE_ENGINE_NETWORK_TIMEOUT 为 1
TTVideoEngine.setIntValue(TTVideoEngine.ALGO_OPTION_USE_ENGINE_NETWORK_TIMEOUT, 1);

TTVideoEngine ttVideoEngine = new TTVideoEngine(context, TTVideoEngine.PLAYER_TYPE_OWN);
// 2. 为 engine 实例设置网络超时时间(秒)
// 本示例设置为 10 秒
ttVideoEngine.setIntOption(PLAYER_NETWORK_TIMEOUT, 10);
// 3. 关闭建连报错重试。在建立连接失败时,不进行重试
ttVideoEngine.setIntOption(PLAYER_OPTION_SET_ORIGINAL_RETRY, 0);
// 4. 关闭 engine 层播放失败重试。播放失败时,不进行重试
ttVideoEngine.setIntOption(PLAYER_OPTION_SET_MAX_ACCUMULATED_COUNT, 0);

生成 UnionInfo

UnionInfo 是播放端从设备中提取的用于标识访问或设备唯一性的信息。播放器 SDK 通过 UnionInfo 向应用服务端发起播放请求,应用服务端通过服务端 SDK 本地签发包含 UnionInfoPlayAuthToken 并下发给播放器 SDK,即可播放火山引擎私有加密视频。更多信息,请见火山引擎私有加密方案。您可通过以下代码生成 UnionInfo

String unionInfo = TTVideoEngine.getEngineUniqueId(context);

参考信息

清晰度枚举参考

Resolution 枚举如下表所示。

key

视频清晰度

音频清晰度

视频描述

音频描述

Standard

360p

medium

标清

普通音质

High

480p

higher

高清

高音质

SuperHigh

720p

highest

超清

音乐音质

ExtremelyHigh

1080p

original

1080P

原画

TwoK

2k

2K

此档位对音频不生效

FourK

4k

4K

此档位对音频不生效

Auto

自动调节

DASH 支持根据网速动态调节分辨率

此档位对音频不生效

更多文档

最近更新时间:2026.04.28 16:08:36
这个页面对您有帮助吗?
有用
有用
无用
无用