快速进阶
播放控制条
简单播放控制条可参考demo中的SimpleMediaController
类。该类由播放按钮、播放进度条等组成。
涉及到的接口有:
接口 | 功能 |
---|---|
long getDuration() |
获取视频时长,单位为毫秒 |
long getCurrentPosition |
获取当前播放位置,单位为毫秒 |
void seekTo(long milliSecond) |
切换到某处播放 |
start() |
开始播放 |
pause() |
暂停播放 |
OnBufferingUpdateListener |
监听,回调时返回已缓存时长占视频播放时长的百分比,根据该值更新二级进度条(缓存进度) |
boolean isPlaying() |
是否正在播放 |
高级设置接口
BDCloudMediaPlayer提供多个高级设置接口:
接口 | 功能 |
---|---|
setBufferSizeInBytes(int size) |
- 设置缓冲过程中,起播数据字节长度; - 即『加载中』缓冲字节数达到这个size后,回调BUFFERING_END; - 默认为 1*1024*1024,即1M,上限为4M; |
setBufferTimeInMs(int time) |
- 设置缓冲过程中,起播数据时长,单位为毫秒; - 即『加载中』缓冲数据可播放时长达到这个time后,回调BUFFERING_END; - 与上面的设置函数相关,以先达到者为准;默认为1*1000,即1秒上限为4秒。 |
setDecodeMode(int mode) |
设置解码模式,可以设置为 DECODE_AUTO(优先硬解,其次软解) 或者 DECODE_SW(软解),默认为DECODE_AUTO; |
setLogEnabled(boolean enable) |
- 设置开启播放器Logcat输出,默认为false; - 发布应用时,需保证该值为false; |
setMaxCacheSizeInBytes(int size) |
- 设置最大缓存区大小; - 默认为 5*1024*1024,即 5M,上限为5M。 - 下载数据领先于播放数据的大小。 |
setMaxProbeSize(int maxProbeSize) |
- 设置最大视频探测probe大小; - 默认为 1*1024*1024,即1M,上限为4M; |
setMaxProbeTime(int maxProbeTime) |
- 设置最大视频探测probe时长,单位为毫秒; - 默认为1*1000,即1秒,上限为4秒。 |
setVolume(float leftVolume, float rightVolume) |
设置左右声道的音量 |
setInitPlayPosition(long positionInMilliSeconds) |
设置初始播放位置 |
setTimeoutInUs(int timeout) |
设置建立连接和数据下载过程中超时时长,单位为微秒 |
setAudioDataCallback(OnReceiveAudioDataCallback callback) |
设置正在播放的音频回调 |
多码率有感切换
当播放的是HLS多码率视频时,播放器支持在播放过程中实时切换码率。
获取多码率视频(Master M3U8)的index数目
String[] getVariantInfo()
- 该variantinfo直接从Master m3u8文件中取值,根据(#EXT-X-STREAM-INF)格式的不同,取到的值可能为:
1920x1080,3541000
也可能为,232370
(不规范的视频)。逗号前是分辨率,逗号后是码率; - 数组的大小即为多码率的数目;
选择多码率
播放过程中,选择多码率:
mMediaPlayer.selectResolutionByIndex(index);
该函数会使得player内部的状态变化stop --> prepareAsync --> prepared
。
BDCloudMediaPlayer还开放了selectVariantByIndex
接口。该接口不帮忙维护mediaplayer状态。如果想使用该接口,需要保证在prepareAsync
之前调用。
多码率无缝切换
播放器不仅支持HLS的多码率快速切换,同时也支持MP4等主流媒体格式的无缝切换功能。具体操作如下:
Master playlist 的HLS格式多码率无缝切换
- 设置输入格式:
mMediaPlayer.setMediaInputType(mode)
。 - 在
PlayerState.STATE_PREPARED
状态后,调用mMediaPlayer.getMediaItems()
获取多码率信息列表,更新UI。 - 用户根据对应索引切换到指定码率:
mMediaPlayer.selectMediaByIndex(index)
。 - 当收到
IMediaPlayer.MEDIA_INFO_MEDIA_CHANGE_START
通知表示视频开始切换。 - 当收到
IMediaPlayer.MEDIA_INFO_MEDIA_CHANGE_END
通知表示切换结束,同时可以取extra值判断切换是否成功。此时播放器缓冲播放完成后即会切换到新的码率显示。 - 当收到
onVideoSizeChanged(...)
回调表示视频分辨率发生变化。
MP4等非嵌套码率的无缝切换
- 设置输入格式:
mMediaPlayer.setMediaInputType(mode)
。 - 设置多码率视频链接(注意这里和HLS的区别):
mMediaPlayer.setMediaItems(mediaItems)
。 - 在
PlayerState.STATE_PREPARED
状态后,调用mVideoView.getMutilMediasDsc()
获取多码率信息列表,更新UI。 - 用户根据对应索引切换到指定码率
mMediaPlayer.selectMediaByIndex(index)
。 - 当收到
IMediaPlayer.MEDIA_INFO_MEDIA_CHANGE_START
通知表示视频开始切换。 - 当收到
IMediaPlayer.MEDIA_INFO_MEDIA_CHANGE_END
通知表示切换结束,同时可以取extra值判断切换是否成功。此时播放器缓冲播放完成后即会切换到新的码率显示。 - 当收到
onVideoSizeChanged(...)
回调表示视频分辨率发生变化。
播放HLS加密视频
百度智能云MCP服务和VideoWorks服务支持转码成HLS加密视频。
不同的加密方式,播放时的方法略有不同:
-
PlayerBinding加密模式
-
Token模式(推荐)
Token模式是PlayerBinding模式的升级版,根据约定的token进行更加安全地播放。
token需要您的服务器与百度智能云服务器合作来生成,您的App从您的服务器拿到token后,设置给播放器即可。 prepare之前需要先设置token
:mMediaPlayer.setDecryptTokenForHLS(mDrmToken);
HLS视频下载
播放器支持对M3U8视频进行下载和管理。
下载管理器
下载管理器以单例的形式提供:
globalVideoDownloadManager = VideoDownloadManager.getInstance(context, userName);
其中userName仅用于做下载记录的区分,不要求为实际用户名,可以是实际用户名的加密串或签名串。
下载步骤
- 调用
globalVideoDownloadManager = VideoDownloadManager.getInstance(context, userName)
获得下载管理单例。 -
调用
globalVideoDownloadManager.startOrResumeDownloader(url, observer)
启动下载任务。函数原型:
public void startOrResumeDownloader(String url, DownloadObserver observer)
public void startOrResumeDownloaderWithToken(String url, String token, DownloadObserver observer) // 下载加密视频
此后也可调用暂停(pauseDownloader
)、恢复(startOrResumeDownloader
)、删除(deleteDownloader
)、批量停止(stopAll
)等接口对下载任务进行管理。
其中,在启动下载时,若想实时监听下载进度及状态,可继承DownloadObserver
类并实现update
方法,将该类的实例传给startOrResumeDownloader
即可实时监听。不想实时监听,startOrResumeDownloader
方法的第二个参数可传null。
public void update(DownloadableVideoItem downloader)
-
实时获取下载任务的信息
任务下载过程中,回调
update(DownloadableVideoItem downloader)
,实时获取下载状态。downloader对象可获得下述方法:
方法 | 描述 |
---|---|
getUrl() | 获取单个下载的url |
getLocalAbsolutePath() | 获取下载文件的本地绝对路径 |
getProgress() | 获取下载进度 |
getStatus() | 获取下载状态(枚举类DownloadStatus) |
getErrorCode() | 下载状态为Error的时候,通过该接口获取错误码 |
getFailReason() | 获取下载失败或中止的简单描述 |
注意: 错误码如DownloadableVideoItem.ERROR_CODE_INVALID_URL等
其中,发生错误时的错误码如下表:
错误码 | 描述 |
---|---|
ERROR_CODE_NO_ERROR | 无错误 |
ERROR_CODE_INVALID_URL | 地址无效 |
ERROR_CODE_NETWORK_FAILED | 网络问题 |
ERROR_CODE_SDCARD_UNMOUNTED | 本地存储问题 |
ERROR_CODE_M3U8_\INVALID_FORMAT | m3u8格式问题 |
ERROR_CODE_M3U8_SAVE_FAILED | m3u8存储问题 |
ERROR_CODE_M3U8_DRM_INVALID | drm保护相关key或者token无效 |
ERROR_CODE_TS_SAVE_FAILED | ts文件保存失败 |
-
通过URL查找下载任务
通过
downloadableVideoItem = globalVideoDownloadManager.getDownloadableVideoItemByUrl(url)
获得下载任务item,以便访问item中的信息。通过
globalVideoDownloadManager.getAllDownloadableVideoItems()
获得所有下载单元,可以从中选择出未下载完成的任务,启动继续下载(startOrResumeDownloader(oneItem.getUrl(), null)
),即可实现断点续传。 - 下载成功后,
DownloadableVideoItem#getLocalAbsolutePath
方法拿到本地视频文件全路径,传给播放器进行本地播放即可。
预下载/边播边缓存
代理缓存器支持MP4视频的预下载和边播边存
设置视频预下载/边播边缓存步骤
// 获取缓存代理管理器
mProxyCacheManager = ProxyCacheManager.getInstance();
// 获取播放代理链接
String proxyPath = mProxyCacheManager.getProxyUrl(mAppContext, path);
// 设置缓存进度监听器
mProxyCacheManager.setCacheAvailableListener(cacheListener);
// 将代理链接设置给播放器
setVideoURI(proxyPath);
// 反注册缓存监听器,释放资源
mProxyCacheManager.release();
详细代码参见demo中的BDCloudVideoView.java
。
边播边录制
// 创建录制控制器
mRecordController = new RecordController();
// 初始化录制控制器
mRecordController.init(mNewSurfaceTexture,RecordConstants.VIDEO_ENCODE_FRAME_RATE,RecordConstants.DEFAULT_BIT_RATE_GTE_API18)
// 设置渲染回调
mVideoRender.setRenderList(mRecordController.getRenderCallbackList());
// 设置录制尺寸
mRecordController.setRecordSize(mWidth, mHeight);
// 开始录制
mRecordController.startRecord(filePath);
// 设置录制监听
mRecordController.setRecordListener(listener);
// 停止录制
mRecordController.stopRecord();
详细代码参见demo中BDCloudView.java , TextureRenderView.java
。
外挂字幕
通过下面的接口可以添加外挂字幕,当前支持的字幕格式包括srt\ssa\ass\webvtt。需要注意的是,该接口需要在收到播放器onPrepared回调后调用,并且对于同一个播放器,同一时刻仅能添加一个外挂字幕轨道,添加新的外挂字幕会自动代替旧的外挂字幕。
// extSubUrl对应外挂字幕地址
public void addExtSubtitleUrl(String extSubUrl);
在播放内核中,当外挂字幕成功读取后,会通过下面的回调进行通知
private final IMediaPlayer.OnExtSubtitleOpenListener mExtSubtitleOpenListener =
new IMediaPlayer.OnExtSubtitleOpenListener() {
@Override
public void onExtSubtitleOpen(IMediaPlayer mp, String url) {
// 外挂字幕打开
}
};
具体的字幕内容也会在IMediaPlayer.OnTimedTextListener
中回调,这一点与内嵌字幕相同。
多音轨、多字幕切换
对于带有多个音轨、字幕轨的片源,可以通过下面的方式实现轨道的无缝切换。
- 先利用下面的接口获取当前片源所有的轨道信息
public @Nullable BDCloudTrackInfo[] getTrackInfo();
在BDCloudTrackInfo
类中记录了每个轨道的媒体类型和语言信息。
- 根据轨道信息数组的下标进行切换
利用下面的接口可以执行轨道的选择和反选,传入的参数即对应第一步获取的轨道信息数组下标。
public void selectTrack(int track);
public void deselectTrack(int track);
- 查询当前选择的轨道
利用下面的接口可以获取当前选中的视频/音频/字幕轨,返回参数也对应第一步获取的轨道信息数组下标。
public int getSelectedTrack(@ITrackInfo.TrackType int trackType)
- 轨道变化回调
轨道的添加、切换都会通过下面的回调进行通知,其中action对应轨道添加或切换事件,type对应轨道类型,trackid则对应轨道序号。
interface OnTrackChangedListener {
void onTrackChanged(IMediaPlayer mp,
@ITrackInfo.TrackAction int action,
@ITrackInfo.TrackType int type,
int trackid);
}
- 无缝切换与有感切换
播放器默认使能轨道的无缝切换(切换过程中无缓冲状态),如果需要切换为有感切换,可以在prepareAsync
之前设置下面的选项来实现
setOption(OPT_CATEGORY_PLAYER, "enable-smooth-track-change", 0);
AV1解码支持
在播放器SDK流媒体版中,依赖系统硬解和系统软解能力实现对AV1编码格式的支持,如果系统不具备AV1解码能力,则通过OnErrorListener
接口回调IMediaPlayer.MEDIA_ERROR_VIDEO_DECODER_NOT_SUPPORTED
错误。
在播放器SDK全媒体版中,集成了单独的AV1软件解码器,此时的解码器选择顺序为:优先选择系统硬件解码,否则使用AV1软件解码。
常见错误码含义
常见错误码分为播放内核错误、鉴权错误、其他错误三类,具体定义和含义解释可以参考Demo工程CommonUtils.java
中getReadableErrorMsg
方法的实现。