1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "audio_player_napi.h"
17 #include <climits>
18 #include "player_callback_napi.h"
19 #include "media_log.h"
20 #include "media_errors.h"
21 #include "string_ex.h"
22 #ifdef SUPPORT_JSSTACK
23 #include "xpower_event_js.h"
24 #endif
25
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioPlayerNapi"};
28 }
29
30 namespace OHOS {
31 namespace Media {
32 thread_local napi_ref AudioPlayerNapi::constructor_ = nullptr;
33 const std::string CLASS_NAME = "AudioPlayer";
34 const std::string STATE_PLAYING = "playing";
35 const std::string STATE_PAUSED = "paused";
36 const std::string STATE_STOPPED = "stopped";
37 const std::string STATE_IDLE = "idle";
38 const std::string STATE_ERROR = "error";
39
AudioPlayerNapi()40 AudioPlayerNapi::AudioPlayerNapi()
41 {
42 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
43 }
44
~AudioPlayerNapi()45 AudioPlayerNapi::~AudioPlayerNapi()
46 {
47 CancelCallback();
48 nativePlayer_ = nullptr;
49 callbackNapi_ = nullptr;
50
51 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
52 }
53
Init(napi_env env,napi_value exports)54 napi_value AudioPlayerNapi::Init(napi_env env, napi_value exports)
55 {
56 napi_property_descriptor properties[] = {
57 DECLARE_NAPI_FUNCTION("play", Play),
58 DECLARE_NAPI_FUNCTION("pause", Pause),
59 DECLARE_NAPI_FUNCTION("stop", Stop),
60 DECLARE_NAPI_FUNCTION("reset", Reset),
61 DECLARE_NAPI_FUNCTION("release", Release),
62 DECLARE_NAPI_FUNCTION("seek", Seek),
63 DECLARE_NAPI_FUNCTION("on", On),
64 DECLARE_NAPI_FUNCTION("setVolume", SetVolume),
65 DECLARE_NAPI_FUNCTION("getTrackDescription", GetTrackDescription),
66
67 DECLARE_NAPI_GETTER_SETTER("src", GetSrc, SetSrc),
68 DECLARE_NAPI_GETTER_SETTER("fdSrc", GetFdSrc, SetFdSrc),
69 DECLARE_NAPI_GETTER_SETTER("loop", GetLoop, SetLoop),
70 DECLARE_NAPI_GETTER_SETTER("audioInterruptMode", GetAudioInterruptMode, SetAudioInterruptMode),
71
72 DECLARE_NAPI_GETTER("currentTime", GetCurrentTime),
73 DECLARE_NAPI_GETTER("duration", GetDuration),
74 DECLARE_NAPI_GETTER("state", GetState)
75 };
76
77 napi_property_descriptor staticProperty[] = {
78 DECLARE_NAPI_STATIC_FUNCTION("createAudioPlayer", CreateAudioPlayer),
79 };
80
81 napi_value constructor = nullptr;
82 napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
83 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
84 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define AudioPlayer class");
85
86 status = napi_create_reference(env, constructor, 1, &constructor_);
87 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to create reference of constructor");
88
89 status = napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor);
90 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to set constructor");
91
92 status = napi_define_properties(env, exports, sizeof(staticProperty) / sizeof(staticProperty[0]), staticProperty);
93 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define static function");
94
95 MEDIA_LOGD("Init success");
96 return exports;
97 }
98
Constructor(napi_env env,napi_callback_info info)99 napi_value AudioPlayerNapi::Constructor(napi_env env, napi_callback_info info)
100 {
101 napi_value result = nullptr;
102 napi_value jsThis = nullptr;
103 size_t argCount = 0;
104 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
105 if (status != napi_ok) {
106 napi_get_undefined(env, &result);
107 MEDIA_LOGE("Failed to retrieve details about the callback");
108 return result;
109 }
110
111 AudioPlayerNapi *playerNapi = new(std::nothrow) AudioPlayerNapi();
112 CHECK_AND_RETURN_RET_LOG(playerNapi != nullptr, nullptr, "No memory");
113
114 playerNapi->env_ = env;
115 playerNapi->nativePlayer_ = PlayerFactory::CreatePlayer();
116 if (playerNapi->nativePlayer_ == nullptr) {
117 MEDIA_LOGE("failed to CreatePlayer");
118 }
119
120 if (playerNapi->callbackNapi_ == nullptr && playerNapi->nativePlayer_ != nullptr) {
121 playerNapi->callbackNapi_ = std::make_shared<PlayerCallbackNapi>(env);
122 (void)playerNapi->nativePlayer_->SetPlayerCallback(playerNapi->callbackNapi_);
123 }
124
125 status = napi_wrap(env, jsThis, reinterpret_cast<void *>(playerNapi),
126 AudioPlayerNapi::Destructor, nullptr, nullptr);
127 if (status != napi_ok) {
128 napi_get_undefined(env, &result);
129 delete playerNapi;
130 MEDIA_LOGE("Failed to wrap native instance");
131 return result;
132 }
133
134 MEDIA_LOGD("Constructor success");
135 return jsThis;
136 }
137
Destructor(napi_env env,void * nativeObject,void * finalize)138 void AudioPlayerNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
139 {
140 (void)env;
141 (void)finalize;
142 if (nativeObject != nullptr) {
143 delete reinterpret_cast<AudioPlayerNapi *>(nativeObject);
144 }
145 MEDIA_LOGD("Destructor success");
146 }
147
CreateAudioPlayer(napi_env env,napi_callback_info info)148 napi_value AudioPlayerNapi::CreateAudioPlayer(napi_env env, napi_callback_info info)
149 {
150 napi_value result = nullptr;
151 napi_value constructor = nullptr;
152 napi_status status = napi_get_reference_value(env, constructor_, &constructor);
153 if (status != napi_ok) {
154 MEDIA_LOGE("Failed to get the representation of constructor object");
155 napi_get_undefined(env, &result);
156 return result;
157 }
158
159 status = napi_new_instance(env, constructor, 0, nullptr, &result);
160 if (status != napi_ok) {
161 MEDIA_LOGE("Failed to instantiate JavaScript audio player instance");
162 napi_get_undefined(env, &result);
163 return result;
164 }
165
166 MEDIA_LOGD("CreateAudioPlayer success");
167 return result;
168 }
169
CreateAudioPlayerAsync(napi_env env,napi_callback_info info)170 napi_value AudioPlayerNapi::CreateAudioPlayerAsync(napi_env env, napi_callback_info info)
171 {
172 napi_value result = nullptr;
173 napi_get_undefined(env, &result);
174 MEDIA_LOGD("CreateAudioPlayerAsync In");
175
176 std::unique_ptr<MediaAsyncContext> asyncContext = std::make_unique<MediaAsyncContext>(env);
177
178 // get args
179 napi_value jsThis = nullptr;
180 napi_value args[1] = { nullptr };
181 size_t argCount = 1;
182 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
183 if (status != napi_ok) {
184 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
185 }
186
187 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
188 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
189 asyncContext->JsResult = std::make_unique<MediaJsResultInstance>(constructor_);
190 napi_value resource = nullptr;
191 napi_create_string_utf8(env, "CreateAudioPlayerAsync", NAPI_AUTO_LENGTH, &resource);
192 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {},
193 MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncContext.get()), &asyncContext->work));
194 NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
195 asyncContext.release();
196
197 return result;
198 }
199
SetSrc(napi_env env,napi_callback_info info)200 napi_value AudioPlayerNapi::SetSrc(napi_env env, napi_callback_info info)
201 {
202 napi_value undefinedResult = nullptr;
203 napi_get_undefined(env, &undefinedResult);
204 napi_value jsThis = nullptr;
205 napi_value args[1] = { nullptr };
206
207 size_t argCount = 1;
208 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
209 if (status != napi_ok || jsThis == nullptr || args[0] == nullptr) {
210 MEDIA_LOGE("Failed to retrieve details about the callback");
211 return undefinedResult;
212 }
213
214 AudioPlayerNapi *player = nullptr;
215 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
216 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
217
218 if (player->nativePlayer_ == nullptr) {
219 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
220 return undefinedResult;
221 }
222
223 napi_valuetype valueType = napi_undefined;
224 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_string) {
225 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
226 return undefinedResult;
227 }
228
229 player->uri_ = CommonNapi::GetStringArgument(env, args[0]);
230 const std::string fdHead = "fd://";
231 const std::string httpHead = "http";
232 int32_t ret = MSERR_EXT_INVALID_VAL;
233
234 MEDIA_LOGD("input url is %{public}s!", player->uri_.c_str());
235 if (player->uri_.find(fdHead) != std::string::npos) {
236 int32_t fd = -1;
237 std::string inputFd = player->uri_.substr(fdHead.size());
238 if (!StrToInt(inputFd, fd) || fd < 0) {
239 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
240 return undefinedResult;
241 }
242
243 ret = player->nativePlayer_->SetSource(fd, 0, -1);
244 } else if (player->uri_.find(httpHead) != std::string::npos) {
245 ret = player->nativePlayer_->SetSource(player->uri_);
246 }
247
248 if (ret != MSERR_OK) {
249 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetSource");
250 return undefinedResult;
251 }
252
253 ret = player->nativePlayer_->PrepareAsync();
254 if (ret != MSERR_OK) {
255 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to PrepareAsync");
256 return undefinedResult;
257 }
258
259 return undefinedResult;
260 }
261
GetSrc(napi_env env,napi_callback_info info)262 napi_value AudioPlayerNapi::GetSrc(napi_env env, napi_callback_info info)
263 {
264 napi_value undefinedResult = nullptr;
265 napi_get_undefined(env, &undefinedResult);
266 napi_value jsThis = nullptr;
267 napi_value jsResult = nullptr;
268 AudioPlayerNapi *player = nullptr;
269 size_t argCount = 0;
270
271 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
272 if (status != napi_ok || jsThis == nullptr) {
273 MEDIA_LOGE("Failed to retrieve details about the callback");
274 return undefinedResult;
275 }
276
277 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
278 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
279
280 status = napi_create_string_utf8(env, player->uri_.c_str(), NAPI_AUTO_LENGTH, &jsResult);
281 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_string_utf8 error");
282
283 MEDIA_LOGD("GetSrc success");
284 return jsResult;
285 }
286
SetFdSrc(napi_env env,napi_callback_info info)287 napi_value AudioPlayerNapi::SetFdSrc(napi_env env, napi_callback_info info)
288 {
289 napi_value undefinedResult = nullptr;
290 napi_get_undefined(env, &undefinedResult);
291 napi_value jsThis = nullptr;
292 napi_value args[1] = { nullptr };
293
294 size_t argCount = 1;
295 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
296 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr && args[0] != nullptr,
297 undefinedResult, "Failed to retrieve details about the callback");
298
299 AudioPlayerNapi *player = nullptr;
300 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
301 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
302 if (player->nativePlayer_ == nullptr) {
303 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
304 return undefinedResult;
305 }
306
307 napi_valuetype valueType = napi_undefined;
308 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_object) {
309 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
310 return undefinedResult;
311 }
312
313 if (!CommonNapi::GetFdArgument(env, args[0], player->rawFd_)) {
314 MEDIA_LOGE("get rawfd argument failed!");
315 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
316 return undefinedResult;
317 }
318
319 int32_t ret = player->nativePlayer_->SetSource(player->rawFd_.fd, player->rawFd_.offset, player->rawFd_.length);
320 if (ret != MSERR_OK) {
321 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetSource rawFd");
322 return undefinedResult;
323 }
324
325 ret = player->nativePlayer_->PrepareAsync();
326 if (ret != MSERR_OK) {
327 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to PrepareAsync");
328 return undefinedResult;
329 }
330
331 MEDIA_LOGD("SetFdSrc success");
332 return undefinedResult;
333 }
334
GetFdSrc(napi_env env,napi_callback_info info)335 napi_value AudioPlayerNapi::GetFdSrc(napi_env env, napi_callback_info info)
336 {
337 napi_value undefinedResult = nullptr;
338 napi_get_undefined(env, &undefinedResult);
339 napi_value jsThis = nullptr;
340 napi_value jsResult = nullptr;
341 AudioPlayerNapi *player = nullptr;
342 size_t argCount = 0;
343
344 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
345 if (status != napi_ok || jsThis == nullptr) {
346 MEDIA_LOGE("Failed to retrieve details about the callback");
347 return undefinedResult;
348 }
349
350 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
351 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
352
353 status = napi_create_object(env, &jsResult);
354 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "create jsResult object error");
355
356 CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt32(env, jsResult, "fd", player->rawFd_.fd) == true, nullptr);
357 CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt64(env, jsResult, "offset", player->rawFd_.offset) == true,
358 nullptr);
359 CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt64(env, jsResult, "length", player->rawFd_.length) == true,
360 nullptr);
361
362 MEDIA_LOGD("GetFdSrc success");
363 return jsResult;
364 }
365
Play(napi_env env,napi_callback_info info)366 napi_value AudioPlayerNapi::Play(napi_env env, napi_callback_info info)
367 {
368 napi_value undefinedResult = nullptr;
369 napi_get_undefined(env, &undefinedResult);
370
371 size_t argCount = 0;
372 napi_value jsThis = nullptr;
373 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
374 if (status != napi_ok || jsThis == nullptr) {
375 MEDIA_LOGE("Failed to retrieve details about the callback");
376 return undefinedResult;
377 }
378
379 AudioPlayerNapi *player = nullptr;
380 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
381 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
382
383 if (player->nativePlayer_ == nullptr) {
384 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
385 return undefinedResult;
386 }
387 #ifdef SUPPORT_JSSTACK
388 HiviewDFX::ReportXPowerJsStackSysEvent(env, "STREAM_CHANGE", "SRC=Media");
389 #endif
390 int32_t ret = player->nativePlayer_->Play();
391 if (ret != MSERR_OK) {
392 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Play");
393 return undefinedResult;
394 }
395 MEDIA_LOGD("Play success");
396 return undefinedResult;
397 }
398
Pause(napi_env env,napi_callback_info info)399 napi_value AudioPlayerNapi::Pause(napi_env env, napi_callback_info info)
400 {
401 napi_value undefinedResult = nullptr;
402 napi_get_undefined(env, &undefinedResult);
403
404 size_t argCount = 0;
405 napi_value jsThis = nullptr;
406 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
407 if (status != napi_ok || jsThis == nullptr) {
408 MEDIA_LOGE("Failed to retrieve details about the callback");
409 return undefinedResult;
410 }
411
412 AudioPlayerNapi *player = nullptr;
413 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
414 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
415
416 if (player->nativePlayer_ == nullptr) {
417 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
418 return undefinedResult;
419 }
420 int32_t ret = player->nativePlayer_->Pause();
421 if (ret != MSERR_OK) {
422 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Pause");
423 return undefinedResult;
424 }
425 MEDIA_LOGD("Pause success");
426 return undefinedResult;
427 }
428
Stop(napi_env env,napi_callback_info info)429 napi_value AudioPlayerNapi::Stop(napi_env env, napi_callback_info info)
430 {
431 napi_value undefinedResult = nullptr;
432 napi_get_undefined(env, &undefinedResult);
433
434 size_t argCount = 0;
435 napi_value jsThis = nullptr;
436 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
437 if (status != napi_ok || jsThis == nullptr) {
438 MEDIA_LOGE("Failed to retrieve details about the callback");
439 return undefinedResult;
440 }
441
442 AudioPlayerNapi *player = nullptr;
443 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
444 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
445
446 if (player->nativePlayer_ == nullptr) {
447 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
448 return undefinedResult;
449 }
450 int32_t ret = player->nativePlayer_->Stop();
451 if (ret != MSERR_OK) {
452 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Stop");
453 return undefinedResult;
454 }
455 MEDIA_LOGD("Stop success");
456 return undefinedResult;
457 }
458
Reset(napi_env env,napi_callback_info info)459 napi_value AudioPlayerNapi::Reset(napi_env env, napi_callback_info info)
460 {
461 MEDIA_LOGD("AudioPlayerNapi Reset");
462 napi_value undefinedResult = nullptr;
463 napi_get_undefined(env, &undefinedResult);
464
465 size_t argCount = 0;
466 napi_value jsThis = nullptr;
467 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
468 if (status != napi_ok || jsThis == nullptr) {
469 MEDIA_LOGE("Failed to retrieve details about the callback");
470 return undefinedResult;
471 }
472
473 AudioPlayerNapi *player = nullptr;
474 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
475 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
476
477 if (player->nativePlayer_ == nullptr) {
478 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
479 return undefinedResult;
480 }
481
482 int32_t ret = player->nativePlayer_->Reset();
483 if (ret != MSERR_OK) {
484 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Reset");
485 return undefinedResult;
486 }
487 MEDIA_LOGD("Reset success");
488 return undefinedResult;
489 }
490
Release(napi_env env,napi_callback_info info)491 napi_value AudioPlayerNapi::Release(napi_env env, napi_callback_info info)
492 {
493 napi_value undefinedResult = nullptr;
494 napi_get_undefined(env, &undefinedResult);
495
496 size_t argCount = 0;
497 napi_value jsThis = nullptr;
498 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
499 if (status != napi_ok || jsThis == nullptr) {
500 MEDIA_LOGE("Failed to retrieve details about the callback");
501 return undefinedResult;
502 }
503
504 AudioPlayerNapi *player = nullptr;
505 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
506 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "get player napi error");
507
508 if (player->nativePlayer_ == nullptr) {
509 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
510 return undefinedResult;
511 }
512
513 (void)player->nativePlayer_->Release();
514 player->CancelCallback();
515 player->callbackNapi_ = nullptr;
516 player->nativePlayer_ = nullptr;
517 player->uri_.clear();
518 MEDIA_LOGD("Release success");
519 return undefinedResult;
520 }
521
Seek(napi_env env,napi_callback_info info)522 napi_value AudioPlayerNapi::Seek(napi_env env, napi_callback_info info)
523 {
524 napi_value undefinedResult = nullptr;
525 napi_get_undefined(env, &undefinedResult);
526
527 size_t argCount = 1;
528 napi_value args[1] = { nullptr };
529 napi_value jsThis = nullptr;
530
531 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
532 if (status != napi_ok || jsThis == nullptr || args[0] == nullptr) {
533 MEDIA_LOGE("Failed to retrieve details about the callback");
534 return undefinedResult;
535 }
536
537 AudioPlayerNapi *player = nullptr;
538 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
539 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
540 if (player->nativePlayer_ == nullptr) {
541 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
542 return undefinedResult;
543 }
544
545 napi_valuetype valueType = napi_undefined;
546 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
547 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
548 return undefinedResult;
549 }
550
551 int32_t position = -1;
552 status = napi_get_value_int32(env, args[0], &position);
553 if (status != napi_ok || position < 0) {
554 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
555 return undefinedResult;
556 }
557
558 int32_t ret = player->nativePlayer_->Seek(position, SEEK_PREVIOUS_SYNC);
559 if (ret != MSERR_OK) {
560 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to Seek");
561 return undefinedResult;
562 }
563
564 MEDIA_LOGD("Seek success");
565 return undefinedResult;
566 }
567
SetVolume(napi_env env,napi_callback_info info)568 napi_value AudioPlayerNapi::SetVolume(napi_env env, napi_callback_info info)
569 {
570 napi_value undefinedResult = nullptr;
571 napi_get_undefined(env, &undefinedResult);
572
573 size_t argCount = 1;
574 napi_value args[1] = { nullptr };
575 napi_value jsThis = nullptr;
576
577 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
578 if (status != napi_ok || jsThis == nullptr || args[0] == nullptr) {
579 MEDIA_LOGE("Failed to retrieve details about the callback");
580 return undefinedResult;
581 }
582
583 AudioPlayerNapi *player = nullptr;
584 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
585 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
586
587 if (player->nativePlayer_ == nullptr) {
588 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
589 return undefinedResult;
590 }
591
592 napi_valuetype valueType = napi_undefined;
593 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
594 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
595 return undefinedResult;
596 }
597
598 double volumeLevel;
599 status = napi_get_value_double(env, args[0], &volumeLevel);
600 if (status != napi_ok || volumeLevel < 0.0f || volumeLevel > 1.0f) {
601 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
602 return undefinedResult;
603 }
604 #ifdef SUPPORT_JSSTACK
605 HiviewDFX::ReportXPowerJsStackSysEvent(env, "VOLUME_CHANGE", "SRC=Media");
606 #endif
607 int32_t ret = player->nativePlayer_->SetVolume(static_cast<float>(volumeLevel), static_cast<float>(volumeLevel));
608 if (ret != MSERR_OK) {
609 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetVolume");
610 return undefinedResult;
611 }
612 MEDIA_LOGD("SetVolume success");
613 return undefinedResult;
614 }
615
On(napi_env env,napi_callback_info info)616 napi_value AudioPlayerNapi::On(napi_env env, napi_callback_info info)
617 {
618 napi_value undefinedResult = nullptr;
619 napi_get_undefined(env, &undefinedResult);
620
621 static constexpr size_t minArgCount = 2;
622 size_t argCount = minArgCount;
623 napi_value args[minArgCount] = { nullptr, nullptr };
624 napi_value jsThis = nullptr;
625 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
626 if (status != napi_ok || jsThis == nullptr || args[0] == nullptr || args[1] == nullptr) {
627 MEDIA_LOGE("Failed to retrieve details about the callback");
628 return undefinedResult;
629 }
630
631 AudioPlayerNapi *player = nullptr;
632 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
633 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
634
635 napi_valuetype valueType0 = napi_undefined;
636 napi_valuetype valueType1 = napi_undefined;
637 if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string ||
638 napi_typeof(env, args[1], &valueType1) != napi_ok || valueType1 != napi_function) {
639 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
640 return undefinedResult;
641 }
642
643 std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
644 MEDIA_LOGD("callbackName: %{public}s", callbackName.c_str());
645
646 napi_ref ref = nullptr;
647 status = napi_create_reference(env, args[1], 1, &ref);
648 CHECK_AND_RETURN_RET_LOG(status == napi_ok && ref != nullptr, undefinedResult, "failed to create reference!");
649
650 std::shared_ptr<AutoRef> autoRef = std::make_shared<AutoRef>(env, ref);
651 player->SetCallbackReference(callbackName, autoRef);
652 return undefinedResult;
653 }
654
SetLoop(napi_env env,napi_callback_info info)655 napi_value AudioPlayerNapi::SetLoop(napi_env env, napi_callback_info info)
656 {
657 size_t argCount = 1;
658 napi_value args[1] = { nullptr };
659 napi_value jsThis = nullptr;
660 napi_value undefinedResult = nullptr;
661 napi_get_undefined(env, &undefinedResult);
662
663 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
664 if (status != napi_ok || jsThis == nullptr || args[0] == nullptr) {
665 MEDIA_LOGE("Failed to retrieve details about the callback");
666 return undefinedResult;
667 }
668
669 AudioPlayerNapi *player = nullptr;
670 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
671 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
672
673 if (player->nativePlayer_ == nullptr) {
674 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
675 return undefinedResult;
676 }
677
678 napi_valuetype valueType = napi_undefined;
679 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_boolean) {
680 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
681 return undefinedResult;
682 }
683
684 bool loopFlag = false;
685 status = napi_get_value_bool(env, args[0], &loopFlag);
686 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_value_bool error");
687
688 int32_t ret = player->nativePlayer_->SetLooping(loopFlag);
689 if (ret != MSERR_OK) {
690 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetLooping");
691 return undefinedResult;
692 }
693
694 MEDIA_LOGD("SetLoop success");
695 return undefinedResult;
696 }
697
698
GetLoop(napi_env env,napi_callback_info info)699 napi_value AudioPlayerNapi::GetLoop(napi_env env, napi_callback_info info)
700 {
701 napi_value jsThis = nullptr;
702 napi_value jsResult = nullptr;
703 napi_value undefinedResult = nullptr;
704 napi_get_undefined(env, &undefinedResult);
705
706 size_t argCount = 0;
707 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
708 if (status != napi_ok || jsThis == nullptr) {
709 MEDIA_LOGE("Failed to retrieve details about the callback");
710 return undefinedResult;
711 }
712
713 AudioPlayerNapi *player = nullptr;
714 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
715 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
716
717 if (player->nativePlayer_ == nullptr) {
718 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
719 return undefinedResult;
720 }
721 bool loopFlag = player->nativePlayer_->IsLooping();
722
723 status = napi_get_boolean(env, loopFlag, &jsResult);
724 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_boolean error");
725
726 MEDIA_LOGD("GetSrc success loop Status: %{public}d", loopFlag);
727 return jsResult;
728 }
729
GetCurrentTime(napi_env env,napi_callback_info info)730 napi_value AudioPlayerNapi::GetCurrentTime(napi_env env, napi_callback_info info)
731 {
732 napi_value jsThis = nullptr;
733 napi_value undefinedResult = nullptr;
734 napi_get_undefined(env, &undefinedResult);
735
736 size_t argCount = 0;
737 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
738 if (status != napi_ok || jsThis == nullptr) {
739 MEDIA_LOGE("Failed to retrieve details about the callback");
740 return undefinedResult;
741 }
742
743 AudioPlayerNapi *player = nullptr;
744 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
745 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
746
747 if (player->nativePlayer_ == nullptr) {
748 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
749 return undefinedResult;
750 }
751 int32_t currentTime = -1;
752 (void)player->nativePlayer_->GetCurrentTime(currentTime);
753
754 napi_value jsResult = nullptr;
755 status = napi_create_int32(env, currentTime, &jsResult);
756 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int32 error");
757
758 MEDIA_LOGD("GetCurrenTime success, Current time: %{public}d", currentTime);
759 return jsResult;
760 }
761
GetDuration(napi_env env,napi_callback_info info)762 napi_value AudioPlayerNapi::GetDuration(napi_env env, napi_callback_info info)
763 {
764 napi_value jsThis = nullptr;
765 napi_value jsResult = nullptr;
766 napi_value undefinedResult = nullptr;
767 napi_get_undefined(env, &undefinedResult);
768
769 size_t argCount = 0;
770 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
771 if (status != napi_ok || jsThis == nullptr) {
772 MEDIA_LOGE("Failed to retrieve details about the callback");
773 return undefinedResult;
774 }
775
776 AudioPlayerNapi *player = nullptr;
777 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
778 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
779
780 if (player->nativePlayer_ == nullptr) {
781 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
782 return undefinedResult;
783 }
784 int32_t duration = -1;
785 (void)player->nativePlayer_->GetDuration(duration);
786
787 status = napi_create_int32(env, duration, &jsResult);
788 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int64 error");
789
790 MEDIA_LOGD("GetDuration success, Current time: %{public}d", duration);
791 return jsResult;
792 }
793
GetJSState(PlayerStates currentState)794 static std::string GetJSState(PlayerStates currentState)
795 {
796 std::string result;
797
798 MEDIA_LOGD("GetJSState()! is called!, %{public}d", currentState);
799 switch (currentState) {
800 case PLAYER_IDLE:
801 case PLAYER_INITIALIZED:
802 case PLAYER_PREPARING:
803 case PLAYER_PREPARED:
804 result = STATE_IDLE;
805 break;
806 case PLAYER_STARTED:
807 result = STATE_PLAYING;
808 break;
809 case PLAYER_PAUSED:
810 result = STATE_PAUSED;
811 break;
812 case PLAYER_STOPPED:
813 case PLAYER_PLAYBACK_COMPLETE:
814 result = STATE_STOPPED;
815 break;
816 default:
817 // Considering default state as stopped
818 MEDIA_LOGE("Error state! %{public}d", currentState);
819 result = STATE_ERROR;
820 break;
821 }
822 return result;
823 }
824
GetState(napi_env env,napi_callback_info info)825 napi_value AudioPlayerNapi::GetState(napi_env env, napi_callback_info info)
826 {
827 napi_value jsThis = nullptr;
828 napi_value jsResult = nullptr;
829 napi_value undefinedResult = nullptr;
830 std::string curState;
831 napi_get_undefined(env, &undefinedResult);
832
833 size_t argCount = 0;
834 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
835 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "Failed to retrieve details about the callback");
836
837 AudioPlayerNapi *player = nullptr;
838 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
839 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "Failed to retrieve instance");
840
841 if (player->callbackNapi_ == nullptr) {
842 return undefinedResult;
843 } else {
844 std::shared_ptr<PlayerCallbackNapi> cb = std::static_pointer_cast<PlayerCallbackNapi>(player->callbackNapi_);
845 curState = GetJSState(cb->GetCurrentState());
846 MEDIA_LOGD("GetState success, State: %{public}s", curState.c_str());
847 }
848 status = napi_create_string_utf8(env, curState.c_str(), NAPI_AUTO_LENGTH, &jsResult);
849 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_string_utf8 error");
850 return jsResult;
851 }
852
ErrorCallback(MediaServiceExtErrCode errCode,std::string errMsg)853 void AudioPlayerNapi::ErrorCallback(MediaServiceExtErrCode errCode, std::string errMsg)
854 {
855 if (callbackNapi_ != nullptr) {
856 std::shared_ptr<PlayerCallbackNapi> napiCb = std::static_pointer_cast<PlayerCallbackNapi>(callbackNapi_);
857 napiCb->SendErrorCallback(errCode, errMsg);
858 }
859 }
860
AsyncGetTrackDescription(napi_env env,void * data)861 void AudioPlayerNapi::AsyncGetTrackDescription(napi_env env, void *data)
862 {
863 auto asyncContext = reinterpret_cast<AudioPlayerAsyncContext *>(data);
864 CHECK_AND_RETURN_LOG(asyncContext != nullptr, "AudioPlayerAsyncContext is nullptr!");
865
866 if (asyncContext->jsPlayer == nullptr) {
867 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "jsPlayer is destroyed(null), please check js_runtime");
868 return;
869 }
870
871 if (asyncContext->jsPlayer->nativePlayer_ == nullptr) {
872 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "nativePlayer is released(null), please create player again");
873 return;
874 }
875
876 auto player = asyncContext->jsPlayer->nativePlayer_;
877 std::vector<Format> &audioInfo = asyncContext->jsPlayer->audioTrackInfoVec_;
878 audioInfo.clear();
879 int32_t ret = player->GetAudioTrackInfo(audioInfo);
880 if (ret != MSERR_OK) {
881 asyncContext->SignError(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)),
882 "failed to GetAudioTrackInfo");
883 return;
884 }
885
886 if (audioInfo.empty()) {
887 asyncContext->SignError(MSERR_EXT_OPERATE_NOT_PERMIT, "audio track info is empty");
888 return;
889 }
890
891 asyncContext->JsResult = std::make_unique<MediaJsResultArray>(audioInfo);
892 MEDIA_LOGD("AsyncGetTrackDescription Out");
893 }
894
GetTrackDescription(napi_env env,napi_callback_info info)895 napi_value AudioPlayerNapi::GetTrackDescription(napi_env env, napi_callback_info info)
896 {
897 napi_value result = nullptr;
898 napi_get_undefined(env, &result);
899
900 MEDIA_LOGD("GetTrackDescription In");
901 std::unique_ptr<AudioPlayerAsyncContext> asyncContext = std::make_unique<AudioPlayerAsyncContext>(env);
902
903 // get args
904 napi_value jsThis = nullptr;
905 napi_value args[1] = { nullptr };
906 size_t argCount = 1;
907 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
908 if (status != napi_ok || jsThis == nullptr) {
909 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
910 }
911
912 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
913 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
914 // get jsPlayer
915 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
916 // async work
917 napi_value resource = nullptr;
918 napi_create_string_utf8(env, "GetTrackDescription", NAPI_AUTO_LENGTH, &resource);
919 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, AudioPlayerNapi::AsyncGetTrackDescription,
920 MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncContext.get()), &asyncContext->work));
921 NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
922 asyncContext.release();
923 return result;
924 }
925
SetAudioInterruptMode(napi_env env,napi_callback_info info)926 napi_value AudioPlayerNapi::SetAudioInterruptMode(napi_env env, napi_callback_info info)
927 {
928 size_t argCount = 1;
929 napi_value args[1] = { nullptr };
930 napi_value jsThis = nullptr;
931 napi_value undefinedResult = nullptr;
932 napi_get_undefined(env, &undefinedResult);
933
934 MEDIA_LOGD("SetAudioInterruptMode In");
935 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
936 if (status != napi_ok || jsThis == nullptr || args[0] == nullptr) {
937 MEDIA_LOGE("Failed to retrieve details about the callback");
938 return undefinedResult;
939 }
940
941 AudioPlayerNapi *player = nullptr;
942 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
943 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
944
945 if (player->nativePlayer_ == nullptr) {
946 player->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
947 return undefinedResult;
948 }
949
950 napi_valuetype valueType = napi_undefined;
951 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
952 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
953 return undefinedResult;
954 }
955
956 int32_t interruptMode = 0;
957 status = napi_get_value_int32(env, args[0], &interruptMode);
958 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_value_int32 error");
959
960 if (interruptMode < AudioStandard::InterruptMode::SHARE_MODE ||
961 interruptMode > AudioStandard::InterruptMode::INDEPENDENT_MODE) {
962 player->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
963 return undefinedResult;
964 }
965
966 player->interruptMode_ = AudioStandard::InterruptMode(interruptMode);
967 Format format;
968 (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_MODE, interruptMode);
969 int32_t ret = player->nativePlayer_->SetParameter(format);
970 if (ret != MSERR_OK) {
971 player->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetParameter");
972 return undefinedResult;
973 }
974
975 MEDIA_LOGD("SetAudioInterruptMode success");
976 return undefinedResult;
977 }
978
GetAudioInterruptMode(napi_env env,napi_callback_info info)979 napi_value AudioPlayerNapi::GetAudioInterruptMode(napi_env env, napi_callback_info info)
980 {
981 napi_value jsThis = nullptr;
982 napi_value jsResult = nullptr;
983 napi_value undefinedResult = nullptr;
984 napi_get_undefined(env, &undefinedResult);
985
986 size_t argCount = 0;
987 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
988 if (status != napi_ok || jsThis == nullptr) {
989 MEDIA_LOGE("Failed to retrieve details about the callback");
990 return undefinedResult;
991 }
992
993 AudioPlayerNapi *player = nullptr;
994 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
995 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
996
997 status = napi_create_object(env, &jsResult);
998 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "create jsresult object error");
999
1000 CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt32(env, jsResult, "InterruptMode",
1001 player->interruptMode_) == true, nullptr);
1002 MEDIA_LOGD("GetAudioInterruptMode success");
1003 return jsResult;
1004 }
1005
SetCallbackReference(const std::string & callbackName,std::shared_ptr<AutoRef> ref)1006 void AudioPlayerNapi::SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref)
1007 {
1008 refMap_[callbackName] = ref;
1009 if (callbackNapi_ != nullptr) {
1010 std::shared_ptr<PlayerCallbackNapi> napiCb = std::static_pointer_cast<PlayerCallbackNapi>(callbackNapi_);
1011 napiCb->SaveCallbackReference(callbackName, ref);
1012 }
1013 }
1014
CancelCallback()1015 void AudioPlayerNapi::CancelCallback()
1016 {
1017 if (callbackNapi_ != nullptr) {
1018 std::shared_ptr<PlayerCallbackNapi> napiCb = std::static_pointer_cast<PlayerCallbackNapi>(callbackNapi_);
1019 napiCb->ClearCallbackReference();
1020 }
1021 }
1022 } // namespace Media
1023 } // namespace OHOS
1024