1# Using AVPlayer to Play Video (C/C++) 2 3The [AVPlayer](../../reference/apis-media-kit/_a_v_player.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 video. 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), setting the playback window, 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 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 video 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. Set the playback window by calling [OH_AVPlayer_SetVideoSurface()](../../reference/apis-media-kit/_a_v_player.md#oh_avplayer_setvideosurface). This function must be called after **SetSource** and before **Prepare**. 68 697. 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. 70 718. (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). 72 739. 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. 74 7510. (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. 76 7711. 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. 78 79## Sample Code 80 81```c++ 82#include "napi/native_api.h" 83 84#include <ace/xcomponent/native_interface_xcomponent.h> 85#include <multimedia/player_framework/avplayer.h> 86#include <multimedia/player_framework/avplayer_base.h> 87#include <multimedia/player_framework/native_averrors.h> 88 89#include <hilog/log.h> 90 91#define LOG_MSG_TAG "AVPlayerNdk" 92#define LOG(format, ...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, LOG_MSG_TAG, format, ##__VA_ARGS__)) 93#define LOGE(format, ...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, LOG_MSG_TAG, format, ##__VA_ARGS__)) 94 95typedef struct DemoNdkPlayer { 96 OH_AVPlayer *player = nullptr; 97 char *url = nullptr; 98 int32_t errorCode = AV_ERR_UNKNOWN; 99 100 int32_t value = -1; 101 int32_t state = -1; 102 int32_t stateChangeReason = -1; 103 AVPlayerState avState = AV_IDLE; 104 AVPlaybackSpeed speed = AV_SPEED_FORWARD_1_00_X; 105 106 float volume = 0.0; 107 int64_t duration = -1; 108 109 int32_t width = -1; 110 int32_t height = -1; 111 112 static OHNativeWindow *nativeWindow; 113 114 AVPlayerBufferingType bufferType = AVPLAYER_BUFFERING_START; 115 int32_t bufferValue = -1; 116 117 uint32_t *bitRates = nullptr; 118 size_t bitRatesSize = 0; 119 uint32_t bitRate = 0; 120 121 int32_t interruptType = -1; 122 int32_t interruptForce = -1; 123 int32_t interruptHint = -1; 124} DemoNdkPlayer; 125 126OHNativeWindow *DemoNdkPlayer::nativeWindow = nullptr; 127 128void HandleStateChange(OH_AVPlayer *player, AVPlayerState state) { 129 OH_AVErrCode ret; 130 switch (state) { 131 case AV_IDLE: // This state is reported upon a successful callback of OH_AVPlayer_Reset(). 132// ret = OH_AVPlayer_SetURLSource(player, url); // Set the URL. 133// if (ret != AV_ERR_OK) { 134// // Handle the exception. 135// } 136 break; 137 case AV_INITIALIZED: 138 ret = OH_AVPlayer_SetVideoSurface(player, DemoNdkPlayer::nativeWindow); // Set the video playback surface. 139 LOG("OH_AVPlayer_SetVideoSurface ret:%d", ret); 140 ret = OH_AVPlayer_Prepare(player); // This state is reported when the AVPlayer sets the playback source. 141 if (ret != AV_ERR_OK) { 142 // Handle the exception. 143 } 144 break; 145 case AV_PREPARED: 146// ret = OH_AVPlayer_SetAudioEffectMode(player, EFFECT_NONE); // Set the audio effect mode. 147// if (ret != AV_ERR_OK) { 148// // Handle the exception. 149// } 150 ret = OH_AVPlayer_Play(player); // Call OH_AVPlayer_Play() to start playback. 151 if (ret != AV_ERR_OK) { 152 // Handle the exception. 153 } 154 break; 155 case AV_PLAYING: 156// ret = OH_AVPlayer_Pause(player); // Call OH_AVPlayer_Pause() to pause the playback. 157// if (ret != AV_ERR_OK) { 158// // Handle the exception. 159// } 160 break; 161 case AV_PAUSED: 162// ret = OH_AVPlayer_Play(player); // Call OH_AVPlayer_Play() again to start playback. 163// if (ret != AV_ERR_OK) { 164// // Handle the exception. 165// } 166 break; 167 case AV_STOPPED: 168 ret = OH_AVPlayer_Release(player); // Call OH_AVPlayer_Reset() to reset the AVPlayer state. 169 if (ret != AV_ERR_OK) { 170 // Handle the exception. 171 } 172 break; 173 case AV_COMPLETED: 174 ret = OH_AVPlayer_Stop(player);// Call OH_AVPlayer_Stop() to stop the playback. 175 if (ret != AV_ERR_OK) { 176 // Handle the exception. 177 } 178 break; 179 default: 180 break; 181 } 182} 183 184void OHAVPlayerOnInfoCallback(OH_AVPlayer *player, AVPlayerOnInfoType type, OH_AVFormat *infoBody, void *userData) { 185 OH_AVErrCode ret; 186 int32_t value = -1; 187 188 DemoNdkPlayer *demoNdkPlayer = reinterpret_cast<DemoNdkPlayer *>(userData); 189 if (demoNdkPlayer == nullptr || player == nullptr) { 190 LOGE("OHAVPlayerOnInfoCallback demoNdkPlayer is nullptr"); 191 return; 192 } 193 switch (type) { 194 case AV_INFO_TYPE_STATE_CHANGE: 195 LOG("AVPlayerOnInfoType AV_INFO_TYPE_STATE_CHANGE"); 196 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_STATE, &demoNdkPlayer->state); 197 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_STATE_CHANGE_REASON, &demoNdkPlayer->stateChangeReason); 198 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_STATE_CHANGE state: %d ,stateChangeReason: %d", 199 demoNdkPlayer->state, demoNdkPlayer->stateChangeReason); 200 demoNdkPlayer->avState = static_cast<AVPlayerState>(demoNdkPlayer->state); 201 HandleStateChange(player, demoNdkPlayer->avState); 202 break; 203 case AV_INFO_TYPE_SEEKDONE: 204 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_SEEK_POSITION, &value); 205 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_SEEKDONE value: %d", value); 206 break; 207 case AV_INFO_TYPE_SPEEDDONE: 208 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_PLAYBACK_SPEED, &value); 209 demoNdkPlayer->speed = static_cast<AVPlaybackSpeed>(value); 210 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_SPEEDDONE value: %d", value); 211 break; 212 case AV_INFO_TYPE_BITRATEDONE: 213 // Currently, OH_AVFormat does not support storage of data of the uint32_t type or custom type. 214 // Obtain the data of the int32_t type and forcibly convert the data to the corresponding type. 215 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_BITRATE, &value); 216 demoNdkPlayer->bitRate = static_cast<uint32_t>(value); 217 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATEDONE value: %d", value); 218 break; 219 case AV_INFO_TYPE_EOS: 220 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_EOS"); 221 break; 222 case AV_INFO_TYPE_POSITION_UPDATE: 223 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_CURRENT_POSITION, &value); 224 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_POSITION_UPDATE value: %d", value); 225 break; 226 case AV_INFO_TYPE_MESSAGE: 227 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_MESSAGE_TYPE, &value); 228 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_MESSAGE value: %d", value); 229 break; 230 case AV_INFO_TYPE_VOLUME_CHANGE: 231 OH_AVFormat_GetFloatValue(infoBody, OH_PLAYER_VOLUME, &demoNdkPlayer->volume); 232 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_VOLUME_CHANGE value: %f", demoNdkPlayer->volume); 233 break; 234 case AV_INFO_TYPE_RESOLUTION_CHANGE: 235 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_VIDEO_WIDTH, &demoNdkPlayer->width); 236 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_VIDEO_HEIGHT, &demoNdkPlayer->height); 237 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_RESOLUTION_CHANGE width: %d, height: %d", 238 demoNdkPlayer->width, demoNdkPlayer->height); 239 break; 240 case AV_INFO_TYPE_BUFFERING_UPDATE: 241 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_BUFFERING_TYPE, &value); 242 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_BUFFERING_VALUE, &demoNdkPlayer->bufferValue); 243 demoNdkPlayer->bufferType = static_cast<AVPlayerBufferingType>(value); 244 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BUFFERING_UPDATE bufferType: %d, bufferValue: %d", 245 value, demoNdkPlayer->bufferValue); 246 break; 247 case AV_INFO_TYPE_BITRATE_COLLECT: { 248 uint8_t *bitRates = nullptr; 249 size_t size = 0; 250 OH_AVFormat_GetBuffer(infoBody, OH_PLAYER_BITRATE_ARRAY, &bitRates, &size); 251 demoNdkPlayer->bitRatesSize = size / sizeof(uint32_t); 252 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATE_COLLECT bytes size: %zu, size: %zu", 253 size, demoNdkPlayer->bitRatesSize ); 254 if (demoNdkPlayer->bitRatesSize <= 0) { 255 LOGE("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATE_COLLECT invalid bitRatesSize"); 256 return; 257 } 258 demoNdkPlayer->bitRates = new uint32_t[demoNdkPlayer->bitRatesSize]; 259 if (demoNdkPlayer->bitRates == nullptr || bitRates == nullptr) { 260 LOGE("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATE_COLLECT bitRates is nullptr"); 261 return; 262 } 263 memcpy((void *)(demoNdkPlayer->bitRates), (void *)bitRates, demoNdkPlayer->bitRatesSize * sizeof(uint32_t)); 264 for (size_t i = 0; i < demoNdkPlayer->bitRatesSize; i++) { 265 LOGE("OHAVPlayerOnInfoCallback AV_INFO_TYPE_BITRATE_COLLECT bitRates[%zu]: %zu", 266 i, *(demoNdkPlayer->bitRates + i)); 267 } 268 break; 269 } 270 case AV_INFO_TYPE_INTERRUPT_EVENT: 271 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_AUDIO_INTERRUPT_TYPE, &demoNdkPlayer->interruptType); 272 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_AUDIO_INTERRUPT_FORCE, &demoNdkPlayer->interruptForce); 273 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_AUDIO_INTERRUPT_HINT, &demoNdkPlayer->interruptHint); 274 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_INTERRUPT_EVENT interruptType: %d, interruptForce: %d" 275 ", interruptHint: %d", demoNdkPlayer->interruptType, demoNdkPlayer->interruptForce, 276 demoNdkPlayer->interruptHint); 277 break; 278 case AV_INFO_TYPE_DURATION_UPDATE: 279 OH_AVFormat_GetLongValue(infoBody, OH_PLAYER_DURATION, &demoNdkPlayer->duration); 280 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_DURATION_UPDATE value: %lld", demoNdkPlayer->duration); 281 break; 282 case AV_INFO_TYPE_IS_LIVE_STREAM: 283 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_IS_LIVE_STREAM, &value); 284 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_IS_LIVE_STREAM value: %d", value); 285 break; 286 case AV_INFO_TYPE_TRACKCHANGE: 287 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_TRACKCHANGE value: %d", value); 288 break; 289 case AV_INFO_TYPE_TRACK_INFO_UPDATE: 290 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_TRACK_INFO_UPDATE value: %d", value); 291 break; 292 case AV_INFO_TYPE_SUBTITLE_UPDATE: 293 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_SUBTITLE_UPDATE value: %d", value); 294 break; 295 case AV_INFO_TYPE_AUDIO_OUTPUT_DEVICE_CHANGE: 296 OH_AVFormat_GetIntValue(infoBody, OH_PLAYER_AUDIO_DEVICE_CHANGE_REASON, &value); 297 LOG("OHAVPlayerOnInfoCallback AV_INFO_TYPE_AUDIO_OUTPUT_DEVICE_CHANGE value: %d", value); 298 break; 299 default: 300 break; 301 } 302} 303 304void OHAVPlayerOnErrorCallback(OH_AVPlayer *player, int32_t errorCode, const char *errorMsg, void *userData) { 305 LOG("OHAVPlayerOnError errorCode: %d ,errorMsg: %s", errorCode, errorMsg == nullptr ? "unknown" : errorMsg); 306 DemoNdkPlayer *demoNdkPlayer = reinterpret_cast<DemoNdkPlayer *>(userData); 307 if (demoNdkPlayer == nullptr || player == nullptr) { 308 LOGE("OHAVPlayerOnErrorCallback demoNdkPlayer or player is nullptr"); 309 return; 310 } 311 demoNdkPlayer->errorCode = errorCode; 312 // do something 313} 314 315// Describe the mapped play method in the index.d.ts file and pass in a parameter of the string type. 316// When calling the player method in the .ets file, pass in the file path testNapi.play("/data/test/test.mp4"). 317static napi_value Play(napi_env env, napi_callback_info info) 318{ 319 OH_AVErrCode ret; 320 size_t argc = 1; 321 napi_value args[1] = {nullptr}; 322 323 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 324 325 // Obtain the parameter type. 326 napi_valuetype stringType; 327 if (napi_ok != napi_typeof(env, args[0], &stringType)) { 328 // Handle the exception. 329 return nullptr; 330 } 331 332 // Verify the parameter. 333 if (napi_null == stringType) { 334 // Handle the exception. 335 return nullptr; 336 } 337 338 // Obtain the length of the passed-in string. 339 size_t length = 0; 340 if (napi_ok != napi_get_value_string_utf8(env, args[0], nullptr, 0, &length)) { 341 // Handle the exception. 342 return nullptr; 343 } 344 345 // If "" is passed in, the result is directly returned. 346 if (length == 0) { 347 // Handle the exception. 348 return nullptr; 349 } 350 351 // Read the passed-in string and place it in the buffer. 352 char *url = new char[length + 1]; 353 if (napi_ok != napi_get_value_string_utf8(env, args[0], url, length + 1, &length)) { 354 delete[] url; 355 url = nullptr; 356 // Handle the exception. 357 return nullptr; 358 } 359 360 // Use the new function to set the information callback and error callback. Do not use OH_AVPlayer_SetPlayerCallback. 361 // Release the object when it is no longer needed. 362 OH_AVPlayer *player = OH_AVPlayer_Create(); 363 DemoNdkPlayer *demoNdkPlayer = new DemoNdkPlayer({ 364 .player = player, 365 .url = url, 366 }); 367 LOG("call OH_AVPlayer_SetPlayerOnInfoCallback"); 368 ret = OH_AVPlayer_SetOnInfoCallback(player, OHAVPlayerOnInfoCallback, demoNdkPlayer); 369 LOG("OH_AVPlayer_SetPlayerOnInfoCallback ret:%d", ret); 370 LOG("call OH_AVPlayer_SetPlayerOnErrorCallback"); 371 ret = OH_AVPlayer_SetOnErrorCallback(player, OHAVPlayerOnErrorCallback, demoNdkPlayer); 372 LOG("OH_AVPlayer_SetPlayerOnErrorCallback ret:%d", ret); 373 374 if (ret != AV_ERR_OK) { 375 // Handle the exception. 376 } 377 ret = OH_AVPlayer_SetURLSource(player, url); // Set the URL. 378 if (ret != AV_ERR_OK) { 379 // Handle the exception. 380 } 381 // Set the audio stream type. 382 OH_AudioStream_Usage streamUsage = OH_AudioStream_Usage::AUDIOSTREAM_USAGE_UNKNOWN; 383 ret = OH_AVPlayer_SetAudioRendererInfo(player, streamUsage); 384 if (ret != AV_ERR_OK) { 385 // Handle the exception. 386 } 387 // Set the audio interruption mode. 388 OH_AudioInterrupt_Mode interruptMode = OH_AudioInterrupt_Mode::AUDIOSTREAM_INTERRUPT_MODE_INDEPENDENT; 389 ret = OH_AVPlayer_SetAudioInterruptMode(player, interruptMode); 390 if (ret != AV_ERR_OK) { 391 // Handle the exception. 392 } 393 napi_value value; 394 napi_create_int32(env, 0, &value); 395 return value; 396} 397 398// Define the surface callback. 399void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) { 400 LOG("OnSurfaceCreatedCB..."); 401 // Obtain an OHNativeWindow instance. 402 OHNativeWindow * nativeWindow = static_cast<OHNativeWindow *>(window); 403 DemoNdkPlayer::nativeWindow = nativeWindow; 404 // ... 405} 406 407void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) { 408 LOG("OnSurfaceDestroyedCB..."); 409 // Obtain an OHNativeWindow instance. 410 OHNativeWindow * nativeWindow = static_cast<OHNativeWindow *>(window); 411 // ... 412} 413 414void Export(napi_env env, napi_value exports) { 415 if ((env == nullptr) || (exports == nullptr)) { 416 LOG("Export: env or exports is null"); 417 return; 418 } 419 napi_value exportInstance = nullptr; 420 if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) { 421 LOG("Export: napi_get_named_property fail"); 422 return; 423 } 424 OH_NativeXComponent *nativeXComponent = nullptr; 425 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) { 426 LOG("Export: napi_unwrap fail"); 427 return; 428 } 429 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'}; 430 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; 431 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { 432 LOG("OH_NativeXComponent_GetXComponentId fail"); 433 return; 434 } 435 LOG("call Export surfaceID=%s", idStr); 436} 437 438EXTERN_C_START 439static napi_value Init(napi_env env, napi_value exports) 440{ 441 napi_property_descriptor desc[] = { 442 { "Play", nullptr, Play, nullptr, nullptr, nullptr, napi_default, nullptr } 443 }; 444 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 445 446 Export(env, exports); 447 return exports; 448} 449EXTERN_C_END 450 451static napi_module demoModule = { 452 .nm_version =1, 453 .nm_flags = 0, 454 .nm_filename = nullptr, 455 .nm_register_func = Init, 456 .nm_modname = "entry", 457 .nm_priv = ((void*)0), 458 .reserved = { 0 }, 459}; 460 461extern "C" __attribute__((constructor)) void RegisterEntryModule(void) 462{ 463 napi_module_register(&demoModule); 464} 465``` 466