从API version 11开始,支持使用AVPlayer实现端到端播放流媒体资源。本开发指导将以完整地播放一个流媒体作为示例,向开发者讲解AVPlayer流媒体播放相关功能。
播放的全流程包含:创建AVPlayer、设置回调监听函数、设置播放资源、设置播放参数(音量/倍速/焦点模式)、设置播放窗口、播放控制(播放/暂停/跳转/停止)、重置、销毁播放器实例。
在进行应用开发的过程中,开发者可以通过AVPlayer的信息监听回调函数OH_AVPlayerOnInfoCallback和错误监听回调函数OH_AVPlayerOnErrorCallback主动获取播放过程信息。如果应用在视频播放器处于错误状态时执行操作,系统会抛出异常或生成其他未定义的行为。
状态的详细说明请参考AVPlayerState。当播放处于prepared/playing/paused/completed状态时,播放引擎处于工作状态,这需要占用系统较多的运行内存。当客户端暂时不使用播放器时,调用reset()或release()回收内存资源,合理利用资源。
播放状态变化示意图:

当前指导仅介绍如何实现流媒体资源播放,如需播放本地资源,请参考使用AVPlayer播放视频(C/C++)。如果在应用开发过程中涉及后台播放、播放冲突等情况,请根据实际需要参考以下说明。
避免播放被系统强制中断。此功能仅适用于ArkTS API,如需使用此功能请参考使用AVPlayer播放视频(ArkTS)。
在CMake脚本中链接如下动态库:
target_link_libraries(entry PUBLIC
libavplayer.so
libnative_media_core.so
libhilog_ndk.z.so
) 使用OH_AVPlayer_SetOnInfoCallback()、OH_AVPlayer_SetOnErrorCallback()接口设置信息监听回调函数和错误监听回调函数,需要在CMake脚本中链接libnative_media_core.so动态库。
开发者使用系统日志能力时,需引入如下头文件。
#include <hilog/log.h>
并需要在CMake脚本中链接libhilog_ndk.z.so动态库。
开发者通过引入avplayer.h、avplayer_base.h和native_averrors.h头文件,使用流媒体播放相关API。
详细的API说明请参考AVPlayer。
创建AVPlayer实例:调用OH_AVPlayer_Create()接口,AVPlayer初始化为AVPlayerState.AV_IDLE状态。
OH_AVPlayer *player = OH_AVPlayer_Create();
设置回调监听函数:使用OH_AVPlayer_SetOnInfoCallback()和OH_AVPlayer_SetOnErrorCallback()接口设置信息监听回调函数和错误监听回调函数,配合全流程场景使用。获取更多信息的同时还可以通过设置userData区分不同播放实例。
支持的监听事件如下所示:
| 事件类型 | 说明 |
|---|---|
| OH_AVPlayerOnInfoCallback | 必要事件,监听播放器的过程信息。 需要播放器在AV_IDLE状态下、未调用设置资源接口前完成设置监听。如果在调用设置资源接口后再设置监听,会导致无法收到资源设置过程中上报的OH_AVPlayerOnInfoCallback事件。 |
| OH_AVPlayerOnErrorCallback | 必要事件,监听播放器的错误信息。 需要播放器在AV_IDLE状态下、未调用设置资源接口前完成设置监听。如果在调用设置资源接口后再设置监听,会导致无法收到资源设置过程中上报的OH_AVPlayerOnErrorCallback事件。 |
// 设置回调,监听信息。
LOG("call OH_AVPlayer_SetOnInfoCallback");
int32_t ret = OH_AVPlayer_SetOnInfoCallback(player, OHAVPlayerOnInfoCallback, nullptr);
LOG("OH_AVPlayer_SetOnInfoCallback ret:%{public}d", ret); LOG("call OH_AVPlayer_SetOnErrorCallback");
ret = OH_AVPlayer_SetOnErrorCallback(player, OHAVPlayerOnErrorCallback, nullptr);
LOG("OH_AVPlayer_SetOnErrorCallback ret:%{public}d", ret); 设置资源:调用OH_AVPlayer_SetURLSource(),设置属性URL(支持点播和直播源),AVPlayer进入AVPlayerState.AV_INITIALIZED(初始化)状态。
LOG("player %{public}s >> URL source", url);
LOG("call %{public}s", "OH_AVPlayer_SetURLSource");
ret = OH_AVPlayer_SetURLSource(player, url);
LOG("OH_AVPlayer_SetURLSource ret:%{public}d", ret); (可选)设置智能追帧:直播场景下调用OH_AVPlayer_SetPlaybackStrategy(),设置AVPlayer启用智能追帧。
void OHAVPlayerSetPlaybackStrategy(OH_AVPlayer *player)
{
// 设置播放策略。
OH_AVPlaybackStrategy *myStrategy = OH_AVPlaybackStrategy_Create();
double waterLine = 6.0;
OH_AVPlaybackStrategy_SetThresholdForAutoQuickPlay(myStrategy, waterLine); // 直播场景设置智能追帧。
int32_t ret = OH_AVPlayer_SetPlaybackStrategy(player, myStrategy);
LOG("OH_AVPlayer_SetPlaybackStrategy ret:%{public}d", ret);
OH_AVPlaybackStrategy_Destroy(myStrategy);
} (可选)设置音频流类型:调用OH_AVPlayer_SetAudioRendererInfo(),设置AVPlayer音频流类型。
// 设置音频流类型。
LOG("call %{public}s", "OH_AVPlayer_SetAudioRendererInfo");
OH_AudioStream_Usage streamUsage = OH_AudioStream_Usage::AUDIOSTREAM_USAGE_UNKNOWN;
ret = OH_AVPlayer_SetAudioRendererInfo(player, streamUsage);
LOG("OH_AVPlayer_SetAudioRendererInfo ret:%{public}d", ret); (可选)设置音频打断模式:调用OH_AVPlayer_SetAudioInterruptMode(),设置AVPlayer音频流打断模式。
// 设置音频流打断模式。
LOG("call OH_AVPlayer_SetAudioInterruptMode");
OH_AudioInterrupt_Mode interruptMode = OH_AudioInterrupt_Mode::AUDIOSTREAM_INTERRUPT_MODE_INDEPENDENT;
ret = OH_AVPlayer_SetAudioInterruptMode(player, interruptMode);
LOG("OH_AVPlayer_SetAudioInterruptMode ret:%{public}d", ret); 设置播放画面窗口:调用OH_AVPlayer_SetVideoSurface()设置播放画面窗口。此函数必须在SetSource之后,Prepare之前调用。
ret = OH_AVPlayer_SetVideoSurface(player, context->nativeWindow_);
LOG("OH_AVPlayer_SetVideoSurface ret:%{public}d", ret); 准备播放:调用OH_AVPlayer_Prepare(),AVPlayer进入AVPlayerState.AV_PREPARED(准备)状态,此时可以获取时长,设置音量。
ret = OH_AVPlayer_Prepare(player); // 设置播放源后触发该状态上报。
if (ret != AV_ERR_OK) {
// 处理异常。
LOG("player %{public}s", "OH_AVPlayer_Prepare Err");
} (可选)设置音频音效模式:调用OH_AVPlayer_SetAudioEffectMode(),设置AVPlayer音频音效模式。
LOG("AVPlayerState AV_PREPARED");
ret = OH_AVPlayer_SetAudioEffectMode(player, EFFECT_NONE); // 设置音频音效模式。
LOG("OH_AVPlayer_SetAudioEffectMode ret:%{public}d", ret); 播放控制:包含播放OH_AVPlayer_Play()、暂停OH_AVPlayer_Pause()、跳转OH_AVPlayer_Seek()、停止OH_AVPlayer_Stop()等操作。
static napi_value NAPI_Global_Play(napi_env env, napi_callback_info info) {
int ret = -1;
auto context = SampleManager::GetInstance();
if (context->player_ != NULL) {
ret = OH_AVPlayer_Play(context->player_);
LOG("OH_AVPlayer_Play ret:%{public}d", ret);
} else {
LOG("no found Player Instances");
}
napi_value value;
napi_create_int32(env, ret, &value);
return value;
} static napi_value NAPI_Global_Pause(napi_env env, napi_callback_info info) {
int ret = 100;
auto context = SampleManager::GetInstance();
if (context->player_ != NULL) {
ret = OH_AVPlayer_Pause(context->player_);
LOG("OH_AVPlayer_Pause ret:%{public}d", ret);
} else {
LOG("no found Player Instances");
}
napi_value value;
napi_create_int32(env, ret, &value);
return value;
} static napi_value NAPI_Global_Seek(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
int seekValue;
napi_get_value_int32(env, args[0], &seekValue);
int mode;
napi_get_value_int32(env, args[1], &mode);
auto context = SampleManager::GetInstance();
if (context->player_ != NULL) {
int ret;
switch (mode) {
case 0:
LOG("call NAPI_Global_Seek value:%{public}d mode:AV_SEEK_NEXT_SYNC", seekValue);
ret = OH_AVPlayer_Seek(context->player_, seekValue, AV_SEEK_NEXT_SYNC);
break;
case 1:
LOG("call NAPI_Global_Seek value:%{public}d mode:AV_SEEK_PREVIOUS_SYNC", seekValue);
ret = OH_AVPlayer_Seek(context->player_, seekValue, AV_SEEK_PREVIOUS_SYNC);
break;
case 2:
LOG("call NAPI_Global_Seek value:%{public}d mode:AV_SEEK_CLOSEST", seekValue);
ret = OH_AVPlayer_Seek(context->player_, seekValue, AV_SEEK_CLOSEST);
break;
default:
LOG("call NAPI_Global_Seek value:%{public}d mode:AV_SEEK_PREVIOUS_SYNC", seekValue);
ret = OH_AVPlayer_Seek(context->player_, seekValue, AV_SEEK_PREVIOUS_SYNC);
break;
}
LOG("OH_AVPlayer_Seek ret:%{public}d", ret);
} else {
LOG("no found Player Instances");
}
napi_value value;
napi_create_int32(env, 0, &value);
return value;
} static napi_value NAPI_Global_Stop(napi_env env, napi_callback_info info) {
int ret = 100;
auto context = SampleManager::GetInstance();
if (context->player_ != NULL) {
ret = OH_AVPlayer_Stop(context->player_);
LOG("OH_AVPlayer_Stop ret:%{public}d", ret);
} else {
LOG("no found Player Instances");
}
napi_value value;
napi_create_int32(env, ret, &value);
return value;
} (可选)更换资源:调用OH_AVPlayer_Reset()重置资源,AVPlayer重新进入AVPlayerState.AV_IDLE(空闲)状态,允许更换资源URL。
static napi_value NAPI_Global_Reset(napi_env env, napi_callback_info info) {
int ret = 100;
auto context = SampleManager::GetInstance();
if (context->player_ != NULL) {
ret = OH_AVPlayer_Reset(context->player_);
LOG("OH_AVPlayer_Reset ret:%{public}d", ret);
} else {
LOG("no found Player Instances");
}
napi_value value;
napi_create_int32(env, ret, &value);
return value;
} 退出播放:调用OH_AVPlayer_Release()销毁实例,AVPlayer进入AVPlayerState.AV_RELEASED(释放)状态,退出播放。如果后续再操作AVPlayer实例,则行为未知,可能导致应用进程崩溃,应用异常退出等情况。
static napi_value NAPI_Global_Release(napi_env env, napi_callback_info info) {
int ret = -1;
auto context = SampleManager::GetInstance();
if (context->player_ != NULL) {
ret = OH_AVPlayer_Release(context->player_);
LOG("OH_AVPlayer_Release ret:%{public}d", ret);
} else {
LOG("no found Player Instances");
}
napi_value value;
napi_create_int32(env, ret, &value);
return value;
}