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