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 "video_player_napi.h"
17 #include <climits>
18 #include "video_callback_napi.h"
19 #include "media_log.h"
20 #include "media_errors.h"
21 #include "surface_utils.h"
22 #include "string_ex.h"
23 #include "meta/video_types.h"
24 #include "js_common_utils.h"
25 #ifdef SUPPORT_JSSTACK
26 #include "xpower_event_js.h"
27 #endif
28
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "VideoPlayerNapi"};
31 }
32
33 namespace OHOS {
34 namespace Media {
35 namespace VideoPlayState {
36 const std::string STATE_IDLE = "idle";
37 const std::string STATE_PREPARED = "prepared";
38 const std::string STATE_PLAYING = "playing";
39 const std::string STATE_PAUSED = "paused";
40 const std::string STATE_STOPPED = "stopped";
41 const std::string STATE_ERROR = "error";
42 };
43 thread_local napi_ref VideoPlayerNapi::constructor_ = nullptr;
44 const std::string CLASS_NAME = "VideoPlayer";
45
GetJSState(PlayerStates currentState)46 static std::string GetJSState(PlayerStates currentState)
47 {
48 std::string result;
49 MEDIA_LOGD("GetJSState()! is called!, %{public}d", currentState);
50 switch (currentState) {
51 case PLAYER_IDLE:
52 case PLAYER_INITIALIZED:
53 result = VideoPlayState::STATE_IDLE;
54 break;
55 case PLAYER_PREPARED:
56 result = VideoPlayState::STATE_PREPARED;
57 break;
58 case PLAYER_STARTED:
59 result = VideoPlayState::STATE_PLAYING;
60 break;
61 case PLAYER_PAUSED:
62 result = VideoPlayState::STATE_PAUSED;
63 break;
64 case PLAYER_STOPPED:
65 case PLAYER_PLAYBACK_COMPLETE:
66 result = VideoPlayState::STATE_STOPPED;
67 break;
68 default:
69 // Considering default state as stopped
70 MEDIA_LOGE("Error state! %{public}d", currentState);
71 result = VideoPlayState::STATE_ERROR;
72 break;
73 }
74 return result;
75 }
76
VideoPlayerNapi()77 VideoPlayerNapi::VideoPlayerNapi()
78 {
79 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
80 }
81
~VideoPlayerNapi()82 VideoPlayerNapi::~VideoPlayerNapi()
83 {
84 CancelCallback();
85 nativePlayer_ = nullptr;
86 jsCallback_ = nullptr;
87
88 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
89 }
90
Init(napi_env env,napi_value exports)91 napi_value VideoPlayerNapi::Init(napi_env env, napi_value exports)
92 {
93 napi_property_descriptor staticProperty[] = {
94 DECLARE_NAPI_STATIC_FUNCTION("createVideoPlayer", CreateVideoPlayer),
95 };
96
97 napi_property_descriptor properties[] = {
98 DECLARE_NAPI_FUNCTION("setDisplaySurface", SetDisplaySurface),
99 DECLARE_NAPI_FUNCTION("prepare", Prepare),
100 DECLARE_NAPI_FUNCTION("play", Play),
101 DECLARE_NAPI_FUNCTION("pause", Pause),
102 DECLARE_NAPI_FUNCTION("stop", Stop),
103 DECLARE_NAPI_FUNCTION("reset", Reset),
104 DECLARE_NAPI_FUNCTION("release", Release),
105 DECLARE_NAPI_FUNCTION("seek", Seek),
106 DECLARE_NAPI_FUNCTION("on", On),
107 DECLARE_NAPI_FUNCTION("setVolume", SetVolume),
108 DECLARE_NAPI_FUNCTION("getTrackDescription", GetTrackDescription),
109 DECLARE_NAPI_FUNCTION("setSpeed", SetSpeed),
110 DECLARE_NAPI_FUNCTION("selectBitrate", SelectBitrate),
111
112 DECLARE_NAPI_GETTER_SETTER("url", GetUrl, SetUrl),
113 DECLARE_NAPI_GETTER_SETTER("fdSrc", GetFdSrc, SetFdSrc),
114 DECLARE_NAPI_GETTER_SETTER("loop", GetLoop, SetLoop),
115 DECLARE_NAPI_GETTER_SETTER("videoScaleType", GetVideoScaleType, SetVideoScaleType),
116 DECLARE_NAPI_GETTER_SETTER("audioInterruptMode", GetAudioInterruptMode, SetAudioInterruptMode),
117
118 DECLARE_NAPI_GETTER("currentTime", GetCurrentTime),
119 DECLARE_NAPI_GETTER("duration", GetDuration),
120 DECLARE_NAPI_GETTER("state", GetState),
121 DECLARE_NAPI_GETTER("width", GetWidth),
122 DECLARE_NAPI_GETTER("height", GetHeight),
123 };
124
125 napi_value constructor = nullptr;
126 napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
127 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
128 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define AudioPlayer class");
129
130 status = napi_create_reference(env, constructor, 1, &constructor_);
131 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to create reference of constructor");
132
133 status = napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor);
134 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to set constructor");
135
136 status = napi_define_properties(env, exports, sizeof(staticProperty) / sizeof(staticProperty[0]), staticProperty);
137 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define static function");
138
139 MEDIA_LOGD("Init success");
140 return exports;
141 }
142
Constructor(napi_env env,napi_callback_info info)143 napi_value VideoPlayerNapi::Constructor(napi_env env, napi_callback_info info)
144 {
145 napi_value result = nullptr;
146 napi_value jsThis = nullptr;
147 size_t argCount = 0;
148 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
149 if (status != napi_ok) {
150 napi_get_undefined(env, &result);
151 MEDIA_LOGE("Failed to retrieve details about the callback");
152 return result;
153 }
154
155 VideoPlayerNapi *jsPlayer = new(std::nothrow) VideoPlayerNapi();
156 CHECK_AND_RETURN_RET_LOG(jsPlayer != nullptr, nullptr, "failed to new VideoPlayerNapi");
157
158 jsPlayer->env_ = env;
159 jsPlayer->nativePlayer_ = PlayerFactory::CreatePlayer();
160 if (jsPlayer->nativePlayer_ == nullptr) {
161 MEDIA_LOGE("failed to CreatePlayer");
162 }
163
164 if (jsPlayer->jsCallback_ == nullptr && jsPlayer->nativePlayer_ != nullptr) {
165 jsPlayer->jsCallback_ = std::make_shared<VideoCallbackNapi>(env);
166 (void)jsPlayer->nativePlayer_->SetPlayerCallback(jsPlayer->jsCallback_);
167 }
168
169 status = napi_wrap(env, jsThis, reinterpret_cast<void *>(jsPlayer),
170 VideoPlayerNapi::Destructor, nullptr, nullptr);
171 if (status != napi_ok) {
172 napi_get_undefined(env, &result);
173 delete jsPlayer;
174 MEDIA_LOGE("Failed to wrap native instance");
175 return result;
176 }
177
178 MEDIA_LOGD("Constructor success");
179 return jsThis;
180 }
181
Destructor(napi_env env,void * nativeObject,void * finalize)182 void VideoPlayerNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
183 {
184 (void)env;
185 (void)finalize;
186 if (nativeObject != nullptr) {
187 delete reinterpret_cast<VideoPlayerNapi *>(nativeObject);
188 }
189 MEDIA_LOGD("Destructor success");
190 }
191
CreateVideoPlayer(napi_env env,napi_callback_info info)192 napi_value VideoPlayerNapi::CreateVideoPlayer(napi_env env, napi_callback_info info)
193 {
194 napi_value result = nullptr;
195 napi_get_undefined(env, &result);
196 MEDIA_LOGD("CreateVideoPlayer In");
197
198 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
199
200 // get args
201 napi_value jsThis = nullptr;
202 napi_value args[1] = { nullptr };
203 size_t argCount = 1;
204 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
205 if (status != napi_ok) {
206 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
207 }
208
209 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
210 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
211 asyncContext->JsResult = std::make_unique<MediaJsResultInstance>(constructor_);
212 auto ret = MediaAsyncContext::SendCompleteEvent(env, asyncContext.get(), napi_eprio_high);
213 if (ret != napi_status::napi_ok) {
214 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
215 } else {
216 asyncContext.release();
217 }
218
219 return result;
220 }
221
SetUrl(napi_env env,napi_callback_info info)222 napi_value VideoPlayerNapi::SetUrl(napi_env env, napi_callback_info info)
223 {
224 napi_value undefinedResult = nullptr;
225 napi_get_undefined(env, &undefinedResult);
226 MEDIA_LOGD("SetUrl In");
227 // get args and jsThis
228 napi_value jsThis = nullptr;
229 napi_value args[1] = { nullptr };
230 size_t argCount = 1;
231 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
232 if (status != napi_ok || jsThis == nullptr) {
233 MEDIA_LOGE("Failed to retrieve details about the callback");
234 return undefinedResult;
235 }
236
237 // get VideoPlayerNapi
238 VideoPlayerNapi *jsPlayer = nullptr;
239 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
240 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
241 if (jsPlayer->nativePlayer_ == nullptr) {
242 jsPlayer->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
243 return undefinedResult;
244 }
245 napi_valuetype valueType = napi_undefined;
246 if (argCount < 1 || napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_string) {
247 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
248 return undefinedResult;
249 }
250 // get url from js
251 jsPlayer->url_ = CommonNapi::GetStringArgument(env, args[0]);
252
253 const std::string fdHead = "fd://";
254 const std::string httpHead = "http";
255 int32_t ret = MSERR_EXT_INVALID_VAL;
256 MEDIA_LOGD("input url is %{private}s!", jsPlayer->url_.c_str());
257 if (jsPlayer->url_.find(fdHead) != std::string::npos) {
258 std::string inputFd = jsPlayer->url_.substr(fdHead.size());
259 int32_t fd = -1;
260 if (!StrToInt(inputFd, fd) || fd < 0) {
261 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
262 return undefinedResult;
263 }
264
265 ret = jsPlayer->nativePlayer_->SetSource(fd, 0, -1);
266 } else if (jsPlayer->url_.find(httpHead) != std::string::npos) {
267 ret = jsPlayer->nativePlayer_->SetSource(jsPlayer->url_);
268 }
269
270 if (ret != MSERR_OK) {
271 MEDIA_LOGE("input url error!");
272 jsPlayer->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to set source");
273 return undefinedResult;
274 }
275
276 MEDIA_LOGD("SetUrl success");
277 return undefinedResult;
278 }
279
GetUrl(napi_env env,napi_callback_info info)280 napi_value VideoPlayerNapi::GetUrl(napi_env env, napi_callback_info info)
281 {
282 napi_value undefinedResult = nullptr;
283 napi_get_undefined(env, &undefinedResult);
284
285 // get jsThis
286 napi_value jsThis = nullptr;
287 size_t argCount = 0;
288 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
289 if (status != napi_ok || jsThis == nullptr) {
290 MEDIA_LOGE("failed to napi_get_cb_info");
291 return undefinedResult;
292 }
293
294 // get VideoPlayerNapi
295 VideoPlayerNapi *jsPlayer = nullptr;
296 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
297 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
298
299 napi_value jsResult = nullptr;
300 status = napi_create_string_utf8(env, jsPlayer->url_.c_str(), NAPI_AUTO_LENGTH, &jsResult);
301 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_string_utf8 error");
302
303 MEDIA_LOGD("GetSrc success");
304 return jsResult;
305 }
306
SetFdSrc(napi_env env,napi_callback_info info)307 napi_value VideoPlayerNapi::SetFdSrc(napi_env env, napi_callback_info info)
308 {
309 napi_value undefinedResult = nullptr;
310 napi_get_undefined(env, &undefinedResult);
311
312 // get args and jsThis
313 napi_value jsThis = nullptr;
314 napi_value args[1] = { nullptr };
315 size_t argCount = 1;
316 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
317 if (status != napi_ok || jsThis == nullptr) {
318 MEDIA_LOGE("Failed to retrieve details about the callback");
319 return undefinedResult;
320 }
321
322 // get VideoPlayerNapi
323 VideoPlayerNapi *jsPlayer = nullptr;
324 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
325 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
326 if (jsPlayer->nativePlayer_ == nullptr) {
327 jsPlayer->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
328 return undefinedResult;
329 }
330 // get url from js
331 napi_valuetype valueType = napi_undefined;
332 if (argCount < 1 || napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_object) {
333 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
334 return undefinedResult;
335 }
336
337 if (!CommonNapi::GetFdArgument(env, args[0], jsPlayer->rawFd_)) {
338 MEDIA_LOGE("get rawfd argument failed!");
339 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
340 return undefinedResult;
341 }
342
343 // set url to server
344 int32_t ret = jsPlayer->nativePlayer_->SetSource(jsPlayer->rawFd_.fd, jsPlayer->rawFd_.offset,
345 jsPlayer->rawFd_.length);
346 if (ret != MSERR_OK) {
347 jsPlayer->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetSource");
348 return undefinedResult;
349 }
350
351 MEDIA_LOGD("SetFdSrc success");
352 return undefinedResult;
353 }
354
GetFdSrc(napi_env env,napi_callback_info info)355 napi_value VideoPlayerNapi::GetFdSrc(napi_env env, napi_callback_info info)
356 {
357 napi_value undefinedResult = nullptr;
358 napi_get_undefined(env, &undefinedResult);
359
360 // get jsThis
361 napi_value jsThis = nullptr;
362 size_t argCount = 0;
363 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
364 if (status != napi_ok || jsThis == nullptr) {
365 MEDIA_LOGE("failed to napi_get_cb_info");
366 return undefinedResult;
367 }
368
369 // get VideoPlayerNapi
370 VideoPlayerNapi *jsPlayer = nullptr;
371 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
372 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
373
374 napi_value jsResult = nullptr;
375 status = napi_create_object(env, &jsResult);
376 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "create jsResult object error");
377
378 CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt32(env, jsResult, "fd", jsPlayer->rawFd_.fd) == true, nullptr);
379 CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt64(env, jsResult, "offset", jsPlayer->rawFd_.offset) == true,
380 nullptr);
381 CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt64(env, jsResult, "length", jsPlayer->rawFd_.length) == true,
382 nullptr);
383
384 MEDIA_LOGD("GetFdSrc success");
385 return jsResult;
386 }
387
AsyncSetDisplaySurface(napi_env env,void * data)388 void VideoPlayerNapi::AsyncSetDisplaySurface(napi_env env, void *data)
389 {
390 MEDIA_LOGD("AsyncSetDisplaySurface In");
391 auto asyncContext = reinterpret_cast<VideoPlayerAsyncContext *>(data);
392 CHECK_AND_RETURN_LOG(asyncContext != nullptr, "VideoPlayerAsyncContext is nullptr!");
393
394 if (asyncContext->jsPlayer == nullptr) {
395 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "jsPlayer is destroyed(null), please check js_runtime");
396 return;
397 }
398
399 if (asyncContext->jsPlayer->nativePlayer_ == nullptr) {
400 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "nativePlayer is released(null), please create player again");
401 return;
402 }
403
404 uint64_t surfaceId = 0;
405 MEDIA_LOGD("get surface, surfaceStr = %{public}s", asyncContext->surface.c_str());
406 if (asyncContext->surface.empty() || asyncContext->surface[0] < '0' || asyncContext->surface[0] > '9') {
407 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "input surface id is invalid");
408 return;
409 }
410 if (!StrToULL(asyncContext->surface, surfaceId)) {
411 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "invalid parameters, failed to obtain surfaceId");
412 return;
413 }
414 MEDIA_LOGD("get surface, surfaceId = (%{public}" PRIu64 ")", surfaceId);
415
416 auto surface = SurfaceUtils::GetInstance()->GetSurface(surfaceId);
417 if (surface != nullptr) {
418 int32_t ret = asyncContext->jsPlayer->nativePlayer_->SetVideoSurface(surface);
419 if (ret != MSERR_OK) {
420 asyncContext->SignError(MSERR_EXT_OPERATE_NOT_PERMIT, "failed to SetVideoSurface");
421 }
422 } else {
423 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "failed to get surface from SurfaceUtils");
424 }
425 MEDIA_LOGD("AsyncSetDisplaySurface Out");
426 }
427
SetDisplaySurface(napi_env env,napi_callback_info info)428 napi_value VideoPlayerNapi::SetDisplaySurface(napi_env env, napi_callback_info info)
429 {
430 napi_value result = nullptr;
431 napi_get_undefined(env, &result);
432
433 MEDIA_LOGD("SetDisplaySurface In");
434 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
435
436 // get args
437 napi_value jsThis = nullptr;
438 napi_value args[2] = { nullptr };
439 size_t argCount = 2;
440 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
441 if (status != napi_ok || jsThis == nullptr) {
442 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "failed to napi_get_cb_info");
443 }
444
445 // get surface id from js
446 napi_valuetype valueType = napi_undefined;
447 if (argCount > 0 && napi_typeof(env, args[0], &valueType) == napi_ok && valueType == napi_string) {
448 asyncContext->surface = CommonNapi::GetStringArgument(env, args[0]);
449 }
450 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[1]);
451 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
452 // get jsPlayer
453 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
454
455 napi_value resource = nullptr;
456 napi_create_string_utf8(env, "SetDisplaySurface", NAPI_AUTO_LENGTH, &resource);
457 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, VideoPlayerNapi::AsyncSetDisplaySurface,
458 MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncContext.get()), &asyncContext->work));
459 NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
460 asyncContext.release();
461
462 return result;
463 }
464
ProcessWork(napi_env env,napi_status status,void * data)465 int32_t VideoPlayerNapi::ProcessWork(napi_env env, napi_status status, void *data)
466 {
467 auto asyncContext = reinterpret_cast<VideoPlayerAsyncContext *>(data);
468
469 int32_t ret = MSERR_OK;
470 auto player = asyncContext->jsPlayer->nativePlayer_;
471 if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_PREPARE) {
472 ret = player->PrepareAsync();
473 } else if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_PLAY) {
474 ret = player->Play();
475 } else if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_PAUSE) {
476 auto cb = std::static_pointer_cast<VideoCallbackNapi>(asyncContext->jsPlayer->jsCallback_);
477 if (cb->GetCurrentState() == PLAYER_PAUSED) {
478 return MSERR_INVALID_OPERATION;
479 }
480 ret = player->Pause();
481 } else if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_STOP) {
482 ret = player->Stop();
483 } else if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_VOLUME) {
484 float volume = static_cast<float>(asyncContext->volume);
485 ret = player->SetVolume(volume, volume);
486 } else if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_SEEK) {
487 PlayerSeekMode seekMode = static_cast<PlayerSeekMode>(asyncContext->seekMode);
488 MEDIA_LOGD("seek position %{public}d, seekmode %{public}d", asyncContext->seekPosition, seekMode);
489 ret = player->Seek(asyncContext->seekPosition, seekMode);
490 } else if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_SPEED) {
491 PlaybackRateMode speedMode = static_cast<PlaybackRateMode>(asyncContext->speedMode);
492 ret = player->SetPlaybackSpeed(speedMode);
493 } else if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_BITRATE) {
494 uint32_t bitRate = static_cast<uint32_t>(asyncContext->bitRate);
495 ret = player->SelectBitRate(bitRate);
496 } else {
497 MEDIA_LOGW("invalid operate playback!");
498 }
499
500 return ret;
501 }
502
CompleteAsyncWork(napi_env env,void * data,napi_event_priority prio)503 napi_status VideoPlayerNapi::CompleteAsyncWork(napi_env env, void *data, napi_event_priority prio)
504 {
505 auto task = [env, data]() {
506 MEDIA_LOGD("CompleteAsyncFunc In");
507 auto asyncContext = reinterpret_cast<VideoPlayerAsyncContext *>(data);
508 CHECK_AND_RETURN_LOG(asyncContext != nullptr, "VideoPlayerAsyncContext is nullptr!");
509
510 if (asyncContext->jsPlayer == nullptr) {
511 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "jsPlayer is destroyed(null), please check js_runtime");
512 return MediaAsyncContext::CompleteCallback(env, napi_ok, data);
513 }
514 if (asyncContext->jsPlayer->nativePlayer_ == nullptr || asyncContext->jsPlayer->jsCallback_ == nullptr) {
515 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "nativePlayer is released(null), please create player again");
516 return MediaAsyncContext::CompleteCallback(env, napi_ok, data);
517 }
518 if (asyncContext->asyncWorkType < AsyncWorkType::ASYNC_WORK_PREPARE ||
519 asyncContext->asyncWorkType >= AsyncWorkType::ASYNC_WORK_INVALID) {
520 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "invalid asyncWorkType, please check player code");
521 return MediaAsyncContext::CompleteCallback(env, napi_ok, data);
522 }
523
524 asyncContext->env_ = env;
525 auto cb = std::static_pointer_cast<VideoCallbackNapi>(asyncContext->jsPlayer->jsCallback_);
526
527 int32_t ret = MSERR_OK;
528 if (asyncContext->asyncWorkType == AsyncWorkType::ASYNC_WORK_RESET) {
529 cb->ClearAsyncWork(false, "the requests was aborted because user called reset");
530 cb->QueueAsyncWork(asyncContext);
531 ret = asyncContext->jsPlayer->nativePlayer_->Reset();
532 } else {
533 cb->QueueAsyncWork(asyncContext);
534 ret = ProcessWork(env, napi_ok, data);
535 }
536
537 if (ret != MSERR_OK) {
538 cb->ClearAsyncWork(true, "the request was aborted because videoplayer ProcessWork error");
539 }
540 };
541 return napi_send_event(env, task, prio);
542 }
543
Prepare(napi_env env,napi_callback_info info)544 napi_value VideoPlayerNapi::Prepare(napi_env env, napi_callback_info info)
545 {
546 napi_value result = nullptr;
547 napi_get_undefined(env, &result);
548 MEDIA_LOGD("Prepare In");
549
550 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
551 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_PREPARE;
552
553 // get args
554 napi_value jsThis = nullptr;
555 napi_value args[1] = { nullptr };
556 size_t argCount = 1;
557 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
558 if (status != napi_ok || jsThis == nullptr) {
559 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
560 }
561
562 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
563 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
564
565 // get jsPlayer
566 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
567 // async work
568 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
569 if (ret != napi_status::napi_ok) {
570 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
571 } else {
572 asyncContext.release();
573 }
574 return result;
575 }
576
Play(napi_env env,napi_callback_info info)577 napi_value VideoPlayerNapi::Play(napi_env env, napi_callback_info info)
578 {
579 napi_value result = nullptr;
580 napi_get_undefined(env, &result);
581 MEDIA_LOGD("Play In");
582
583 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
584 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_PLAY;
585 // get args
586 napi_value jsThis = nullptr;
587 napi_value args[1] = { nullptr };
588 size_t argCount = 1;
589 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
590 if (status != napi_ok || jsThis == nullptr) {
591 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
592 }
593
594 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
595 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
596 // get jsPlayer
597 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
598 #ifdef SUPPORT_JSSTACK
599 HiviewDFX::ReportXPowerJsStackSysEvent(env, "STREAM_CHANGE", "SRC=Media");
600 #endif
601 // async work
602 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
603 if (ret != napi_status::napi_ok) {
604 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
605 } else {
606 asyncContext.release();
607 }
608 return result;
609 }
610
Pause(napi_env env,napi_callback_info info)611 napi_value VideoPlayerNapi::Pause(napi_env env, napi_callback_info info)
612 {
613 napi_value result = nullptr;
614 napi_get_undefined(env, &result);
615
616 MEDIA_LOGD("Pause In");
617 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
618 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_PAUSE;
619
620 // get args
621 napi_value jsThis = nullptr;
622 napi_value args[1] = { nullptr };
623 size_t argCount = 1;
624 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
625 if (status != napi_ok || jsThis == nullptr) {
626 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
627 }
628
629 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
630 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
631
632 // get jsPlayer
633 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
634 // async work
635 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
636 if (ret != napi_status::napi_ok) {
637 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
638 } else {
639 asyncContext.release();
640 }
641 return result;
642 }
643
Stop(napi_env env,napi_callback_info info)644 napi_value VideoPlayerNapi::Stop(napi_env env, napi_callback_info info)
645 {
646 napi_value result = nullptr;
647 napi_get_undefined(env, &result);
648
649 MEDIA_LOGD("Stop In");
650 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
651 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_STOP;
652
653 // get args
654 napi_value jsThis = nullptr;
655 napi_value args[1] = { nullptr };
656 size_t argCount = 1;
657 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
658 if (status != napi_ok || jsThis == nullptr) {
659 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
660 }
661
662 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
663 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
664 // get jsPlayer
665 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
666 // async work
667 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
668 if (ret != napi_status::napi_ok) {
669 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
670 } else {
671 asyncContext.release();
672 }
673 return result;
674 }
675
Reset(napi_env env,napi_callback_info info)676 napi_value VideoPlayerNapi::Reset(napi_env env, napi_callback_info info)
677 {
678 napi_value result = nullptr;
679 napi_get_undefined(env, &result);
680
681 MEDIA_LOGD("Reset In");
682 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
683 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_RESET;
684
685 // get args
686 napi_value jsThis = nullptr;
687 napi_value args[1] = { nullptr };
688 size_t argCount = 1;
689 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
690 if (status != napi_ok || jsThis == nullptr) {
691 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
692 }
693
694 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
695 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
696
697 // get jsPlayer
698 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
699 // async work
700 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
701 if (ret != napi_status::napi_ok) {
702 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
703 } else {
704 asyncContext.release();
705 }
706 return result;
707 }
708
Release(napi_env env,napi_callback_info info)709 napi_value VideoPlayerNapi::Release(napi_env env, napi_callback_info info)
710 {
711 napi_value result = nullptr;
712 napi_get_undefined(env, &result);
713
714 MEDIA_LOGD("Release In");
715 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
716
717 // get args
718 napi_value jsThis = nullptr;
719 napi_value args[1] = { nullptr };
720 size_t argCount = 1;
721 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
722 if (status != napi_ok || jsThis == nullptr) {
723 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
724 }
725
726 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
727 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
728
729 // get jsPlayer
730 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
731 if (asyncContext->jsPlayer == nullptr) {
732 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "jsPlayer is destroyed(null), please check js_runtime");
733 } else if (asyncContext->jsPlayer->nativePlayer_ == nullptr) {
734 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "nativePlayer is released(null), please create player again");
735 } else {
736 (void)asyncContext->jsPlayer->nativePlayer_->Release();
737 asyncContext->jsPlayer->CancelCallback();
738 asyncContext->jsPlayer->jsCallback_ = nullptr;
739 asyncContext->jsPlayer->nativePlayer_ = nullptr;
740 asyncContext->jsPlayer->url_.clear();
741 }
742
743 // async work
744 auto ret = MediaAsyncContext::SendCompleteEvent(env, asyncContext.get(), napi_eprio_high);
745 if (ret != napi_status::napi_ok) {
746 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
747 } else {
748 asyncContext.release();
749 }
750 return result;
751 }
752
Seek(napi_env env,napi_callback_info info)753 napi_value VideoPlayerNapi::Seek(napi_env env, napi_callback_info info)
754 {
755 napi_value result = nullptr;
756 napi_get_undefined(env, &result);
757
758 MEDIA_LOGI("Seek In");
759 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
760 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_SEEK;
761
762 napi_value jsThis = nullptr;
763 napi_value args[3] = { nullptr }; // timeMs: number, mode:SeekMode, callback:AsyncCallback<number>
764 size_t argCount = 3;
765 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
766 if (status != napi_ok || jsThis == nullptr) {
767 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
768 }
769 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
770 if (asyncContext->jsPlayer != nullptr && asyncContext->jsPlayer->jsCallback_ != nullptr) {
771 auto cb = std::static_pointer_cast<VideoCallbackNapi>(asyncContext->jsPlayer->jsCallback_);
772 if (GetJSState(cb->GetCurrentState()) == VideoPlayState::STATE_STOPPED) {
773 asyncContext->SignError(MSERR_EXT_OPERATE_NOT_PERMIT, "current state does not support seek");
774 }
775 }
776
777 if (CommonNapi::CheckValueType(env, args[0], napi_number)) {
778 (void)napi_get_value_int32(env, args[0], &asyncContext->seekPosition); // timeMs: number
779 if (asyncContext->seekPosition < 0) {
780 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "seek position < 0");
781 }
782 }
783
784 if (CommonNapi::CheckValueType(env, args[1], napi_number)) {
785 (void)napi_get_value_int32(env, args[1], &asyncContext->seekMode); // mode:SeekMode
786 if (asyncContext->seekMode < SEEK_NEXT_SYNC || asyncContext->seekMode > SEEK_CLOSEST) {
787 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "seek mode invalid");
788 }
789 if (CommonNapi::CheckValueType(env, args[2], napi_function)) { // callback:AsyncCallback<number>
790 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[2]); // callback:AsyncCallback<number>
791 }
792 } else if (CommonNapi::CheckValueType(env, args[1], napi_function)) {
793 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[1]); // callback:AsyncCallback<number>
794 }
795 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
796
797 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
798 if (ret != napi_status::napi_ok) {
799 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
800 } else {
801 asyncContext.release();
802 }
803 return result;
804 }
805
SetSpeed(napi_env env,napi_callback_info info)806 napi_value VideoPlayerNapi::SetSpeed(napi_env env, napi_callback_info info)
807 {
808 napi_value result = nullptr;
809 napi_get_undefined(env, &result);
810
811 MEDIA_LOGD("SetSpeed In");
812 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
813 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_SPEED;
814
815 // get args
816 napi_value jsThis = nullptr;
817 napi_value args[2] = { nullptr };
818 size_t argCount = 2;
819 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
820 if (status != napi_ok || jsThis == nullptr) {
821 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
822 }
823
824 // get speed mode
825 napi_valuetype valueType = napi_undefined;
826 if (argCount < 1 || napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
827 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed get speed mode");
828 }
829 status = napi_get_value_int32(env, args[0], &asyncContext->speedMode);
830 if (status != napi_ok ||
831 asyncContext->speedMode < SPEED_FORWARD_0_75_X ||
832 asyncContext->speedMode > SPEED_FORWARD_2_00_X) {
833 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "speed mode invalid");
834 }
835 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[1]);
836 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
837
838 // get jsPlayer
839 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
840 // async work
841 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
842 if (ret != napi_status::napi_ok) {
843 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
844 } else {
845 asyncContext.release();
846 }
847 return result;
848 }
849
SelectBitrate(napi_env env,napi_callback_info info)850 napi_value VideoPlayerNapi::SelectBitrate(napi_env env, napi_callback_info info)
851 {
852 napi_value result = nullptr;
853 napi_get_undefined(env, &result);
854
855 MEDIA_LOGD("SelectBitRate In");
856 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
857 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_BITRATE;
858
859 // get args
860 napi_value jsThis = nullptr;
861 napi_value args[2] = { nullptr };
862 size_t argCount = 2;
863 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
864 if (status != napi_ok || jsThis == nullptr) {
865 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
866 }
867
868 // get bitrate
869 napi_valuetype valueType = napi_undefined;
870 if (argCount < 1 || napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
871 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed get bitrate");
872 }
873 status = napi_get_value_int32(env, args[0], &asyncContext->bitRate);
874 if ((status != napi_ok) || (asyncContext->bitRate < 0)) {
875 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "bitrate invalid");
876 }
877 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[1]);
878 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
879
880 // get jsPlayer
881 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
882 // async work
883 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
884 if (ret != napi_status::napi_ok) {
885 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
886 } else {
887 asyncContext.release();
888 }
889 return result;
890 }
891
AsyncGetTrackDescription(napi_env env,void * data)892 void VideoPlayerNapi::AsyncGetTrackDescription(napi_env env, void *data)
893 {
894 auto asyncContext = reinterpret_cast<VideoPlayerAsyncContext *>(data);
895 CHECK_AND_RETURN_LOG(asyncContext != nullptr, "VideoPlayerAsyncContext is nullptr!");
896
897 if (asyncContext->jsPlayer == nullptr) {
898 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "jsPlayer is destroyed(null), please check js_runtime");
899 return;
900 }
901
902 if (asyncContext->jsPlayer->nativePlayer_ == nullptr) {
903 asyncContext->SignError(MSERR_EXT_NO_MEMORY, "nativePlayer is released(null), please create player again");
904 return;
905 }
906
907 auto player = asyncContext->jsPlayer->nativePlayer_;
908 std::vector<Format> &videoInfo = asyncContext->jsPlayer->videoTrackInfoVec_;
909 videoInfo.clear();
910 int32_t ret = player->GetVideoTrackInfo(videoInfo);
911 if (ret != MSERR_OK) {
912 asyncContext->SignError(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)),
913 "failed to GetVideoTrackInfo");
914 return;
915 }
916
917 ret = player->GetAudioTrackInfo(videoInfo);
918 if (ret != MSERR_OK) {
919 asyncContext->SignError(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)),
920 "failed to GetAudioTrackInfo");
921 return;
922 }
923
924 if (videoInfo.empty()) {
925 asyncContext->SignError(MSERR_EXT_OPERATE_NOT_PERMIT, "video/audio track info is empty");
926 return;
927 }
928
929 asyncContext->JsResult = std::make_unique<MediaJsResultArray>(videoInfo);
930 MEDIA_LOGD("AsyncGetTrackDescription Out");
931 }
932
GetTrackDescription(napi_env env,napi_callback_info info)933 napi_value VideoPlayerNapi::GetTrackDescription(napi_env env, napi_callback_info info)
934 {
935 napi_value result = nullptr;
936 napi_get_undefined(env, &result);
937
938 MEDIA_LOGD("GetTrackDescription In");
939 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
940
941 // get args
942 napi_value jsThis = nullptr;
943 napi_value args[1] = { nullptr };
944 size_t argCount = 1;
945 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
946 if (status != napi_ok || jsThis == nullptr) {
947 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
948 }
949
950 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[0]);
951 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
952 // get jsPlayer
953 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
954 // async work
955 napi_value resource = nullptr;
956 napi_create_string_utf8(env, "GetTrackDescription", NAPI_AUTO_LENGTH, &resource);
957 NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, VideoPlayerNapi::AsyncGetTrackDescription,
958 MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncContext.get()), &asyncContext->work));
959 NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
960 asyncContext.release();
961 return result;
962 }
963
SetVolume(napi_env env,napi_callback_info info)964 napi_value VideoPlayerNapi::SetVolume(napi_env env, napi_callback_info info)
965 {
966 napi_value result = nullptr;
967 napi_get_undefined(env, &result);
968
969 MEDIA_LOGD("SetVolume In");
970 std::unique_ptr<VideoPlayerAsyncContext> asyncContext = std::make_unique<VideoPlayerAsyncContext>(env);
971 asyncContext->asyncWorkType = AsyncWorkType::ASYNC_WORK_VOLUME;
972
973 // get args
974 napi_value jsThis = nullptr;
975 napi_value args[2] = { nullptr };
976 size_t argCount = 2;
977 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
978 if (status != napi_ok || jsThis == nullptr) {
979 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "failed to napi_get_cb_info");
980 }
981
982 // get volume
983 napi_valuetype valueType = napi_undefined;
984 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
985 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "get volume napi_typeof is't napi_number");
986 } else {
987 status = napi_get_value_double(env, args[0], &asyncContext->volume);
988 if (status != napi_ok || asyncContext->volume < 0.0f || asyncContext->volume > 1.0f) {
989 asyncContext->SignError(MSERR_EXT_INVALID_VAL, "get volume input volume < 0.0f or > 1.0f");
990 }
991 }
992 asyncContext->callbackRef = CommonNapi::CreateReference(env, args[1]);
993 asyncContext->deferred = CommonNapi::CreatePromise(env, asyncContext->callbackRef, result);
994 // get jsPlayer
995 (void)napi_unwrap(env, jsThis, reinterpret_cast<void **>(&asyncContext->jsPlayer));
996 #ifdef SUPPORT_JSSTACK
997 HiviewDFX::ReportXPowerJsStackSysEvent(env, "VOLUME_CHANGE", "SRC=Media");
998 #endif
999 // async work
1000 auto ret = CompleteAsyncWork(env, static_cast<void *>(asyncContext.get()), napi_eprio_high);
1001 if (ret != napi_status::napi_ok) {
1002 MEDIA_LOGE("failed to SendEvent, ret = %{public}d", ret);
1003 } else {
1004 asyncContext.release();
1005 }
1006 return result;
1007 }
1008
On(napi_env env,napi_callback_info info)1009 napi_value VideoPlayerNapi::On(napi_env env, napi_callback_info info)
1010 {
1011 napi_value undefinedResult = nullptr;
1012 napi_get_undefined(env, &undefinedResult);
1013
1014 static constexpr size_t minArgCount = 2;
1015 size_t argCount = minArgCount;
1016 napi_value args[minArgCount] = { nullptr, nullptr };
1017 napi_value jsThis = nullptr;
1018 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
1019 if (status != napi_ok || jsThis == nullptr || argCount < minArgCount) {
1020 MEDIA_LOGE("Failed to retrieve details about the callback");
1021 return undefinedResult;
1022 }
1023
1024 VideoPlayerNapi *jsPlayer = nullptr;
1025 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1026 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1027
1028 napi_valuetype valueType0 = napi_undefined;
1029 napi_valuetype valueType1 = napi_undefined;
1030 if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string ||
1031 napi_typeof(env, args[1], &valueType1) != napi_ok || valueType1 != napi_function) {
1032 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
1033 return undefinedResult;
1034 }
1035
1036 std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
1037 MEDIA_LOGD("callbackName: %{public}s", callbackName.c_str());
1038
1039 napi_ref ref = nullptr;
1040 status = napi_create_reference(env, args[1], 1, &ref);
1041 CHECK_AND_RETURN_RET_LOG(status == napi_ok && ref != nullptr, undefinedResult, "failed to create reference!");
1042
1043 std::shared_ptr<AutoRef> autoRef = std::make_shared<AutoRef>(env, ref);
1044 jsPlayer->SetCallbackReference(callbackName, autoRef);
1045 return undefinedResult;
1046 }
1047
SetLoop(napi_env env,napi_callback_info info)1048 napi_value VideoPlayerNapi::SetLoop(napi_env env, napi_callback_info info)
1049 {
1050 napi_value undefinedResult = nullptr;
1051 napi_get_undefined(env, &undefinedResult);
1052
1053 MEDIA_LOGD("SetLoop In");
1054 size_t argCount = 1;
1055 napi_value args[1] = { nullptr };
1056 napi_value jsThis = nullptr;
1057 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
1058 if (status != napi_ok || jsThis == nullptr || argCount < 1) {
1059 MEDIA_LOGE("Failed to retrieve details about the callback");
1060 return undefinedResult;
1061 }
1062
1063 VideoPlayerNapi *jsPlayer = nullptr;
1064 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1065 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1066 if (jsPlayer->nativePlayer_ == nullptr) {
1067 jsPlayer->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
1068 return undefinedResult;
1069 }
1070 napi_valuetype valueType = napi_undefined;
1071 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_boolean) {
1072 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
1073 return undefinedResult;
1074 }
1075
1076 bool loopFlag = false;
1077 status = napi_get_value_bool(env, args[0], &loopFlag);
1078 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_value_bool error");
1079
1080 int32_t ret = jsPlayer->nativePlayer_->SetLooping(loopFlag);
1081 if (ret != MSERR_OK) {
1082 jsPlayer->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetLooping");
1083 return undefinedResult;
1084 }
1085 MEDIA_LOGD("SetLoop success");
1086 return undefinedResult;
1087 }
1088
GetLoop(napi_env env,napi_callback_info info)1089 napi_value VideoPlayerNapi::GetLoop(napi_env env, napi_callback_info info)
1090 {
1091 napi_value undefinedResult = nullptr;
1092 napi_get_undefined(env, &undefinedResult);
1093
1094 napi_value jsThis = nullptr;
1095 size_t argCount = 0;
1096 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1097 if (status != napi_ok || jsThis == nullptr) {
1098 MEDIA_LOGE("Failed to retrieve details about the callback");
1099 return undefinedResult;
1100 }
1101
1102 VideoPlayerNapi *jsPlayer = nullptr;
1103 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1104 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1105
1106 if (jsPlayer->nativePlayer_ == nullptr) {
1107 jsPlayer->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
1108 return undefinedResult;
1109 }
1110 bool loopFlag = jsPlayer->nativePlayer_->IsLooping();
1111
1112 napi_value jsResult = nullptr;
1113 status = napi_get_boolean(env, loopFlag, &jsResult);
1114 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_boolean error");
1115 MEDIA_LOGD("GetSrc success loop Status: %{public}d", loopFlag);
1116 return jsResult;
1117 }
1118
SetVideoScaleType(napi_env env,napi_callback_info info)1119 napi_value VideoPlayerNapi::SetVideoScaleType(napi_env env, napi_callback_info info)
1120 {
1121 napi_value undefinedResult = nullptr;
1122 napi_get_undefined(env, &undefinedResult);
1123
1124 MEDIA_LOGD("SetVideoScaleType In");
1125 size_t argCount = 1;
1126 napi_value args[1] = { nullptr };
1127 napi_value jsThis = nullptr;
1128 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
1129 if (status != napi_ok || jsThis == nullptr || argCount < 1) {
1130 MEDIA_LOGE("Failed to retrieve details about the callback");
1131 return undefinedResult;
1132 }
1133
1134 VideoPlayerNapi *jsPlayer = nullptr;
1135 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1136 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1137
1138 if (jsPlayer->nativePlayer_ == nullptr) {
1139 jsPlayer->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
1140 return undefinedResult;
1141 }
1142
1143 napi_valuetype valueType = napi_undefined;
1144 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
1145 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
1146 return undefinedResult;
1147 }
1148
1149 int32_t videoScaleType = 0;
1150 status = napi_get_value_int32(env, args[0], &videoScaleType);
1151 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_value_int32 error");
1152 if (videoScaleType > static_cast<int32_t>(Plugins::VideoScaleType::VIDEO_SCALE_TYPE_FIT_CROP)
1153 || videoScaleType < static_cast<int32_t>(Plugins::VideoScaleType::VIDEO_SCALE_TYPE_FIT)) {
1154 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
1155 return undefinedResult;
1156 }
1157 if (jsPlayer->url_.empty()) {
1158 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_STATE, "invalid state, please input parameters after setSrc");
1159 return undefinedResult;
1160 }
1161 jsPlayer->videoScaleType_ = videoScaleType;
1162 Format format;
1163 (void)format.PutIntValue(PlayerKeys::VIDEO_SCALE_TYPE, videoScaleType);
1164 int32_t ret = jsPlayer->nativePlayer_->SetParameter(format);
1165 if (ret != MSERR_OK) {
1166 jsPlayer->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetParameter");
1167 return undefinedResult;
1168 }
1169 MEDIA_LOGD("SetVideoScaleType success");
1170 return undefinedResult;
1171 }
1172
GetVideoScaleType(napi_env env,napi_callback_info info)1173 napi_value VideoPlayerNapi::GetVideoScaleType(napi_env env, napi_callback_info info)
1174 {
1175 napi_value undefinedResult = nullptr;
1176 napi_get_undefined(env, &undefinedResult);
1177
1178 napi_value jsThis = nullptr;
1179 size_t argCount = 0;
1180 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1181 if (status != napi_ok || jsThis == nullptr) {
1182 MEDIA_LOGE("Failed to retrieve details about the callback");
1183 return undefinedResult;
1184 }
1185
1186 VideoPlayerNapi *jsPlayer = nullptr;
1187 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1188 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1189
1190 napi_value jsResult = nullptr;
1191 status = napi_create_int32(env, jsPlayer->videoScaleType_, &jsResult);
1192 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int32 error");
1193 MEDIA_LOGD("GetVideoScaleType success");
1194 return jsResult;
1195 }
1196
GetCurrentTime(napi_env env,napi_callback_info info)1197 napi_value VideoPlayerNapi::GetCurrentTime(napi_env env, napi_callback_info info)
1198 {
1199 napi_value undefinedResult = nullptr;
1200 napi_get_undefined(env, &undefinedResult);
1201
1202 size_t argCount = 0;
1203 napi_value jsThis = nullptr;
1204 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1205 if (status != napi_ok || jsThis == nullptr) {
1206 MEDIA_LOGE("Failed to retrieve details about the callback");
1207 return undefinedResult;
1208 }
1209
1210 VideoPlayerNapi *jsPlayer = nullptr;
1211 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1212 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1213
1214 if (jsPlayer->nativePlayer_ == nullptr) {
1215 jsPlayer->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
1216 return undefinedResult;
1217 }
1218 int32_t currentTime = -1;
1219 (void)jsPlayer->nativePlayer_->GetCurrentTime(currentTime);
1220
1221 napi_value jsResult = nullptr;
1222 status = napi_create_int32(env, currentTime, &jsResult);
1223 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int32 error");
1224 MEDIA_LOGD("GetCurrenTime success, Current time: %{public}d", currentTime);
1225 return jsResult;
1226 }
1227
GetDuration(napi_env env,napi_callback_info info)1228 napi_value VideoPlayerNapi::GetDuration(napi_env env, napi_callback_info info)
1229 {
1230 napi_value undefinedResult = nullptr;
1231 napi_get_undefined(env, &undefinedResult);
1232
1233 napi_value jsThis = nullptr;
1234 size_t argCount = 0;
1235 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1236 if (status != napi_ok || jsThis == nullptr) {
1237 MEDIA_LOGE("Failed to retrieve details about the callback");
1238 return undefinedResult;
1239 }
1240
1241 VideoPlayerNapi *jsPlayer = nullptr;
1242 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1243 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1244
1245 if (jsPlayer->nativePlayer_ == nullptr) {
1246 jsPlayer->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
1247 return undefinedResult;
1248 }
1249 int32_t duration = -1;
1250 (void)jsPlayer->nativePlayer_->GetDuration(duration);
1251
1252 napi_value jsResult = nullptr;
1253 status = napi_create_int32(env, duration, &jsResult);
1254 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int32 error");
1255
1256 MEDIA_LOGD("GetDuration success, Current time: %{public}d", duration);
1257 return jsResult;
1258 }
1259
GetState(napi_env env,napi_callback_info info)1260 napi_value VideoPlayerNapi::GetState(napi_env env, napi_callback_info info)
1261 {
1262 napi_value jsThis = nullptr;
1263 napi_value undefinedResult = nullptr;
1264 napi_get_undefined(env, &undefinedResult);
1265
1266 size_t argCount = 0;
1267 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1268 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "Failed to retrieve details about the callback");
1269
1270 VideoPlayerNapi *jsPlayer = nullptr;
1271 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1272 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "Failed to retrieve instance");
1273
1274 std::string curState = VideoPlayState::STATE_ERROR;
1275 if (jsPlayer->jsCallback_ != nullptr) {
1276 auto cb = std::static_pointer_cast<VideoCallbackNapi>(jsPlayer->jsCallback_);
1277 curState = GetJSState(cb->GetCurrentState());
1278 MEDIA_LOGD("GetState success, State: %{public}s", curState.c_str());
1279 }
1280
1281 napi_value jsResult = nullptr;
1282 status = napi_create_string_utf8(env, curState.c_str(), NAPI_AUTO_LENGTH, &jsResult);
1283 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_string_utf8 error");
1284 return jsResult;
1285 }
1286
GetWidth(napi_env env,napi_callback_info info)1287 napi_value VideoPlayerNapi::GetWidth(napi_env env, napi_callback_info info)
1288 {
1289 napi_value jsThis = nullptr;
1290 napi_value undefinedResult = nullptr;
1291 napi_get_undefined(env, &undefinedResult);
1292
1293 MEDIA_LOGD("GetWidth In");
1294 size_t argCount = 0;
1295 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1296 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "Failed to retrieve details about the callback");
1297
1298 VideoPlayerNapi *jsPlayer = nullptr;
1299 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1300 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1301
1302 int32_t width = 0;
1303 if (jsPlayer->jsCallback_ != nullptr) {
1304 auto cb = std::static_pointer_cast<VideoCallbackNapi>(jsPlayer->jsCallback_);
1305 width = cb->GetVideoWidth();
1306 }
1307
1308 napi_value jsResult = nullptr;
1309 status = napi_create_int32(env, width, &jsResult);
1310 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int32 error");
1311 return jsResult;
1312 }
1313
GetHeight(napi_env env,napi_callback_info info)1314 napi_value VideoPlayerNapi::GetHeight(napi_env env, napi_callback_info info)
1315 {
1316 napi_value jsThis = nullptr;
1317 napi_value undefinedResult = nullptr;
1318 napi_get_undefined(env, &undefinedResult);
1319
1320 MEDIA_LOGD("GetHeight In");
1321 size_t argCount = 0;
1322 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1323 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "Failed to retrieve details about the callback");
1324
1325 VideoPlayerNapi *jsPlayer = nullptr;
1326 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1327 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1328
1329 int32_t height = 0;
1330 if (jsPlayer->jsCallback_ != nullptr) {
1331 auto cb = std::static_pointer_cast<VideoCallbackNapi>(jsPlayer->jsCallback_);
1332 height = cb->GetVideoHeight();
1333 }
1334
1335 napi_value jsResult = nullptr;
1336 status = napi_create_int32(env, height, &jsResult);
1337 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_create_int32 error");
1338 return jsResult;
1339 }
1340
ErrorCallback(MediaServiceExtErrCode errCode,std::string errMsg)1341 void VideoPlayerNapi::ErrorCallback(MediaServiceExtErrCode errCode, std::string errMsg)
1342 {
1343 if (jsCallback_ != nullptr) {
1344 auto cb = std::static_pointer_cast<VideoCallbackNapi>(jsCallback_);
1345 cb->SendErrorCallback(errCode, errMsg);
1346 }
1347 }
1348
SetAudioInterruptMode(napi_env env,napi_callback_info info)1349 napi_value VideoPlayerNapi::SetAudioInterruptMode(napi_env env, napi_callback_info info)
1350 {
1351 size_t argCount = 1;
1352 napi_value args[1] = { nullptr };
1353 napi_value jsThis = nullptr;
1354 napi_value undefinedResult = nullptr;
1355 napi_get_undefined(env, &undefinedResult);
1356
1357 MEDIA_LOGD("SetAudioInterruptMode In");
1358 napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
1359 if (status != napi_ok || jsThis == nullptr || argCount < 1) {
1360 MEDIA_LOGE("Failed to retrieve details about the callback");
1361 return undefinedResult;
1362 }
1363
1364 VideoPlayerNapi *jsPlayer = nullptr;
1365 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&jsPlayer));
1366 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsPlayer != nullptr, undefinedResult, "Failed to retrieve instance");
1367
1368 if (jsPlayer->nativePlayer_ == nullptr) {
1369 jsPlayer->ErrorCallback(MSERR_EXT_NO_MEMORY, "player is released(null), please create player again");
1370 return undefinedResult;
1371 }
1372
1373 napi_valuetype valueType = napi_undefined;
1374 if (napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) {
1375 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "napi_typeof failed, please check the input parameters");
1376 return undefinedResult;
1377 }
1378
1379 int32_t interruptMode = 0;
1380 status = napi_get_value_int32(env, args[0], &interruptMode);
1381 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "napi_get_value_bool error");
1382
1383 if (interruptMode < AudioStandard::InterruptMode::SHARE_MODE ||
1384 interruptMode > AudioStandard::InterruptMode::INDEPENDENT_MODE) {
1385 jsPlayer->ErrorCallback(MSERR_EXT_INVALID_VAL, "invalid parameters, please check the input parameters");
1386 return undefinedResult;
1387 }
1388
1389 jsPlayer->interruptMode_ = AudioStandard::InterruptMode(interruptMode);
1390 Format format;
1391 (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_MODE, interruptMode);
1392 int32_t ret = jsPlayer->nativePlayer_->SetParameter(format);
1393 if (ret != MSERR_OK) {
1394 jsPlayer->ErrorCallback(MSErrorToExtError(static_cast<MediaServiceErrCode>(ret)), "failed to SetParameter");
1395 return undefinedResult;
1396 }
1397
1398 MEDIA_LOGD("SetAudioInterruptMode success");
1399 return undefinedResult;
1400 }
1401
GetAudioInterruptMode(napi_env env,napi_callback_info info)1402 napi_value VideoPlayerNapi::GetAudioInterruptMode(napi_env env, napi_callback_info info)
1403 {
1404 napi_value jsThis = nullptr;
1405 napi_value jsResult = nullptr;
1406 napi_value undefinedResult = nullptr;
1407 napi_get_undefined(env, &undefinedResult);
1408
1409 size_t argCount = 0;
1410 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1411 if (status != napi_ok || jsThis == nullptr) {
1412 MEDIA_LOGE("Failed to retrieve details about the callback");
1413 return undefinedResult;
1414 }
1415
1416 VideoPlayerNapi *player = nullptr;
1417 status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&player));
1418 CHECK_AND_RETURN_RET_LOG(status == napi_ok && player != nullptr, undefinedResult, "Failed to retrieve instance");
1419
1420 CHECK_AND_RETURN_RET_LOG(player->nativePlayer_ != nullptr, undefinedResult, "No memory");
1421
1422 status = napi_create_object(env, &jsResult);
1423 CHECK_AND_RETURN_RET_LOG(status == napi_ok, undefinedResult, "create jsresult object error");
1424
1425 CHECK_AND_RETURN_RET(CommonNapi::AddNumberPropInt32(env, jsResult, "InterruptMode",
1426 player->interruptMode_) == true, nullptr);
1427 MEDIA_LOGD("GetAudioInterruptMode success");
1428 return jsResult;
1429 }
1430
SetCallbackReference(const std::string & callbackName,std::shared_ptr<AutoRef> ref)1431 void VideoPlayerNapi::SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref)
1432 {
1433 refMap_[callbackName] = ref;
1434 if (jsCallback_ != nullptr) {
1435 std::shared_ptr<PlayerCallbackNapi> napiCb = std::static_pointer_cast<PlayerCallbackNapi>(jsCallback_);
1436 napiCb->SaveCallbackReference(callbackName, ref);
1437 }
1438 }
1439
CancelCallback()1440 void VideoPlayerNapi::CancelCallback()
1441 {
1442 if (jsCallback_ != nullptr) {
1443 std::shared_ptr<VideoCallbackNapi> napiCb = std::static_pointer_cast<VideoCallbackNapi>(jsCallback_);
1444 napiCb->ClearCallbackReference();
1445 napiCb->ClearAsyncWork(false, "the requests was aborted because user called release");
1446 }
1447 }
1448 } // namespace Media
1449 } // namespace OHOS