1# Using AVPlayer to Play Audio (C/C++) 2 3The [AVPlayer](media-kit-intro.md#avplayer) is used to play raw media assets in an end-to-end manner. In this topic, you will learn how to use the AVPlayer to play a complete piece of music. 4 5 6The full playback process includes creating an AVPlayer instance, setting callback functions, setting the media asset to play, setting playback parameters (volume, speed, and focus mode), controlling playback (play, pause, seek, and stop), resetting the playback configuration, and releasing the AVPlayer instance. 7 8 9During application development, you can obtain the playback process information through the callbacks [OH_AVPlayerOnInfoCallback](../../reference/apis-media-kit/_a_v_player.md#oh_avplayeroninfocallback) and [OH_AVPlayerOnErrorCallback](../../reference/apis-media-kit/_a_v_player.md#oh_avplayeronerrorcallback) of the AVPlayer. If the application performs an operation when the AVPlayer is not in the given state, the system may throw an exception or generate other undefined behavior. 10 11**Figure 1** Playback state transition 12 13 14 15For details about the states, see [AVPlayerState](../../reference/apis-media-kit/_a_v_player.md#avplayerstate-1). When the AVPlayer is in the **prepared**, **playing**, **paused**, or **completed** state, the playback engine is working and a large amount of RAM is occupied. If your application does not need to use the AVPlayer, call **OH_AVPlayer_Reset()** or **OH_AVPlayer_Release()** to release the instance. 16 17## Development Tips 18 19This topic describes only how to implement the playback of a media asset. In practice, background playback and playback conflicts may be involved. You can refer to the following description to handle the situation based on your service requirements. 20 21- If you want the application to continue playing the media asset in the background or when the screen is off, use the [AVSession](../avsession/avsession-access-scene.md) and [continuous task](../../task-management/continuous-task.md) to prevent the playback from being forcibly interrupted by the system. Only ArkTS APIs are provided. 22- If the media asset being played involves audio, the playback may be interrupted by other applications based on the system audio management policy. (For details, see [Processing Audio Interruption Events](../audio/audio-playback-concurrency.md).) It is recommended that the player application proactively listen for audio interruption events [AV_INFO_TYPE_INTERRUPT_EVENT](../../reference/apis-media-kit/_a_v_player.md#avplayeroninfotype-1) through [OH_AVPlayer_SetOnInfoCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setoninfocallback) and handle the events accordingly to avoid the inconsistency between the application status and the expected effect. 23- When a device is connected to multiple audio output devices, the application can listen for audio output device changes [AV_INFO_TYPE_AUDIO_OUTPUT_DEVICE_CHANGE](../../reference/apis-media-kit/_a_v_player.md#avplayeroninfotype-1) through [OH_AVPlayer_SetOnInfoCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setoninfocallback) and perform the processing accordingly. 24- During the playback, an internal error may occur, for example, network data download failure or media service unavailability. You are advised to set an error callback through [OH_AVPlayer_SetOnErrorCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setonerrorcallback) and handle the error based on the error type. 25- Use [OH_AVPlayer_SetOnInfoCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setoninfocallback) and [OH_AVPlayer_SetOnErrorCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setonerrorcallback) to set the information callback [OH_AVPlayerOnInfoCallback](../../reference/apis-media-kit/_a_v_player.md#oh_avplayeroninfocallback) and error callback [OH_AVPlayerOnErrorCallback](../../reference/apis-media-kit/_a_v_player.md#oh_avplayeronerrorcallback), respectively. After [OH_AVPlayerOnInfoCallback](../../reference/apis-media-kit/_a_v_player.md#oh_avplayeroninfocallback) is set, the callback [OH_AVPlayerOnInfo](../../reference/apis-media-kit/_a_v_player.md#oh_avplayeroninfo) set through [OH_AVPlayer_SetPlayerCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setplayercallback) is not executed. After [OH_AVPlayerOnErrorCallback](../../reference/apis-media-kit/_a_v_player.md#oh_avplayeronerrorcallback) is set, the callback [OH_AVPlayerOnError](../../reference/apis-media-kit/_a_v_player.md#oh_avplayeronerror) set through [OH_AVPlayer_SetPlayerCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setplayercallback) is not executed. 26 27## How to Develop 28Link the following dynamic library in the CMake script: 29``` 30target_link_libraries(sample PUBLIC libavplayer.so) 31``` 32 33To use [OH_AVPlayer_SetOnInfoCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setoninfocallback) and [OH_AVPlayer_SetOnErrorCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setonerrorcallback) to set the information callback and error callback, link the following dynamic link library in the CMake script: 34``` 35target_link_libraries(sample PUBLIC libnative_media_core.so) 36``` 37 38To use system logging, include the following header file: 39``` 40#include <hilog/log.h> 41``` 42 43In addition, link the following dynamic link library in the CMake script: 44``` 45target_link_libraries(sample PUBLIC libhilog_ndk.z.so) 46``` 47 48You can use C/C++ APIs related to audio playback by including the header files [avplayer.h](../../reference/apis-media-kit/avplayer_8h.md), [avpalyer_base.h](../../reference/apis-media-kit/avplayer__base_8h.md), and [native_averrors.h](../../reference/apis-avcodec-kit/native__averrors_8h.md). 49Read [AVPlayer](../../reference/apis-media-kit/_a_v_player.md) for the API reference. 50 511. Create an AVPlayer instance by calling [OH_AVPlayer_Create()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_create). The AVPlayer is initialized to the [AV_IDLE](../../reference/apis-media-kit/_a_v_player.md#avplayerstate-1) state. 52 532. Set callbacks to listen for events. Specifically, call [OH_AVPlayer_SetOnInfoCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setoninfocallback) and [OH_AVPlayer_SetOnErrorCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setonerrorcallback) to set the information callback and error callback, which are used in the entire process scenario. The table below lists the supported events. 54 | Event Type| Description| 55 | -------- | -------- | 56 | OH_AVPlayerOnInfoCallback | Mandatory; used to listen for AVPlayer process information.| 57 | OH_AVPlayerOnErrorCallback | Mandatory; used to listen for AVPlayer errors.| 58 59 The application can obtain more information from the callbacks set by calling [OH_AVPlayer_SetOnInfoCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setoninfocallback) and [OH_AVPlayer_SetOnErrorCallback()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setonerrorcallback). In addition, it can set **userData** to distinguish different AVPlayer instances. 60 613. Set the media asset. Specifically, call [OH_AVPlayer_SetURLSource()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_seturlsource) to set the URL of the media asset. The AVPlayer enters the [AV_INITIALIZED](../../reference/apis-media-kit/_a_v_player.md#avplayerstate-1) state. 62 634. (Optional) Set the audio stream type by calling [OH_AVPlayer_SetAudioRendererInfo()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setaudiorendererinfo). 64 655. (Optional) Set the audio interruption mode by calling [OH_AVPlayer_SetAudioInterruptMode()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setaudiointerruptmode). 66 676. Prepare for the playback by calling [OH_AVPlayer_Prepare()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_prepare). The AVPlayer enters the [AV_PREPARED](../../reference/apis-media-kit/_a_v_player.md#avplayerstate-1) state. In this case, you can obtain the duration and set the volume. 68 697. (Optional) Set the audio effect mode of the AVPlayer by calling [OH_AVPlayer_SetAudioEffectMode()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setaudioeffectmode). 70 718. Control the playback. You can call [OH_AVPlayer_Play()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_play), [OH_AVPlayer_Pause()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_pause), [OH_AVPlayer_Seek()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_seek), and [OH_AVPlayer_Stop()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_stop) to trigger different control operations. 72 739. (Optional) Reset the media asset by calling [OH_AVPlayer_Reset()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_reset). The AVPlayer enters the [AV_IDLE](../../reference/apis-media-kit/_a_v_player.md#avplayerstate-1) state again and you can change the media asset URL. 74 7510. Exit the playback. Specifically, call [OH_AVPlayer_Release()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_release) to destroy the instance. The AVPlayer enters the [AV_RELEASED](../../reference/apis-media-kit/_a_v_player.md#avplayerstate-1) state and exits the playback. Further actions on the AVPlayer instance may lead to undefined behavior, such as the process crashing or the application terminating unexpectedly. 76 77## Sample Code 78 79```c 80#include "napi/native_api.h" 81 82#include <multimedia/player_framework/avplayer.h> 83#include <multimedia/player_framework/avplayer_base.h> 84#include <multimedia/player_framework/native_averrors.h> 85 86#include <hilog/log.h> 87 88#define LOG_MSG_TAG "AVPlayerNdk" 89#define LOG(format, ...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, LOG_MSG_TAG, format, ##__VA_ARGS__)) 90#define LOGE(format, ...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, LOG_MSG_TAG, format, ##__VA_ARGS__)) 91 92typedef struct DemoNdkPlayer { 93 OH_AVPlayer *player = nullptr; 94 char *url = nullptr; 95 int32_t errorCode = AV_ERR_UNKNOWN; 96 97 int32_t value = -1; 98 int32_t state = -1; 99 int32_t stateChangeReason = -1; 100 AVPlayerState avState = AV_IDLE; 101 AVPlaybackSpeed speed = AV_SPEED_FORWARD_1_00_X; 102 103 float volume = 0.0; 104 int64_t duration = -1; 105 106 int32_t width = -1; 107 int32_t height = -1; 108 109 AVPlayerBufferingType bufferType = AVPLAYER_BUFFERING_START; 110 int32_t bufferValue = -1; 111 112 uint32_t *bitRates = nullptr; 113 size_t bitRatesSize = 0; 114 uint32_t bitRate = 0; 115 116 int32_t interruptType = -1; 117 int32_t interruptForce = -1; 118 int32_t interruptHint = -1; 119} DemoNdkPlayer; 120 121void HandleStateChange(OH_AVPlayer *player, AVPlayerState state) { 122 switch (state) { 123 case AV_IDLE: // This state is reported upon a successful callback of OH_AVPlayer_Reset(). 124// ret = OH_AVPlayer_SetURLSource(player, url); // Set the URL. 125// if (ret != AV_ERR_OK) { 126// // Handle the exception. 127// } 128 break; 129 case AV_INITIALIZED: 130 ret = OH_AVPlayer_Prepare(player); // This state is reported when the AVPlayer sets the playback source. 131 if (ret != AV_ERR_OK) { 132 // Exception processing. 133 } 134 break; 135 case AV_PREPARED: 136// ret = OH_AVPlayer_SetAudioEffectMode(player, EFFECT_NONE); // Set the audio effect mode. 137// if (ret != AV_ERR_OK) { 138// // Handle the exception. 139// } 140 ret = OH_AVPlayer_Play(player); // Call OH_AVPlayer_Play() to start playback. 141 if (ret != AV_ERR_OK) { 142 // Exception processing. 143 } 144 break; 145 case AV_PLAYING: 146// ret = OH_AVPlayer_Pause(player); // Call OH_AVPlayer_Pause() to pause the playback. 147// if (ret != AV_ERR_OK) { 148// // Handle the exception. 149// } 150 break; 151 case AV_PAUSED: 152// ret = OH_AVPlayer_Play(player); // Call OH_AVPlayer_Play() again to start playback. 153// if (ret != AV_ERR_OK) { 154// // Handle the exception. 155// } 156 break; 157 case AV_STOPPED: 158 ret = OH_AVPlayer_Release(player); // Call OH_AVPlayer_Reset() to reset the AVPlayer state. 159 if (ret != AV_ERR_OK) { 160 // Exception processing. 161 } 162 break; 163 case AV_COMPLETED: 164 ret = OH_AVPlayer_Stop(player);// Call OH_AVPlayer_Stop() to stop the playback. 165 if (ret != AV_ERR_OK) { 166 // Exception processing. 167 } 168 break; 169 default: 170 break; 171 } 172} 173 174void OHAVPlayerOnInfoCallback(OH_AVPlayer *player, AVPlayerOnInfoType type, OH_AVFormat *infoBody, void *userData) { 175 int32_t ret; 176 int32_t value = -1; 177 178 DemoNdkPlayer *demoNdkPlayer = reinterpret_cast<DemoNdkPlayer *>(userData); 179 if (demoNdkPlayer == nullptr || player == nullptr) { 180 LOGE("OHAVPlayerOnInfoCallback demoNdkPlayer is nullptr"); 181 return; 182 } 183 switch (type) { 184 case AV_INFO_TYPE_STATE_CHANGE: 185 LOG("AVPlayerOnInfoType AV_INFO_TYPE_STATE_CHANGE"); 186 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_STATE, &demoNdkPlayer->state); 187 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_STATE_CHANGE_REASON, &demoNdkPlayer->stateChangeReason); 188 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_STATE_CHANGE state: %d ,stateChangeReason: %d", 189 demoNdkPlayer->state, demoNdkPlayer->stateChangeReason); 190 demoNdkPlayer->avState = static_cast<AVPlayerState>(demoNdkPlayer->state); 191 HandleStateChange(player, demoNdkPlayer->avState); 192 break; 193 case AV_INFO_TYPE_SEEKDONE: 194 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_SEEK_POSITION, &value); 195 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_SEEKDONE value: %d", value); 196 break; 197 case AV_INFO_TYPE_SPEEDDONE: 198 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_PLAYBACK_SPEED, &value); 199 demoNdkPlayer->speed = static_cast<AVPlaybackSpeed>(value); 200 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_SPEEDDONE value: %d", value); 201 break; 202 case AV_INFO_TYPE_BITRATEDONE: 203 // Currently, OH_AVFormat does not support storage of data of the uint32_t type or custom type. 204 // Obtain the data of the int32_t type and forcibly convert the data to the corresponding type. 205 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_BITRATE, &value); 206 demoNdkPlayer->bitRate = static_cast<uint32_t>(value); 207 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATEDONE value: %d", value); 208 break; 209 case AV_INFO_TYPE_EOS: 210 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_EOS"); 211 break; 212 case AV_INFO_TYPE_POSITION_UPDATE: 213 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_CURRENT_POSITION, &value); 214 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_POSITION_UPDATE value: %d", value); 215 break; 216 case AV_INFO_TYPE_MESSAGE: 217 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_MESSAGE_TYPE, &value); 218 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_MESSAGE value: %d", value); 219 break; 220 case AV_INFO_TYPE_VOLUME_CHANGE: 221 OH_AVFormat_GetFloatValue(infoBody, OH_PLAYER_VOLUME, &demoNdkPlayer->volume); 222 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_VOLUME_CHANGE value: %f", demoNdkPlayer->volume); 223 break; 224 case AV_INFO_TYPE_RESOLUTION_CHANGE: 225 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_VIDEO_WIDTH, &demoNdkPlayer->width); 226 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_VIDEO_HEIGHT, &demoNdkPlayer->height); 227 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_RESOLUTION_CHANGE width: %d, height: %d", 228 demoNdkPlayer->width, demoNdkPlayer->height); 229 break; 230 case AV_INFO_TYPE_BUFFERING_UPDATE: 231 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_BUFFERING_TYPE, &value); 232 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_BUFFERING_VALUE, &demoNdkPlayer->bufferValue); 233 demoNdkPlayer->bufferType = static_cast<AVPlayerBufferingType>(value); 234 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BUFFERING_UPDATE bufferType: %d, bufferValue: %d", 235 value, demoNdkPlayer->bufferValue); 236 break; 237 case AV_INFO_TYPE_BITRATE_COLLECT: { 238 uint8_t *bitRates = nullptr; 239 size_t size = 0; 240 OH_AVFormat_GetBuffer(infoBody, OH_PLAYER_BITRATE_ARRAY, &bitRates, &size); 241 demoNdkPlayer->bitRatesSize = size / sizeof(uint32_t); 242 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATE_COLLECT bytes size: %zu, size: %zu", 243 size, demoNdkPlayer->bitRatesSize ); 244 if (demoNdkPlayer->bitRatesSize <= 0) { 245 LOGE("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATE_COLLECT invalid bitRatesSize"); 246 return; 247 } 248 demoNdkPlayer->bitRates = new uint32_t[demoNdkPlayer->bitRatesSize]; 249 if (demoNdkPlayer->bitRates == nullptr || bitRates == nullptr) { 250 LOGE("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATE_COLLECT bitRates is nullptr"); 251 return; 252 } 253 memcpy((void *)(demoNdkPlayer->bitRates), (void *)bitRates, demoNdkPlayer->bitRatesSize * sizeof(uint32_t)); 254 for (size_t i = 0; i < demoNdkPlayer->bitRatesSize; i++) { 255 LOGE("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATE_COLLECT bitRates[%zu]: %zu", 256 i, *(demoNdkPlayer->bitRates + i)); 257 } 258 break; 259 } 260 case AV_INFO_TYPE_INTERRUPT_EVENT: 261 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_AUDIO_INTERRUPT_TYPE, &demoNdkPlayer->interruptType); 262 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_AUDIO_INTERRUPT_FORCE, &demoNdkPlayer->interruptForce); 263 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_AUDIO_INTERRUPT_HINT, &demoNdkPlayer->interruptHint); 264 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_INTERRUPT_EVENT interruptType: %d, interruptForce: %d" 265 ", interruptHint: %d", demoNdkPlayer->interruptType, demoNdkPlayer->interruptForce, 266 demoNdkPlayer->interruptHint); 267 break; 268 case AV_INFO_TYPE_DURATION_UPDATE: 269 OH_AVFormat_GetLongValue(infoBody, OH_PLAYER_DURATION, &demoNdkPlayer->duration); 270 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_DURATION_UPDATE value: %lld", demoNdkPlayer->duration); 271 break; 272 case AV_INFO_TYPE_IS_LIVE_STREAM: 273 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_IS_LIVE_STREAM, &value); 274 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_IS_LIVE_STREAM value: %d", value); 275 break; 276 case AV_INFO_TYPE_TRACKCHANGE: 277 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_TRACKCHANGE value: %d", value); 278 break; 279 case AV_INFO_TYPE_TRACK_INFO_UPDATE: 280 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_TRACK_INFO_UPDATE value: %d", value); 281 break; 282 case AV_INFO_TYPE_SUBTITLE_UPDATE: 283 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_SUBTITLE_UPDATE value: %d", value); 284 break; 285 case AV_INFO_TYPE_AUDIO_OUTPUT_DEVICE_CHANGE: 286 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_AUDIO_DEVICE_CHANGE_REASON, &value); 287 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_AUDIO_OUTPUT_DEVICE_CHANGE value: %d", value); 288 break; 289 default: 290 break; 291 } 292} 293 294void OHAVPlayerOnErrorCallback(OH_AVPlayer *player, int32_t errorCode, const char *errorMsg, void *userData) { 295 LOG("OHAVPlayerOnError errorCode: %d ,errorMsg: %s", errorCode, errorMsg == nullptr ? "unknown" : errorMsg); 296 DemoNdkPlayer *demoNdkPlayer = reinterpret_cast<DemoNdkPlayer *>(userData); 297 if (demoNdkPlayer == nullptr || player == nullptr) { 298 LOGE("OHAVPlayerOnErrorCallback demoNdkPlayer or player is nullptr"); 299 return; 300 } 301 demoNdkPlayer->errorCode = errorCode; 302 // do something 303} 304 305// Describe the mapped play method in the index.d.ts file and pass in a parameter of the string type. 306// When calling the player method in the .ets file, pass in the file path testNapi.play("/data/test/test.mp3"). 307static napi_value Play(napi_env env, napi_callback_info info) 308{ 309 size_t argc = 1; 310 napi_value args[1] = {nullptr}; 311 312 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 313 314 // Obtain the parameter type. 315 napi_valuetype stringType; 316 if (napi_ok != napi_typeof(env, args[0], &stringType)) { 317 // Exception processing. 318 return nullptr; 319 } 320 321 // Verify the parameter. 322 if (napi_null == stringType) { 323 // Exception processing. 324 return nullptr; 325 } 326 327 // Obtain the length of the passed-in string. 328 size_t length = 0; 329 if (napi_ok != napi_get_value_string_utf8(env, args[0], nullptr, 0, &length)) { 330 // Exception processing. 331 return nullptr; 332 } 333 334 // If "" is passed in, the result is directly returned. 335 if (length == 0) { 336 // Exception processing. 337 return nullptr; 338 } 339 340 // Read the passed-in string and place it in the buffer. 341 char *url = new char[length + 1]; 342 if (napi_ok != napi_get_value_string_utf8(env, args[0], url, length + 1, &length)) { 343 delete[] url; 344 url = nullptr; 345 // Exception processing. 346 return nullptr; 347 } 348 349 // Use the new function to set the information callback and error callback. Do not use OH_AVPlayer_SetPlayerCallback. 350 // Release the object when it is no longer needed. 351 DemoNdkPlayer *demoNdkPlayer = new DemoNdkPlayer({ 352 .player = player, 353 .url = url, 354 }); 355 LOG("call OH_AVPlayer_SetPlayerOnInfoCallback"); 356 ret = OH_AVPlayer_SetOnInfoCallback(player, OHAVPlayerOnInfoCallback, demoNdkPlayer); 357 LOG("OH_AVPlayer_SetPlayerOnInfoCallback ret:%d", ret); 358 LOG("call OH_AVPlayer_SetPlayerOnErrorCallback"); 359 ret = OH_AVPlayer_SetOnErrorCallback(player, OHAVPlayerOnErrorCallback, demoNdkPlayer); 360 LOG("OH_AVPlayer_SetPlayerOnErrorCallback ret:%d", ret); 361 362 if (ret != AV_ERR_OK) { 363 // Exception processing. 364 } 365 ret = OH_AVPlayer_SetURLSource(player, url); // Set the URL. 366 if (ret != AV_ERR_OK) { 367 // Exception processing. 368 } 369 // Set the audio stream type. 370 OH_AudioStream_Usage streamUsage = OH_AudioStream_Usage::AUDIOSTREAM_USAGE_UNKNOWN; 371 ret = OH_AVPlayer_SetAudioRendererInfo(player, streamUsage); 372 if (ret != AV_ERR_OK) { 373 // Handle the exception. 374 } 375 // Set the audio interruption mode. 376 OH_AudioInterrupt_Mode interruptMode = OH_AudioInterrupt_Mode::AUDIOSTREAM_INTERRUPT_MODE_INDEPENDENT; 377 ret = OH_AVPlayer_SetAudioInterruptMode(player, interruptMode); 378 if (ret != AV_ERR_OK) { 379 // Handle the exception. 380 } 381 napi_value value; 382 napi_create_int32(env, 0, &value); 383 return value; 384} 385 386EXTERN_C_START 387static napi_value Init(napi_env env, napi_value exports) 388{ 389 napi_property_descriptor desc[] = { 390 { "play", nullptr, Play, nullptr, nullptr, nullptr, napi_default, nullptr } 391 }; 392 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 393 return exports; 394} 395EXTERN_C_END 396 397static napi_module demoModule = { 398 .nm_version =1, 399 .nm_flags = 0, 400 .nm_filename = nullptr, 401 .nm_register_func = Init, 402 .nm_modname = "entry", 403 .nm_priv = ((void*)0), 404 .reserved = { 0 }, 405}; 406 407extern "C" __attribute__((constructor)) void RegisterEntryModule(void) 408{ 409 napi_module_register(&demoModule); 410} 411``` 412