实现播放功能
更新时间: 2024/09/25 10:51:58
本文介绍如何实现音视频媒体播放功能。
播放功能的调用时序如下图所示。
sequenceDiagram
participant App
participant 播放器SDK
App->>播放器SDK: 1.初始化播放器(init)
App->>播放器SDK: 2.创建播放器实例(create)
App->>播放器SDK: 3.监听播放器的相关通知
App->>播放器SDK: 4.将显示图层添加到需要显示的页面上(setDisplay、setSurface)
App->>播放器SDK: 5.设置播放模式、解码类型、播放地址等静态参数(setBufferStrategy、setHardwareDecoder等)
App->>播放器SDK: 6.调用prepareAsync预处理视频源
播放器SDK-->>App: 7.onPrepared回调通知预处理完成
App->>播放器SDK: 8.调用start进行播放(如果设置了setShouldAutoplay,可以不用调用start)
App->>播放器SDK: 9.播放过程中根据需要设置动态参数(setVolume、seekTo等)
App->>播放器SDK: 10.调用release释放播放器
1. 初始化播放器
调用 init
方法初始化播放器。
参数说明如下表所示。
参数 | 类型 | 说明 |
---|---|---|
context | Context | 上下文信息,请使用ApplicationContext传入 |
config | NESDKConfig | SDK 配置信息。 |
示例代码
java NESDKConfig config = new NESDKConfig();
//如果需要应用层上报播放数据,那么设置dataUploadListener,默认SDK内部上报播放数据
config.dataUploadListener = mOnDataUploadListener;
NELivePlayer.OnDataUploadListener mOnDataUploadListener = new NELivePlayer.OnDataUploadListener() {
@Override
public boolean onDataUpload(String url, String data) {
LogUtil.d(TAG, "onDataUpload url:" + url + ", data:" + data);
return true;
}
@Override
public boolean onDocumentUpload(String url, Map<String, String> params, Map<String, String> filepaths) {
LogUtil.d(TAG, "onDataUpload url:" + url + ", params:" + params+",filepaths:"+filepaths);
return true;
}
};
2. 创建播放器实例
调用 create
方法创建播放器实例。
示例代码
javaprivate NELivePlayer mLivePlayer = null;
mLivePlayer = NELivePlayer.create();
3. 设置监听
设置 listener
对播放过程进行监听,并根据监听结果做出相应的处理。
示例代码
java//注册一个回调函数,在视频预处理完成后触发
mLivePlayer.setOnPreparedListener(mPreparedListener);
//注册一个回调函数,在视频大小发生变化时触发
mLivePlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
//视频播放完成的监听器
mLivePlayer.setOnCompletionListener(mCompletionListener);
//播放发生错误时的监听器
mLivePlayer.setOnErrorListener(mErrorListener);
//网络视频流缓存变化的监听器
mLivePlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
//状态变化的监听器,例如缓存开始、缓存结束、视频第一帧、音频第一帧、拉流时网络状态码(例如302跳转状态)等状态时的回调
mLivePlayer.setOnInfoListener(mInfoListener);
//seek操作完成的监听器
mLivePlayer.setOnSeekCompleteListener(mSeekCompleteListener);
//设置当前正在播放的时间戳回调。支持软件解码和硬件解码时回调,支持纯音频、音视频文件时回调,建议优先使用 setOnCurrentSyncTimestampListener 回调时间戳
mLivePlayer.setOnCurrentRealTimeListener(mIntervalTime,mOnCurrentRealTimeListener);
//设置当前正在播放的时间戳回调。支持软件解码时回调,支持音视频文件,不支持硬件解码时回调,不支持纯音频文件时回调。回调的时间间隔的单位:毫秒 ms
mLivePlayer.setOnCurrentSyncTimestampListener(mIntervalTime, mOnCurrentSyncTimestampListener);
//设置当前正在播放的音视频流里附带的内容信息回调。 支持软件解码和硬件解码时回调,支持音视频文件,不支持纯音频文件时回调,回调中的内容信息是需要推流端推流时发送的,否则没有。
mLivePlayer.setOnCurrentSyncContentListener( mOnCurrentSyncContentListener);
//外挂字幕文件解析后的字幕的回调
mLivePlayer.setOnSubtitleListener(mOnSubtitleListener);
3. 设置播放地址
在调用 prepareAsync
进行预处理视频前,调用 setDataSource
设置播放地址。
参数说明如下表所示。
参数 | 类型 | 说明 |
---|---|---|
path | String | 待播放文件的路径,拉流地址的获取方法请参见获取拉流地址 |
config | NEDataSourceConfig | 配置缓存本地信息和解密信息 |
示例代码
java//只设置播放地址
mLivePlayer.setDataSource(mUri.toString());//设置数据源,返回 true 成功,返回 false 失败
//同时设置播放地址和播放参数
NEDataSourceConfig dataSourceConfig = new NEDataSourceConfig();
mLivePlayer.setDataSource(videoPath, dataSourceConfig);
4. 设置显示控件
播放器支持SurfaceView 和 TextureView。
- 若用户显示的 View 继承 SurfaceView,则调用
setDisplay
将显示图层添加到需要显示的页面上。 - 若用户显示的 View 继承 TextureView,则调用
setSurface
将显示图层添加到需要显示的页面上。
参数说明如下表所示。
参数 | 类型 | 说明 |
---|---|---|
sh | SurfaceHolder | Surface监听器,提供访问和控制 SurfaceView 背后的 Surface 相关的方法,参数设置为 null 时,视频不显示 |
surface | Surface | 由屏幕显示内容合成器所管理的原生缓冲器的句柄 |
示例代码
java
//若用户显示的 View 继承 SurfaceView,则通过 setDisplay() 接口将 SurfaceHolder 传到底层用于显示。
mLivePlayer.setDisplay(mSurfaceHolder); //设置显示surface
//若用户显示的 View 继承 TextureView,则通过 setSurface() 接口将 SurfaceTexture 传到底层用于显示。
mLivePlayer.setSurface(mSurface); //设置显示surface
Demo 中的 playerkit 组件封装了可直接使用的 SurfaceView 和 TextureView,您可以参考 Demo 源码进行设置,也可以根据自己的实际需求进行计算并设置。有四种显示模式,包括:
javaVideoScaleMode.NONE = 0; //原始大小
VideoScaleMode.FIT = 1; //等比例放大,有一边贴黑边
VideoScaleMode.FILL = 2; //全屏,画面会拉伸
VideoScaleMode.FULL = 3; //全屏,等比例放大,有一边有裁剪
5. (可选)设置播放缓冲策略
在调用 prepareAsync
进行预处理视频前,调用 setBufferStrategy
设置缓冲策略。
参数说明如下表所示。
bufferStrategy缓冲策略模式:
参数 | 类型 | 说明 |
---|---|---|
NELPTOPSPEED | int | 直播极速模式 |
NELPLOWDELAY | int | 直播低延时模式 默认使用 NELPLOWDELAY 直播低延时模式。 |
NELPFLUENT | int | 直播流畅模式 |
NELPANTIJITTER | int | 点播抗抖动模式 |
NELPDELAYPULLUP | int | 直播延时追赶模式 |
示例代码
javaprivate int mBufferStrategy = NEBufferStrategy.NELPLOWDELAY; //直播低延时
mLivePlayer.setBufferStrategy(mBufferStrategy);
- 直播请使用极速模式、低延时模式、流畅模式或直播延时追赶模式。
- 点播请使用点播抗抖动模式。
6. (可选)设置解码模式
在调用 prepareAsync
进行预处理视频前,调用 setHardwareDecoder
设置是否开启硬件解码模式。
默认是软件解码。
参数说明如下表所示。
参数 | 类型 | 说明 |
---|---|---|
isOpen | boolean |
|
示例代码
javaprivate boolean mHardwareDecoder = false;
mLivePlayer.setHardwareDecoder(mHardwareDecoder); // false 为软件解码, true 为硬件解码
7. (可选)设置自动重试参数
从 v2.1.0 开始,播放器SDK内部加入了自动重试功能。
为了避免在播放音视频媒体流时,因网络连接不稳定或者其他问题导致播放失败,建议设置自动重试参数,以提高播放成功率和用户体验。
通过 setAutoRetryConfig
接口来配置自动重试参数。
参数说明如下表所示。
参数 | 类型 | 说明 |
---|---|---|
config | NEAutoRetryConfig | 自动重试的配置类 |
示例代码
javaAutoRetryConfig autoRetryConfig = new AutoRetryConfig();
// 重试三次
autoRetryConfig.count = 3;
// 设置默认重试时间间隔为1s
autoRetryConfig.delayDefault = 1000;
// 设置三次重试的间隔分别为 100ms, 500ms, 3s
autoRetryConfig.delayArray = new long[]{100, 500, 3000};
// 设置重试时的回调
autoRetryConfig.retryListener = new NEAutoRetryConfig.OnRetryListener() {
@Override
public void onRetry(int what, int extra) {
showToast("开始重试,错误类型:" + what + ",附加信息:" + extra);
}
};
// 将重试配置设置给播放器
mLivePlayer.setAutoRetryConfig(autoRetryConfig);
8. 预处理视频文件
调用 prepareAsync
预处理视频文件,准备播放。
预处理完成后,SDK 会触发 onPrepared
回调。
示例代码
java
mLivePlayer.prepareAsync();
//预处理完成后,sdk会有一个回调,需要先注册一个 OnPreparedListener 获取准备完成的回调,步骤(4)已经注册了。
OnPreparedListener mPreparedListener = new OnPreparedListener() {
public void onPrepared(NELivePlayer mp) {
mLivePlayer.start();
};
(可选)使用密钥预处理视频文件(新)
直播流和非flv、hls点播视频场景中,可以忽略该步骤。
建议您使用新的解密方式解密。
对于 flv 和 hls 格式的点播加密视频,需要密钥进行解密,然后再进行播放。实现流程如下:
-
调用
setDataSource
接口的NEDataSourceConfig
参数设置解密配置信息。 -
SDK 验证密钥的正确性,校验结果通过
OnDecryptionListener
回调同步,校验错误则返回 onError 回调,校验成功则返回 onInfo 回调。 -
如果校验正确,自动调用
prepareAsync
接口预处理视频。
参数说明如下表所示。
参数 | 类型 | 说明 |
---|---|---|
config | NEDataSourceConfig | 播放配置项(配置缓存本地信息和解密信息) |
示例代码
java
NEDataSourceConfig dataSourceConfig = new NEDataSourceConfig();
// 配置解密信息
if (decryptionCode == DecryptionConfigCode.CODE_DECRYPTION_INFO) {
dataSourceConfig.decryptionConfig = new NEDecryptionConfig(transferToken, accid, appKey, token);
}else if (decryptionCode == DecryptionConfigCode.CODE_DECRYPTION_KEY) {
dataSourceConfig.decryptionConfig = new NEDecryptionConfig(flvKey, flvKeyLen);
}
// 配置本地缓存
if(enableCache) {
dataSourceConfig.cacheConfig = new NECacheConfig(true, cachePath);
}
mLivePlayer.setDataSource(videoPath, dataSourceConfig);
mLivePlayer.prepareAsync();
(可选)使用密钥预处理视频文件(旧)
- 该接口未来会废弃,建议用户使用新的解密方式解密。
- 直播流和非flv、hls点播视频场景中,可以忽略该步骤。
- 该接口需要在
setDataSource
后调用, 不能与prepareAsyncWithDecryptionKey
和prepareAsync
同时使用。
对于flv和hls点播的加密视频,需要密钥进行解密,然后再进行播放。用户需要调用该接口来获取密钥并验证密钥的正确性,如果校验正确那么自动进行prepareAsync操作,校验结果OnDecryptionListener中进行回调。
参数说明如下表所示。
参数 | 类型 | 说明 |
---|---|---|
transferToken | String | 获取密钥所需的令牌 |
accid | String | 用户创建的子用户id |
token | String | 子用户的token |
appKey | String | 开发者平台分配的AppKey |
listener | OnDecryptionListener | 密钥校验结果的回调,校验正确才能继续prepareAsync操作 |
示例代码
java
mLivePlayer.prepareAsyncWithDecryptionToken(transferToken, accid, token, appKey, mDecryptionListener);
OnDecryptionListener decryptionListener = new OnDecryptionListener() {
@Override
public void onDecryption(int ret) {
Log.i(TAG, " ret = " + ret);
switch (ret) {
case NEKeyVerifyResultType.NELP_NO_ENCRYPTION:
case NEKeyVerifyResultType.NELP_ENCRYPTION_CHECK_OK:
mCurrState = PREPARING;
break;
case NEKeyVerifyResultType.NELP_ENCRYPTION_UNSUPPORT_PROTOCAL:
break;
case NEKeyVerifyResultType.NELP_ENCRYPTION_KEY_CHECK_ERROR:
break;
case NEKeyVerifyResultType.NELP_ENCRYPTION_INPUT_INVALIED:
break;
case NEKeyVerifyResultType.NELP_ENCRYPTION_GET_KEY_TIMEOUT:
break;
case NEKeyVerifyResultType.NELP_ENCRYPTION_UNKNOWN_ERROR:
break;
default:
break;
}
}
};
9. 开始播放
- 如果在
onPrepared
回调中,设置了setShouldAutoplay
为ture
,则会在收到该回调的同时自动播放。 - 如果在
onPrepared
回调中,设置了setShouldAutoplay
为false
,则收到该回调后,需要调用start
手动播放。
示例代码
javamLivePlayer.start();
10. (可选)获取播放信息
在点播场景中,您还可以执行如下操作:
- 调用
getDuration()
接口,获取文件总时长。 - 调用
getCurrentPosition()
接口,获取当前播放进度,用于设置播放进度条。 - 调用
seekTo()
接口,拖动播放进度条。
11. 退出播放
调用 release
退出播放,释放播放器实例和资源。
示例代码
javamLivePlayer.release();
退出播放并释放相关资源,资源释放成功后会有相应的通知,通知以广播的形式进行接收。若退出后再次进入播放,需要等待资源释放成功后才能进入。