本文为您介绍如何使用 Android 点播 SDK 的基础功能。
TTVideoEngine
提供了类似于 Android 系统 MediaPlayer
的播放控制的方法。
调用 play
方法开始或恢复播放视频。示例代码如下所示。
ttVideoEngine.play(); // 开始播放或恢复播放
调用 pause
方法暂停播放视频。再次调用 play
方法,状态可由暂停恢复到播放。示例代码如下所示。
ttVideoEngine.pause(); // 暂停播放 ttVideoEngine.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 渲染完成回调。 } } });
在调用 play
前通过 setStartTime
方法指定开始播放时间点,实现从指定时间开始播放或跳过片头等功能。示例代码如下:
注意
如果您使用预渲染功能,需在 prepare
前设置。
int startPlayPositionMS = 1000; // 单位 MS ttVideoEngine.setStartTime(startPlayPositionMS); // 从 1 秒钟起播 ttVideoEngine.play();
调用 stop
方法停止播放视频。示例代码如下所示。
ttVideoEngine.stop(); // 停止播放
调用 releaseAsync
方法异步释放播放器实例。示例代码如下所示。
ttVideoEngine.releaseAsync(); // 异步释放播放器实例 boolean isReleased = ttVideoEngine.isReleased(); //获取释放状态 ttVideoEngine = null; // 防止再次调用
说明
TTVideoEngine
设置为 null
,防止再次调用。点播 SDK 支持在播放视频时,只解码音频而不解码视频,适用于纯音频播放场景。相比您根据自身业务逻辑实现的纯音频播放,SDK 只解码音频会更省电。
注意
该功能仅高级版或企业版支持。请确保您已购买高级版或企业版的 License,详见 License 包管理。
// 开启纯音频播放 ttVideoEngine.setRadioMode(true); // 恢复音视频播放 ttVideoEngine.setRadioMode(false);
Android 点播 SDK 支持填充、旋转和镜像等显示模式。
视频的比例和播放控件的比例不一致,就会造成视频拉伸变形的问题。你可以通过设置 displayMode
和 disPlayView
的参数来设置不同的显示模式。示例代码如下所示。
// 无变形;等比例缩放;画面不被裁剪;可能有黑边 int displayMode1 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FIT; // 可能会变形;画面宽高都充满控件;画面不被裁剪;无黑边 int displayMode2 = TTVideoEngineInterface.IMAGE_LAYOUT_TO_FILL; // 无变形;等比例缩放;画面可能被裁剪;无黑边 int displayMode3 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FILL; // 无变形;画面宽充满控件,高按视频比例适配;画面可能被裁剪;可能有黑边。开启 Texturerender 时不生效 int displayMode4 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FILL_X; // 无变形;画面高充满控件,宽按视频比例适配;画面可能被裁剪;可能有黑边。开启 Texturerender 时不生效 int displayMode5 = TTVideoEngineInterface.IMAGE_LAYOUT_ASPECT_FILL_Y; View disPlayView = findViewById(R.id.textureView); // View disPlayView = findViewById(R.id.surfaceView); // 参数 disPlayView 传入显示画面的 TextureView 或 SurfaceView // 参数 displayMode 值见下表 ttvideoEngine.setDisplayMode(disPlayView, displayMode1);
按照以下步骤实现旋转功能:
初始化播放器后,调用 play
前,通过 setIntOption
开启 Texture Render。示例代码如下:
// 在调用 `play` 前设置 ttvideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_USE_TEXTURE_RENDER, 1);
调用 play
后,调用 setRotation
设置视频显示时的旋转角度。设置后,视频会顺时针旋转。示例代码如下:
int rotation = 90; // 旋转角度仅支持 0°/90°/180°/270°,其他值无效 ttvideoEngine.setRotation(rotation); // 设置视频显示时的旋转角度,在调用 `play` 后设置
调用 setMirrorHorizontal
和 setMirrorVertical
方法设置水平和垂直镜像。
// 设置水平镜像 boolean mirrorHorizontal = true; ttVideoEngine.setMirrorHorizontal(mirrorHorizontal); // 设置垂直镜像 boolean mirrorVertical = true; ttVideoEngine.setMirrorVertical(mirrorVertical);
在 TTVideoEngine
触发 onPrepared
回调之后,调用 getVideoWidth
和 getVideoHeight
方法获取视频的宽高。示例代码如下:
int videoWidth = ttVideoEngine.getVideoWidth(); //获取视频的宽 int videoHeight = ttVideoEngine.getVideoHeight(); // 获取视频的高
初始化播放器后,调用 play
前,通过 setIntOption
开启 Texture Render。示例代码如下:
// 在调用 `play` 前设置 ttvideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_USE_TEXTURE_RENDER, 1);
调用 play
后,通过 snapshot
设置截图回调通知;调用 SnapshotListener
接口中定义的 onSnapShot
方法,通过回调函数来获取并处理视频截图位图、截图的宽度和高度。示例代码如下:
mVideoEngine.snapshot(new SnapshotListener() { @Override public void onSnapShot(final Bitmap bitmap, final int with, final int height) { } });
Android 点播 SDK 支持获取当前播放进度、播放时长、缓存进度和缓存进度回调等播放信息。
调用 getCurrentPlaybackTime
方法获取当前播放位置。示例代码如下所示。
int currentPostion = ttVideoEngine.getCurrentPlaybackTime(); // 当前播放位置获取,单位 MS
通过 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); } });
调用 getDuration
方法获取播放时长。示例代码如下所示。
int duration = ttVideoEngine.getDuration(); // 视频时长获取,单位 MS
调用 getLoadedProgress
方法获取缓存进度。示例代码如下所示。
int loadedProgress = ttVideoEngine.getLoadedProgress(); // 缓存进度获取,取值 1-100
通过 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); // 开启循环播放 boolean isLooping = ttVideoEngine.isLooping(); // 查询是否开启循环播放
调用 setPlaybackParams
方法设置倍速。默认值为 1,取值范围为(0,3]。示例代码如下所示。
PlaybackParams params = new PlaybackParams(); params.setSpeed(1f); // 默认为 1 倍速,取值范围(0, 3] ttVideoEngine.setPlaybackParams(params);
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
来处理音频焦点的获取和释放。参考官方文档:管理音频焦点。
使用 VideoID 视频源播放时,服务端会下发多个清晰度的播放地址。当播放器接收到 onFetchedVideoInfo
回调时,就可以调用 supportedResolutionTypes
方法获取到所有清晰度的 Resolution[]
数组。您可用该数组做清晰度列表的展示和清晰度逻辑选择。
调用 getCurrentResolution
方法获取当前清晰度。示例代码如下所示。
// 获取当前清晰度 Resolution currentResolution = ttVideoEngine.getCurrentResolution();
ttVideoEngine.setVideoInfoListener(new VideoInfoListener() { @Override public boolean onFetchedVideoInfo(VideoModel videoModel) { // 获取视频数据成功回调 Log.v("VideoPlay", "onFetchedVideoInfo " + videoModel); if (videoModel == null) return false; // 获取当前 VideoModel 的清晰度数组,可用于清晰度列表展示 Resolution[] resolutions = ttVideoEngine.supportedResolutionTypes(); return false; } });
设置起播清晰度:在播放之前预设值清晰度信息,起播设置清晰度可能不在支持清晰度列表,通过调用 findDefaultResolution
确定最终的启播清晰度。
// 默认清晰度 360p Resolution defaultResolution = Resolution.Standard; // VideoModel 中可能不包含 defaultResolution, 使用 findDefaultResolution 找出与 defaultResolution 最接近的清晰度。 Resolution resolution = TTVideoEngine.findDefaultResolution(videoModel, defaultResolution); // 设置选定的起播清晰度 ttVideoEngine.configResolution(resolution);
起播后,需要明确支持哪些清晰度的视频,切换指定清晰度档位。
// 获取当前可用的清晰度列表 Resolution[] resolutions = ttVideoEngine.supportedResolutionTypes(); // 确定要切换的清晰度,这里逻辑简写,业务根据自身逻辑选定相应的清晰度 Resolution resolution = resolutions[0]; // 设置选定的起播清晰度 ttVideoEngine.configResolution(resolution);
Resolution 枚举如下表所示。
key | 视频清晰度 | 音频清晰度 | 视频描述 | 音频描述 |
---|---|---|---|---|
Standard | 360p | medium | 标清 | 普通音质 |
High | 480p | higher | 高清 | 高音质 |
SuperHigh | 720p | highest | 超清 | 音乐音质 |
ExtremelyHigh | 1080p | original | 1080P | 原画 |
TwoK | 2k | 无 | 2K | 此档位对音频不生效 |
FourK | 4k | 无 | 4K | 此档位对音频不生效 |
Auto | 自动调节 | 无 | DASH 支持根据网速动态调节分辨率 | 此档位对音频不生效 |
通过不同方式播放 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
如果您通过 Vid 方式播放 HLS 视频,客户端无需额外设置,只需确保 GetPlayInfo 接口中返回的 VideoModel
包含过期时间信息即可。
业务类型(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(); // 是否保持屏幕常亮
监听播放状态的示例代码如下所示。
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 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 包管理。
在初始化 SDK 前全局开启实时下载速度监听。
// 全局开启实时下载速度监听,在初始化 SDK 前调用 TTVideoEngine.setIntValue(DATALOADER_KEY_INT_NEED_SPEED_TEST_BY_TIMEINTERNAL, 1); // 初始化 SDK Env.init(...);
设置单个实例测速时间间隔。
// value 为测速时间间隔,单位 MS 推荐值 500 MS // 调用时机:设置播放源后调用 ttVideoEngine.setCustomHeader("X-SpeedTest-TimeInternal", value);
设置回调监听。
// 设置回调监听 TTVideoEngine.setDataLoaderListener(new DataLoaderListener()); interface DataLoaderListener { ... /** * * @param what == DATALOADER_KEY_NOTIFY_SPEEDINFO 时为网速回调 * 此时,code 为 netReadLen(单位 Byte),parameter 为 netReadTime(单位 ms) */ public void onNotify(int what, long code, long parameter, String info) { if (what == DataLoaderHelper.DATALOADER_KEY_NOTIFY_SPEEDINFO) { float dataSize = code / 1024; float time = parameter / 1000; float speed = dataSize / time; // 单位 KB/s Log.d(TAG, "download speed = " + speed); } } }
调用 clearAllCaches 方法清除视频缓存:
TTVideoEngine.clearAllCaches(true); // true 清除所有缓存;false LRU 保留最近 10 条缓存。
在播放过程中,如果用户拖动进度条将视频快进到视频总时长 3 秒以内的位置,播放器会直接回调播放完成。如果您需要支持 Seek 到最后一帧,可通过如下方法配置:
mVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_ENABLE_SEEK_LASTFRAME,1); mVideoEngine.setIntOption(TTVideoEngine.PLAYER_OPTION_ENABLE_SEEK_END,1);
SDK 支持 DirectUrl 模式下设置多个域名的 URL 实现主备容灾。
注意
1.35.1 及以上版本支持此功能。
在初始化前开启 DATALOADER_KEY_INT_ALLOW_TRY_THE_LAST_URL
。
TTVideoEngine.setIntValue(DataLoaderHelper.DATALOADER_KEY_INT_ALLOW_TRY_THE_LAST_URL, 1); Env.init(/* 省略 */);
构造播放源:
注意
主备地址指向的文件必须是同一个文件。
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();
默认情况下,点播 SDK 会自动生成唯一的设备 ID,您可在质量平台追查该设备 ID 的播放记录。参考以下代码获取设备 ID:
// 获取设备 ID TTVideoEngine.getDeviceID()
说明
如果您自己已有一套独立的用户 ID 体系,希望通过用户 ID 来追查单个用户的单次播放行为,则可自定义设备 ID。