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