• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2023 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  * Description: supply napi interface realization for stream player.
15  * Author: huangchanggui
16  * Create: 2023-1-11
17  */
18 
19 #include "napi_stream_player.h"
20 #include <memory>
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 #include "cast_engine_log.h"
24 #include "cast_engine_common.h"
25 #include "napi_castengine_utils.h"
26 #include "napi_async_work.h"
27 #include "napi_errors.h"
28 #include "cast_engine_errors.h"
29 
30 namespace OHOS {
31 namespace CastEngine {
32 namespace CastEngineClient {
33 DEFINE_CAST_ENGINE_LABEL("Cast-Napi-StreamPlayer");
34 
35 thread_local napi_ref NapiStreamPlayer::consRef_ = nullptr;
36 
37 std::map<std::string, std::pair<NapiStreamPlayer::OnEventHandlerType,
38     NapiStreamPlayer::OffEventHandlerType>>
39     NapiStreamPlayer::eventHandlers_ = {
40     { "stateChanged", { OnStateChanged, OffStateChanged } },
41     { "positionChanged", { OnPositionChanged, OffPositionChanged } },
42     { "mediaItemChanged", { OnMediaItemChanged, OffMediaItemChanged } },
43     { "volumeChanged", { OnVolumeChanged, OffVolumeChanged } },
44     { "videoSizeChanged", { OnVideoSizeChanged, OffVideoSizeChanged } },
45     { "loopModeChanged", { OnLoopModeChanged, OffLoopModeChanged } },
46     { "playSpeedChanged", { OnPlaySpeedChanged, OffPlaySpeedChanged } },
47     { "playerError", { OnPlayerError, OffPlayerError } },
48     { "nextRequest", { OnNextRequest, OffNextRequest } },
49     { "previousRequest", { OnPreviousRequest, OffPreviousRequest } },
50     { "seekDone", { OnSeekDone, OffSeekDone } },
51     { "endOfStream", { OnEndOfStream, OffEndOfStream } },
52     { "imageChanged", { OnImageChanged, OffImageChanged } }
53 };
54 
DefineStreamPlayerJSClass(napi_env env)55 void NapiStreamPlayer::DefineStreamPlayerJSClass(napi_env env)
56 {
57     napi_property_descriptor playerDesc[] = {
58         DECLARE_NAPI_FUNCTION("on", OnEvent),
59         DECLARE_NAPI_FUNCTION("off", OffEvent),
60         DECLARE_NAPI_FUNCTION("setSurface", SetSurface),
61         DECLARE_NAPI_FUNCTION("load", Load),
62         DECLARE_NAPI_FUNCTION("start", Start),
63         DECLARE_NAPI_FUNCTION("play", Play),
64         DECLARE_NAPI_FUNCTION("pause", Pause),
65         DECLARE_NAPI_FUNCTION("stop", Stop),
66         DECLARE_NAPI_FUNCTION("next", Next),
67         DECLARE_NAPI_FUNCTION("previous", Previous),
68         DECLARE_NAPI_FUNCTION("seek", Seek),
69         DECLARE_NAPI_FUNCTION("fastForward", FastForward),
70         DECLARE_NAPI_FUNCTION("fastRewind", FastRewind),
71         DECLARE_NAPI_FUNCTION("setVolume", SetVolume),
72         DECLARE_NAPI_FUNCTION("setLoopMode", SetLoopMode),
73         DECLARE_NAPI_FUNCTION("setSpeed", SetSpeed),
74         DECLARE_NAPI_FUNCTION("setMute", SetMute),
75         DECLARE_NAPI_FUNCTION("getPlayerStatus", GetPlayerStatus),
76         DECLARE_NAPI_FUNCTION("getPosition", GetPosition),
77         DECLARE_NAPI_FUNCTION("getVolume", GetVolume),
78         DECLARE_NAPI_FUNCTION("getMute", GetMute),
79         DECLARE_NAPI_FUNCTION("getLoopMode", GetLoopMode),
80         DECLARE_NAPI_FUNCTION("getPlaySpeed", GetPlaySpeed),
81         DECLARE_NAPI_FUNCTION("getMediaInfoHolder", GetMediaInfoHolder),
82         DECLARE_NAPI_FUNCTION("release", Release)
83     };
84 
85     napi_value constructor = nullptr;
86     constexpr int initialRefCount = 1;
87     napi_status status = napi_define_class(env, "streamPlayer", NAPI_AUTO_LENGTH, NapiStreamPlayerConstructor, nullptr,
88         sizeof(playerDesc) / sizeof(playerDesc[0]), playerDesc, &constructor);
89     if (status != napi_ok) {
90         CLOGE("napi_define_class failed");
91         return;
92     }
93     status = napi_create_reference(env, constructor, initialRefCount, &consRef_);
94     if (status != napi_ok) {
95         CLOGE("DefineStreamPlayerJSClass napi_create_reference failed");
96     }
97 }
98 
NapiStreamPlayerConstructor(napi_env env,napi_callback_info info)99 napi_value NapiStreamPlayer::NapiStreamPlayerConstructor(napi_env env, napi_callback_info info)
100 {
101     CLOGD("NapiStreamPlayer construct in");
102     napi_value thisVar = nullptr;
103     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
104     CLOGD("NapiStreamPlayer construct successfully");
105     return thisVar;
106 }
107 
CreateNapiStreamPlayer(napi_env env,std::shared_ptr<IStreamPlayer> player,napi_value & out)108 napi_status NapiStreamPlayer::CreateNapiStreamPlayer(napi_env env, std::shared_ptr<IStreamPlayer> player,
109     napi_value &out)
110 {
111     CLOGD("create napiStreamPlayer in");
112     napi_value result = nullptr;
113     napi_value constructor = nullptr;
114     if (consRef_ == nullptr || player == nullptr) {
115         CLOGE("napiStreamPlayer input is null");
116         return napi_generic_failure;
117     }
118     napi_status status = napi_get_reference_value(env, consRef_, &constructor);
119     if (status != napi_ok || constructor == nullptr) {
120         CLOGE("CreateNapiStreamPlayer napi_get_reference_value failed");
121         return napi_generic_failure;
122     }
123 
124     constexpr size_t argc = 0;
125     status = napi_new_instance(env, constructor, argc, nullptr, &result);
126     if (status != napi_ok) {
127         CLOGE("CreateNapiStreamPlayer napi_new_instance failed");
128         return napi_generic_failure;
129     }
130 
131     NapiStreamPlayer *napiStreamPlayer = new (std::nothrow) NapiStreamPlayer(player);
132     if (napiStreamPlayer == nullptr) {
133         CLOGE("napiStreamPlayer is nullptr");
134         return napi_generic_failure;
135     }
136     auto finalize = [](napi_env env, void *data, void *hint) {
137         NapiStreamPlayer *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(data);
138         if (napiStreamPlayer != nullptr) {
139             CLOGI("napiStreamPlayer deconstructed");
140             delete napiStreamPlayer;
141             napiStreamPlayer = nullptr;
142         }
143     };
144     if (napi_wrap(env, result, napiStreamPlayer, finalize, nullptr, nullptr) != napi_ok) {
145         CLOGE("CreateNapiStreamPlayer napi_wrap failed");
146         delete napiStreamPlayer;
147         napiStreamPlayer = nullptr;
148         return napi_generic_failure;
149     }
150     out = result;
151     CLOGD("Create napiStreamPlayer successfully");
152     return napi_ok;
153 }
154 
GetNapiStreamPlayer(napi_env env,napi_callback_info info)155 NapiStreamPlayer *NapiStreamPlayer::GetNapiStreamPlayer(napi_env env, napi_callback_info info)
156 {
157     napi_value thisVar = nullptr;
158     NAPI_CALL_BASE(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr), nullptr);
159 
160     NapiStreamPlayer *napiStreamPlayer = nullptr;
161     NAPI_CALL_BASE(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiStreamPlayer)), nullptr);
162     if (napiStreamPlayer == nullptr) {
163         CLOGE("napi_unwrap napiStreamPlayer is null");
164         return nullptr;
165     }
166 
167     return napiStreamPlayer;
168 }
169 
OnEvent(napi_env env,napi_callback_info info)170 napi_value NapiStreamPlayer::OnEvent(napi_env env, napi_callback_info info)
171 {
172     constexpr size_t expectedArgc = 2;
173     napi_value argv[expectedArgc] = { 0 };
174     napi_valuetype expectedTypes[expectedArgc] = { napi_string, napi_function };
175     if (!GetJSFuncParams(env, info, argv, expectedArgc, expectedTypes)) {
176         return GetUndefinedValue(env);
177     }
178 
179     std::string eventName = ParseString(env, argv[0]);
180     NapiStreamPlayer *napiStreamPlayer = GetNapiStreamPlayer(env, info);
181     if (napiStreamPlayer == nullptr) {
182         CLOGE("IStreamPlayer is null");
183         return GetUndefinedValue(env);
184     }
185     auto it = eventHandlers_.find(eventName);
186     if (it == eventHandlers_.end()) {
187         CLOGE("event name invalid");
188         return GetUndefinedValue(env);
189     }
190 
191     if (RegisterNativeStreamPlayerListener(napiStreamPlayer) == napi_generic_failure) {
192         return GetUndefinedValue(env);
193     }
194     if (it->second.first(env, argv[1], napiStreamPlayer) != napi_ok) {
195         CLOGE("event name invalid");
196     }
197 
198     return GetUndefinedValue(env);
199 }
200 
OffEvent(napi_env env,napi_callback_info info)201 napi_value NapiStreamPlayer::OffEvent(napi_env env, napi_callback_info info)
202 {
203     constexpr size_t expectedArgc = 2;
204     napi_value argv[expectedArgc] = { 0 };
205     napi_valuetype expectedTypes[expectedArgc] = { napi_string, napi_function};
206     if (!GetJSFuncParams(env, info, argv, expectedArgc, expectedTypes)) {
207         return GetUndefinedValue(env);
208     }
209 
210     std::string eventName = ParseString(env, argv[0]);
211     auto it = eventHandlers_.find(eventName);
212     if (it == eventHandlers_.end()) {
213         CLOGE("event name invalid");
214         return GetUndefinedValue(env);
215     }
216     NapiStreamPlayer *napiStreamPlayer = GetNapiStreamPlayer(env, info);
217     if (napiStreamPlayer == nullptr) {
218         CLOGE("IStreamPlayer is null");
219         return GetUndefinedValue(env);
220     }
221     if (it->second.second(env, argv[1], napiStreamPlayer) != napi_ok) {
222         CLOGE("event name invalid");
223     }
224 
225     return GetUndefinedValue(env);
226 }
227 
OnStateChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)228 napi_status NapiStreamPlayer::OnStateChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
229 {
230     if (napiStreamPlayer == nullptr) {
231         CLOGE("napiStreamPlayer is null");
232         return napi_generic_failure;
233     }
234     if (!napiStreamPlayer->NapiListenerGetter()) {
235         CLOGE("napi stream player callback is null");
236         return napi_generic_failure;
237     }
238     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_PLAYER_STATUS_CHANGED,
239         callback) != napi_ok) {
240         return napi_generic_failure;
241     }
242     return napi_ok;
243 }
244 
OnPositionChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)245 napi_status NapiStreamPlayer::OnPositionChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
246 {
247     if (napiStreamPlayer == nullptr) {
248         CLOGE("napiStreamPlayer is null");
249         return napi_generic_failure;
250     }
251     if (!napiStreamPlayer->NapiListenerGetter()) {
252         CLOGE("napi stream player callback is null");
253         return napi_generic_failure;
254     }
255     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_POSITION_CHANGED,
256         callback) != napi_ok) {
257         return napi_generic_failure;
258     }
259     return napi_ok;
260 }
261 
OnMediaItemChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)262 napi_status NapiStreamPlayer::OnMediaItemChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
263 {
264     if (napiStreamPlayer == nullptr) {
265         CLOGE("napiStreamPlayer is null");
266         return napi_generic_failure;
267     }
268     if (!napiStreamPlayer->NapiListenerGetter()) {
269         CLOGE("napi stream player callback is null");
270         return napi_generic_failure;
271     }
272     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_MEDIA_ITEM_CHANGED,
273         callback) != napi_ok) {
274         return napi_generic_failure;
275     }
276     return napi_ok;
277 }
278 
OnVolumeChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)279 napi_status NapiStreamPlayer::OnVolumeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
280 {
281     if (napiStreamPlayer == nullptr) {
282         CLOGE("napiStreamPlayer is null");
283         return napi_generic_failure;
284     }
285     if (!napiStreamPlayer->NapiListenerGetter()) {
286         CLOGE("napi stream player callback is null");
287         return napi_generic_failure;
288     }
289     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_VOLUME_CHANGED,
290         callback) != napi_ok) {
291         return napi_generic_failure;
292     }
293     return napi_ok;
294 }
295 
OnVideoSizeChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)296 napi_status NapiStreamPlayer::OnVideoSizeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
297 {
298     if (napiStreamPlayer == nullptr) {
299         CLOGE("napiStreamPlayer is null");
300         return napi_generic_failure;
301     }
302     if (!napiStreamPlayer->NapiListenerGetter()) {
303         CLOGE("napi stream player callback is null");
304         return napi_generic_failure;
305     }
306     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_VIDEO_SIZE_CHANGED,
307         callback) != napi_ok) {
308         return napi_generic_failure;
309     }
310     return napi_ok;
311 }
312 
OnLoopModeChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)313 napi_status NapiStreamPlayer::OnLoopModeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
314 {
315     if (napiStreamPlayer == nullptr) {
316         CLOGE("napiStreamPlayer is null");
317         return napi_generic_failure;
318     }
319     if (!napiStreamPlayer->NapiListenerGetter()) {
320         CLOGE("napi stream player callback is null");
321         return napi_generic_failure;
322     }
323     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_LOOP_MODE_CHANGED,
324         callback) != napi_ok) {
325         return napi_generic_failure;
326     }
327     return napi_ok;
328 }
329 
OnPlaySpeedChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)330 napi_status NapiStreamPlayer::OnPlaySpeedChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
331 {
332     if (napiStreamPlayer == nullptr) {
333         CLOGE("napiStreamPlayer is null");
334         return napi_generic_failure;
335     }
336     if (!napiStreamPlayer->NapiListenerGetter()) {
337         CLOGE("napi stream player callback is null");
338         return napi_generic_failure;
339     }
340     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_PLAY_SPEED_CHANGED,
341         callback) != napi_ok) {
342         return napi_generic_failure;
343     }
344     return napi_ok;
345 }
346 
OnPlayerError(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)347 napi_status NapiStreamPlayer::OnPlayerError(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
348 {
349     if (napiStreamPlayer == nullptr) {
350         CLOGE("napiStreamPlayer is null");
351         return napi_generic_failure;
352     }
353     if (!napiStreamPlayer->NapiListenerGetter()) {
354         CLOGE("napi stream player callback is null");
355         return napi_generic_failure;
356     }
357     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_PLAYER_ERROR,
358         callback) != napi_ok) {
359         return napi_generic_failure;
360     }
361     return napi_ok;
362 }
363 
OnNextRequest(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)364 napi_status NapiStreamPlayer::OnNextRequest(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
365 {
366     if (napiStreamPlayer == nullptr) {
367         CLOGE("napiStreamPlayer is null");
368         return napi_generic_failure;
369     }
370     if (!napiStreamPlayer->NapiListenerGetter()) {
371         CLOGE("napi stream player callback is null");
372         return napi_generic_failure;
373     }
374     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_NEXT_REQUEST,
375         callback) != napi_ok) {
376         return napi_generic_failure;
377     }
378     return napi_ok;
379 }
380 
OnPreviousRequest(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)381 napi_status NapiStreamPlayer::OnPreviousRequest(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
382 {
383     if (napiStreamPlayer == nullptr) {
384         CLOGE("napiStreamPlayer is null");
385         return napi_generic_failure;
386     }
387     if (!napiStreamPlayer->NapiListenerGetter()) {
388         CLOGE("napi stream player callback is null");
389         return napi_generic_failure;
390     }
391     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_PREVIOUS_REQUEST,
392         callback) != napi_ok) {
393         return napi_generic_failure;
394     }
395     return napi_ok;
396 }
397 
OnSeekDone(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)398 napi_status NapiStreamPlayer::OnSeekDone(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
399 {
400     if (napiStreamPlayer == nullptr) {
401         CLOGE("napiStreamPlayer is null");
402         return napi_generic_failure;
403     }
404     if (!napiStreamPlayer->NapiListenerGetter()) {
405         CLOGE("napi stream player callback is null");
406         return napi_generic_failure;
407     }
408     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_SEEK_DONE,
409         callback) != napi_ok) {
410         return napi_generic_failure;
411     }
412     return napi_ok;
413 }
414 
OnEndOfStream(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)415 napi_status NapiStreamPlayer::OnEndOfStream(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
416 {
417     if (napiStreamPlayer == nullptr) {
418         CLOGE("napiStreamPlayer is null");
419         return napi_generic_failure;
420     }
421     if (!napiStreamPlayer->NapiListenerGetter()) {
422         CLOGE("napi stream player callback is null");
423         return napi_generic_failure;
424     }
425     if (napiStreamPlayer->NapiListenerGetter()->AddCallback(env, NapiStreamPlayerListener::EVENT_END_OF_STREAM,
426         callback) != napi_ok) {
427         return napi_generic_failure;
428     }
429     return napi_ok;
430 }
431 
OnImageChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)432 napi_status NapiStreamPlayer::OnImageChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
433 {
434     if (napiStreamPlayer == nullptr) {
435         CLOGE("napiStreamPlayer is null");
436         return napi_generic_failure;
437     }
438     auto napiListener = napiStreamPlayer->NapiListenerGetter();
439     if (!napiListener) {
440         CLOGE("napi stream player callback is null");
441         return napi_generic_failure;
442     }
443     if (napiListener->AddCallback(env, NapiStreamPlayerListener::EVENT_IMAGE_CHANGED,
444         callback) != napi_ok) {
445         return napi_generic_failure;
446     }
447     return napi_ok;
448 }
449 
OffStateChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)450 napi_status NapiStreamPlayer::OffStateChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
451 {
452     if (napiStreamPlayer == nullptr) {
453         CLOGE("napiStreamPlayer is null");
454         return napi_generic_failure;
455     }
456     if (!napiStreamPlayer->NapiListenerGetter()) {
457         CLOGE("napi stream player callback is null");
458         return napi_generic_failure;
459     }
460     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env,
461         NapiStreamPlayerListener::EVENT_PLAYER_STATUS_CHANGED, callback) != napi_ok) {
462         return napi_generic_failure;
463     }
464     return napi_ok;
465 }
466 
OffPositionChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)467 napi_status NapiStreamPlayer::OffPositionChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
468 {
469     if (napiStreamPlayer == nullptr) {
470         CLOGE("napiStreamPlayer is null");
471         return napi_generic_failure;
472     }
473     if (!napiStreamPlayer->NapiListenerGetter()) {
474         CLOGE("napi stream player callback is null");
475         return napi_generic_failure;
476     }
477     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_POSITION_CHANGED,
478         callback) != napi_ok) {
479         return napi_generic_failure;
480     }
481     return napi_ok;
482 }
483 
OffMediaItemChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)484 napi_status NapiStreamPlayer::OffMediaItemChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
485 {
486     if (napiStreamPlayer == nullptr) {
487         CLOGE("napiStreamPlayer is null");
488         return napi_generic_failure;
489     }
490     if (!napiStreamPlayer->NapiListenerGetter()) {
491         CLOGE("napi stream player callback is null");
492         return napi_generic_failure;
493     }
494     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_MEDIA_ITEM_CHANGED,
495         callback) != napi_ok) {
496         return napi_generic_failure;
497     }
498     return napi_ok;
499 }
500 
OffVolumeChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)501 napi_status NapiStreamPlayer::OffVolumeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
502 {
503     if (napiStreamPlayer == nullptr) {
504         CLOGE("napiStreamPlayer is null");
505         return napi_generic_failure;
506     }
507     if (!napiStreamPlayer->NapiListenerGetter()) {
508         CLOGE("napi stream player callback is null");
509         return napi_generic_failure;
510     }
511     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_VOLUME_CHANGED,
512         callback) != napi_ok) {
513         return napi_generic_failure;
514     }
515     return napi_ok;
516 }
517 
OffVideoSizeChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)518 napi_status NapiStreamPlayer::OffVideoSizeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
519 {
520     if (napiStreamPlayer == nullptr) {
521         CLOGE("napiStreamPlayer is null");
522         return napi_generic_failure;
523     }
524     if (!napiStreamPlayer->NapiListenerGetter()) {
525         CLOGE("napi stream player callback is null");
526         return napi_generic_failure;
527     }
528     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_VIDEO_SIZE_CHANGED,
529         callback) != napi_ok) {
530         return napi_generic_failure;
531     }
532     return napi_ok;
533 }
534 
OffLoopModeChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)535 napi_status NapiStreamPlayer::OffLoopModeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
536 {
537     if (napiStreamPlayer == nullptr) {
538         CLOGE("napiStreamPlayer is null");
539         return napi_generic_failure;
540     }
541     if (!napiStreamPlayer->NapiListenerGetter()) {
542         CLOGE("napi stream player callback is null");
543         return napi_generic_failure;
544     }
545     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_LOOP_MODE_CHANGED,
546         callback) != napi_ok) {
547         return napi_generic_failure;
548     }
549     return napi_ok;
550 }
551 
OffPlaySpeedChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)552 napi_status NapiStreamPlayer::OffPlaySpeedChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
553 {
554     if (napiStreamPlayer == nullptr) {
555         CLOGE("napiStreamPlayer is null");
556         return napi_generic_failure;
557     }
558     if (!napiStreamPlayer->NapiListenerGetter()) {
559         CLOGE("napi stream player callback is null");
560         return napi_generic_failure;
561     }
562     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_PLAY_SPEED_CHANGED,
563         callback) != napi_ok) {
564         return napi_generic_failure;
565     }
566     return napi_ok;
567 }
568 
OffPlayerError(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)569 napi_status NapiStreamPlayer::OffPlayerError(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
570 {
571     if (napiStreamPlayer == nullptr) {
572         CLOGE("napiStreamPlayer is null");
573         return napi_generic_failure;
574     }
575     if (!napiStreamPlayer->NapiListenerGetter()) {
576         CLOGE("napi stream player callback is null");
577         return napi_generic_failure;
578     }
579     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_PLAYER_ERROR,
580         callback) != napi_ok) {
581         return napi_generic_failure;
582     }
583     return napi_ok;
584 }
585 
OffNextRequest(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)586 napi_status NapiStreamPlayer::OffNextRequest(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
587 {
588     if (napiStreamPlayer == nullptr) {
589         CLOGE("napiStreamPlayer is null");
590         return napi_generic_failure;
591     }
592     if (!napiStreamPlayer->NapiListenerGetter()) {
593         CLOGE("napi stream player callback is null");
594         return napi_generic_failure;
595     }
596     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_NEXT_REQUEST,
597         callback) != napi_ok) {
598         return napi_generic_failure;
599     }
600     return napi_ok;
601 }
602 
OffPreviousRequest(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)603 napi_status NapiStreamPlayer::OffPreviousRequest(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
604 {
605     if (napiStreamPlayer == nullptr) {
606         CLOGE("napiStreamPlayer is null");
607         return napi_generic_failure;
608     }
609     if (!napiStreamPlayer->NapiListenerGetter()) {
610         CLOGE("napi stream player callback is null");
611         return napi_generic_failure;
612     }
613     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_PREVIOUS_REQUEST,
614         callback) != napi_ok) {
615         return napi_generic_failure;
616     }
617     return napi_ok;
618 }
619 
OffSeekDone(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)620 napi_status NapiStreamPlayer::OffSeekDone(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
621 {
622     if (napiStreamPlayer == nullptr) {
623         CLOGE("napiStreamPlayer is null");
624         return napi_generic_failure;
625     }
626     if (!napiStreamPlayer->NapiListenerGetter()) {
627         CLOGE("napi stream player callback is null");
628         return napi_generic_failure;
629     }
630     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_SEEK_DONE,
631         callback) != napi_ok) {
632         return napi_generic_failure;
633     }
634     return napi_ok;
635 }
636 
OffEndOfStream(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)637 napi_status NapiStreamPlayer::OffEndOfStream(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
638 {
639     if (napiStreamPlayer == nullptr) {
640         CLOGE("napiStreamPlayer is null");
641         return napi_generic_failure;
642     }
643     if (!napiStreamPlayer->NapiListenerGetter()) {
644         CLOGE("napi stream player callback is null");
645         return napi_generic_failure;
646     }
647     if (napiStreamPlayer->NapiListenerGetter()->RemoveCallback(env, NapiStreamPlayerListener::EVENT_END_OF_STREAM,
648         callback) != napi_ok) {
649         return napi_generic_failure;
650     }
651     return napi_ok;
652 }
653 
OffImageChanged(napi_env env,napi_value callback,NapiStreamPlayer * napiStreamPlayer)654 napi_status NapiStreamPlayer::OffImageChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer)
655 {
656     if (napiStreamPlayer == nullptr) {
657         CLOGE("napiStreamPlayer is null");
658         return napi_generic_failure;
659     }
660     auto napiListener = napiStreamPlayer->NapiListenerGetter();
661     if (!napiListener) {
662         CLOGE("napi stream player callback is null");
663         return napi_generic_failure;
664     }
665     if (napiListener->RemoveCallback(env, NapiStreamPlayerListener::EVENT_IMAGE_CHANGED,
666         callback) != napi_ok) {
667         return napi_generic_failure;
668     }
669     return napi_ok;
670 }
671 
RegisterNativeStreamPlayerListener(NapiStreamPlayer * napiStreamPlayer)672 napi_status NapiStreamPlayer::RegisterNativeStreamPlayerListener(NapiStreamPlayer *napiStreamPlayer)
673 {
674     if (napiStreamPlayer == nullptr) {
675         CLOGE("napiStreamPlayer is null");
676         return napi_generic_failure;
677     }
678     if (napiStreamPlayer->NapiListenerGetter()) {
679         return napi_ok;
680     }
681     auto streamPlayer = napiStreamPlayer->GetStreamPlayer();
682     if (!streamPlayer) {
683         CLOGE("StreamPlayer is null");
684         return napi_generic_failure;
685     }
686 
687     auto listener = std::make_shared<NapiStreamPlayerListener>();
688     if (!listener) {
689         CLOGE("Failed to malloc stream player listener");
690         return napi_generic_failure;
691     }
692     int32_t ret = streamPlayer->RegisterListener(listener);
693     if (ret != CAST_ENGINE_SUCCESS) {
694         CLOGE("native register stream player listener failed");
695         return napi_generic_failure;
696     }
697     napiStreamPlayer->NapiListenerSetter(listener);
698 
699     return napi_ok;
700 }
701 
SetSurface(napi_env env,napi_callback_info info)702 napi_value NapiStreamPlayer::SetSurface(napi_env env, napi_callback_info info)
703 {
704     CLOGD("Start to set surface in");
705     struct ConcreteTask : public NapiAsyncTask {
706         std::string surfaceId_;
707     };
708     auto napiAsyntask = std::make_shared<ConcreteTask>();
709     if (napiAsyntask == nullptr) {
710         CLOGE("Create NapiAsyncTask failed");
711         return GetUndefinedValue(env);
712     }
713 
714     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
715         constexpr size_t expectedArgc = 1;
716         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
717             NapiErrors::errcode_[ERR_INVALID_PARAM]);
718         napi_valuetype expectedTypes[expectedArgc] = { napi_string };
719         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
720         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
721             NapiErrors::errcode_[ERR_INVALID_PARAM]);
722         napiAsyntask->surfaceId_ = ParseString(env, argv[0]);
723     };
724     napiAsyntask->GetJSInfo(env, info, inputParser);
725     auto executor = [napiAsyntask]() {
726         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
727         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
728             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
729         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
730         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
731             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
732         int32_t ret = streamPlayer->SetSurface(napiAsyntask->surfaceId_);
733         if (ret != CAST_ENGINE_SUCCESS) {
734             if (ret == ERR_NO_PERMISSION) {
735                 napiAsyntask->errMessage = "SetStreamSurface failed : no permission";
736             } else if (ret == ERR_INVALID_PARAM) {
737                 napiAsyntask->errMessage = "SetStreamSurface failed : invalid parameters";
738             } else {
739                 napiAsyntask->errMessage = "SetStreamSurface failed : native server exception";
740             }
741             napiAsyntask->status = napi_generic_failure;
742             napiAsyntask->errCode = NapiErrors::errcode_[ret];
743         }
744     };
745 
746     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
747     return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetStreamSurface", executor, complete);
748 }
749 
Load(napi_env env,napi_callback_info info)750 napi_value NapiStreamPlayer::Load(napi_env env, napi_callback_info info)
751 {
752     CLOGD("Start to load in");
753     struct ConcreteTask : public NapiAsyncTask {
754         MediaInfo mediaInfo_;
755     };
756     auto napiAsyntask = std::make_shared<ConcreteTask>();
757     if (napiAsyntask == nullptr) {
758         CLOGE("Create NapiAsyncTask failed");
759         return GetUndefinedValue(env);
760     }
761 
762     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
763         constexpr size_t expectedArgc = 1;
764         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
765             NapiErrors::errcode_[ERR_INVALID_PARAM]);
766         napi_valuetype expectedTypes[expectedArgc] = { napi_object };
767         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
768         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
769             NapiErrors::errcode_[ERR_INVALID_PARAM]);
770         bool isMediaInfoValid = GetMediaInfoFromJS(env, argv[0], napiAsyntask->mediaInfo_);
771         CHECK_ARGS_RETURN_VOID(napiAsyntask, isMediaInfoValid, "invalid arguments",
772             NapiErrors::errcode_[ERR_INVALID_PARAM]);
773     };
774     napiAsyntask->GetJSInfo(env, info, inputParser);
775     auto executor = [napiAsyntask]() {
776         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
777         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
778             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
779         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
780         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
781             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
782         int32_t ret = streamPlayer->Load(napiAsyntask->mediaInfo_);
783         if (ret != CAST_ENGINE_SUCCESS) {
784             if (ret == ERR_NO_PERMISSION) {
785                 napiAsyntask->errMessage = "Load failed : no permission";
786             } else {
787                 napiAsyntask->errMessage = "Load failed : native server exception";
788             }
789             napiAsyntask->status = napi_generic_failure;
790             napiAsyntask->errCode = NapiErrors::errcode_[ret];
791         }
792     };
793 
794     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
795     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Load", executor, complete);
796 }
797 
Start(napi_env env,napi_callback_info info)798 napi_value NapiStreamPlayer::Start(napi_env env, napi_callback_info info)
799 {
800     CLOGD("Start to start in");
801     struct ConcreteTask : public NapiAsyncTask {
802         MediaInfo mediaInfo_;
803     };
804     auto napiAsyntask = std::make_shared<ConcreteTask>();
805     if (napiAsyntask == nullptr) {
806         CLOGE("Create NapiAsyncTask failed");
807         return GetUndefinedValue(env);
808     }
809 
810     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
811         constexpr size_t expectedArgc = 1;
812         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
813             NapiErrors::errcode_[ERR_INVALID_PARAM]);
814         napi_valuetype expectedTypes[expectedArgc] = { napi_object };
815         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
816         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
817             NapiErrors::errcode_[ERR_INVALID_PARAM]);
818         bool isMediaInfoValid = GetMediaInfoFromJS(env, argv[0], napiAsyntask->mediaInfo_);
819         CHECK_ARGS_RETURN_VOID(napiAsyntask, isMediaInfoValid, "invalid arguments",
820             NapiErrors::errcode_[ERR_INVALID_PARAM]);
821     };
822     napiAsyntask->GetJSInfo(env, info, inputParser);
823     auto executor = [napiAsyntask]() {
824         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
825         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
826             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
827         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
828         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
829             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
830         int32_t ret = streamPlayer->Play(napiAsyntask->mediaInfo_);
831         if (ret != CAST_ENGINE_SUCCESS) {
832             if (ret == ERR_NO_PERMISSION) {
833                 napiAsyntask->errMessage = "Start failed : no permission";
834             } else {
835                 napiAsyntask->errMessage = "Start failed : native server exception";
836             }
837             napiAsyntask->status = napi_generic_failure;
838             napiAsyntask->errCode = NapiErrors::errcode_[ret];
839         }
840     };
841 
842     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
843     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Start", executor, complete);
844 }
845 
Play(napi_env env,napi_callback_info info)846 napi_value NapiStreamPlayer::Play(napi_env env, napi_callback_info info)
847 {
848     CLOGD("Start to play in");
849     struct ConcreteTask : public NapiAsyncTask {
850         bool isRemotePlay_ = true;
851         int index_;
852     };
853     auto napiAsyntask = std::make_shared<ConcreteTask>();
854     if (napiAsyntask == nullptr) {
855         CLOGE("Create NapiAsyncTask failed");
856         return GetUndefinedValue(env);
857     }
858     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
859         constexpr size_t expectedRemotePlayArgc = 0;
860         constexpr size_t expectedLocalPlayArgc = 1;
861         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedRemotePlayArgc || argc == expectedLocalPlayArgc,
862             "invalid arguments", NapiErrors::errcode_[ERR_INVALID_PARAM]);
863         if (argc == expectedLocalPlayArgc) {
864             napi_valuetype expectedTypes[expectedLocalPlayArgc] = { napi_number };
865             bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedLocalPlayArgc, expectedTypes);
866             CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
867                 NapiErrors::errcode_[ERR_INVALID_PARAM]);
868             napiAsyntask->index_ = ParseInt32(env, argv[0]);
869             napiAsyntask->isRemotePlay_ = false;
870         }
871     };
872     napiAsyntask->GetJSInfo(env, info, inputParser);
873     auto executor = [napiAsyntask]() {
874         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
875         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
876             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
877         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
878         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
879             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
880         int32_t ret = CAST_ENGINE_ERROR;
881         if (napiAsyntask->isRemotePlay_) {
882             ret = streamPlayer->Play();
883         } else {
884             ret = streamPlayer->Play(napiAsyntask->index_);
885         }
886         if (ret != CAST_ENGINE_SUCCESS) {
887             napiAsyntask->errMessage = "Play failed";
888             napiAsyntask->status = napi_generic_failure;
889             napiAsyntask->errCode = NapiErrors::errcode_[ret];
890         }
891     };
892     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
893     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Play", executor, complete);
894 }
895 
Pause(napi_env env,napi_callback_info info)896 napi_value NapiStreamPlayer::Pause(napi_env env, napi_callback_info info)
897 {
898     CLOGD("Start to pause in");
899     auto napiAsyntask = std::make_shared<NapiAsyncTask>();
900     if (napiAsyntask == nullptr) {
901         CLOGE("Create NapiAsyncTask failed");
902         return GetUndefinedValue(env);
903     }
904 
905     napiAsyntask->GetJSInfo(env, info);
906     auto executor = [napiAsyntask]() {
907         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
908         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
909             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
910         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
911         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
912             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
913         int32_t ret = streamPlayer->Pause();
914         if (ret != CAST_ENGINE_SUCCESS) {
915             if (ret == ERR_NO_PERMISSION) {
916                 napiAsyntask->errMessage = "Pause failed : no permission";
917             } else {
918                 napiAsyntask->errMessage = "Pause failed : native server exception";
919             }
920             napiAsyntask->status = napi_generic_failure;
921             napiAsyntask->errCode = NapiErrors::errcode_[ret];
922         }
923     };
924 
925     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
926     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Pause", executor, complete);
927 }
928 
Stop(napi_env env,napi_callback_info info)929 napi_value NapiStreamPlayer::Stop(napi_env env, napi_callback_info info)
930 {
931     CLOGD("Start to stop in");
932     auto napiAsyntask = std::make_shared<NapiAsyncTask>();
933     if (napiAsyntask == nullptr) {
934         CLOGE("Create NapiAsyncTask failed");
935         return GetUndefinedValue(env);
936     }
937 
938     napiAsyntask->GetJSInfo(env, info);
939     auto executor = [napiAsyntask]() {
940         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
941         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
942             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
943         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
944         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
945             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
946         int32_t ret = streamPlayer->Stop();
947         if (ret != CAST_ENGINE_SUCCESS) {
948             if (ret == ERR_NO_PERMISSION) {
949                 napiAsyntask->errMessage = "Stop failed : no permission";
950             } else {
951                 napiAsyntask->errMessage = "Stop failed : native server exception";
952             }
953             napiAsyntask->status = napi_generic_failure;
954             napiAsyntask->errCode = NapiErrors::errcode_[ret];
955         }
956     };
957 
958     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
959     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Stop", executor, complete);
960 }
961 
Next(napi_env env,napi_callback_info info)962 napi_value NapiStreamPlayer::Next(napi_env env, napi_callback_info info)
963 {
964     CLOGD("Start to next in");
965     auto napiAsyntask = std::make_shared<NapiAsyncTask>();
966     if (napiAsyntask == nullptr) {
967         CLOGE("Create NapiAsyncTask failed");
968         return GetUndefinedValue(env);
969     }
970 
971     napiAsyntask->GetJSInfo(env, info);
972     auto executor = [napiAsyntask]() {
973         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
974         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
975             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
976         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
977         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
978             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
979         int32_t ret = streamPlayer->Next();
980         if (ret != CAST_ENGINE_SUCCESS) {
981             if (ret == ERR_NO_PERMISSION) {
982                 napiAsyntask->errMessage = "Next failed : no permission";
983             } else {
984                 napiAsyntask->errMessage = "Next failed : native server exception";
985             }
986             napiAsyntask->status = napi_generic_failure;
987             napiAsyntask->errCode = NapiErrors::errcode_[ret];
988         }
989     };
990 
991     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
992     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Next", executor, complete);
993 }
994 
Previous(napi_env env,napi_callback_info info)995 napi_value NapiStreamPlayer::Previous(napi_env env, napi_callback_info info)
996 {
997     CLOGD("Start to previous in");
998     auto napiAsyntask = std::make_shared<NapiAsyncTask>();
999     if (napiAsyntask == nullptr) {
1000         CLOGE("Create NapiAsyncTask failed");
1001         return GetUndefinedValue(env);
1002     }
1003 
1004     napiAsyntask->GetJSInfo(env, info);
1005     auto executor = [napiAsyntask]() {
1006         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1007         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1008             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1009         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1010         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1011             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1012         int32_t ret = streamPlayer->Previous();
1013         if (ret != CAST_ENGINE_SUCCESS) {
1014             if (ret == ERR_NO_PERMISSION) {
1015                 napiAsyntask->errMessage = "Previous failed : no permission";
1016             } else {
1017                 napiAsyntask->errMessage = "Previous failed : native server exception";
1018             }
1019             napiAsyntask->status = napi_generic_failure;
1020             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1021         }
1022     };
1023 
1024     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1025     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Previous", executor, complete);
1026 }
1027 
Seek(napi_env env,napi_callback_info info)1028 napi_value NapiStreamPlayer::Seek(napi_env env, napi_callback_info info)
1029 {
1030     CLOGD("Start to seek in");
1031     struct ConcreteTask : public NapiAsyncTask {
1032         int position_;
1033     };
1034     auto napiAsyntask = std::make_shared<ConcreteTask>();
1035     if (napiAsyntask == nullptr) {
1036         CLOGE("Create NapiAsyncTask failed");
1037         return GetUndefinedValue(env);
1038     }
1039 
1040     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
1041         constexpr size_t expectedArgc = 1;
1042         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
1043             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1044         napi_valuetype expectedTypes[expectedArgc] = { napi_number };
1045         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
1046         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
1047             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1048         napiAsyntask->position_ = ParseInt32(env, argv[0]);
1049     };
1050     napiAsyntask->GetJSInfo(env, info, inputParser);
1051     auto executor = [napiAsyntask]() {
1052         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1053         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1054             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1055         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1056         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1057             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1058         int32_t ret = streamPlayer->Seek(napiAsyntask->position_);
1059         if (ret != CAST_ENGINE_SUCCESS) {
1060             if (ret == ERR_NO_PERMISSION) {
1061                 napiAsyntask->errMessage = "Seek failed : no permission";
1062             } else if (ret == ERR_INVALID_PARAM) {
1063                 napiAsyntask->errMessage = "Seek failed : invalid parameters";
1064             } else {
1065                 napiAsyntask->errMessage = "Seek failed : native server exception";
1066             }
1067             napiAsyntask->status = napi_generic_failure;
1068             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1069         }
1070     };
1071 
1072     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1073     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Seek", executor, complete);
1074 }
1075 
FastForward(napi_env env,napi_callback_info info)1076 napi_value NapiStreamPlayer::FastForward(napi_env env, napi_callback_info info)
1077 {
1078     CLOGD("Start to FastForward in");
1079     struct ConcreteTask : public NapiAsyncTask {
1080         int delta_;
1081     };
1082     auto napiAsyntask = std::make_shared<ConcreteTask>();
1083     if (napiAsyntask == nullptr) {
1084         CLOGE("Create NapiAsyncTask failed");
1085         return GetUndefinedValue(env);
1086     }
1087 
1088     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
1089         constexpr size_t expectedArgc = 1;
1090         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
1091             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1092         napi_valuetype expectedTypes[expectedArgc] = { napi_number };
1093         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
1094         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
1095             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1096         napiAsyntask->delta_ = ParseInt32(env, argv[0]);
1097     };
1098     napiAsyntask->GetJSInfo(env, info, inputParser);
1099     auto executor = [napiAsyntask]() {
1100         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1101         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1102             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1103         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1104         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1105             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1106         int32_t ret = streamPlayer->FastForward(napiAsyntask->delta_);
1107         if (ret != CAST_ENGINE_SUCCESS) {
1108             if (ret == ERR_NO_PERMISSION) {
1109                 napiAsyntask->errMessage = "FastForward failed : no permission";
1110             } else if (ret == ERR_INVALID_PARAM) {
1111                 napiAsyntask->errMessage = "FastForward failed : invalid parameters";
1112             } else {
1113                 napiAsyntask->errMessage = "FastForward failed : native server exception";
1114             }
1115             napiAsyntask->status = napi_generic_failure;
1116             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1117         }
1118     };
1119 
1120     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1121     return NapiAsyncWork::Enqueue(env, napiAsyntask, "FastForward", executor, complete);
1122 }
1123 
FastRewind(napi_env env,napi_callback_info info)1124 napi_value NapiStreamPlayer::FastRewind(napi_env env, napi_callback_info info)
1125 {
1126     CLOGD("Start to FastRewind in");
1127     struct ConcreteTask : public NapiAsyncTask {
1128         int delta_;
1129     };
1130     auto napiAsyntask = std::make_shared<ConcreteTask>();
1131     if (napiAsyntask == nullptr) {
1132         CLOGE("Create NapiAsyncTask failed");
1133         return GetUndefinedValue(env);
1134     }
1135 
1136     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
1137         constexpr size_t expectedArgc = 1;
1138         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
1139             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1140         napi_valuetype expectedTypes[expectedArgc] = { napi_number };
1141         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
1142         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
1143             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1144         napiAsyntask->delta_ = ParseInt32(env, argv[0]);
1145     };
1146     napiAsyntask->GetJSInfo(env, info, inputParser);
1147     auto executor = [napiAsyntask]() {
1148         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1149         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1150             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1151         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1152         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1153             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1154         int32_t ret = streamPlayer->FastRewind(napiAsyntask->delta_);
1155         if (ret != CAST_ENGINE_SUCCESS) {
1156             if (ret == ERR_NO_PERMISSION) {
1157                 napiAsyntask->errMessage = "FastRewind failed : no permission";
1158             } else if (ret == ERR_INVALID_PARAM) {
1159                 napiAsyntask->errMessage = "FastRewind failed : invalid parameters";
1160             } else {
1161                 napiAsyntask->errMessage = "FastRewind failed : native server exception";
1162             }
1163             napiAsyntask->status = napi_generic_failure;
1164             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1165         }
1166     };
1167 
1168     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1169     return NapiAsyncWork::Enqueue(env, napiAsyntask, "FastRewind", executor, complete);
1170 }
1171 
SetVolume(napi_env env,napi_callback_info info)1172 napi_value NapiStreamPlayer::SetVolume(napi_env env, napi_callback_info info)
1173 {
1174     CLOGD("Start to set volume in");
1175     struct ConcreteTask : public NapiAsyncTask {
1176         int volume_;
1177     };
1178     auto napiAsyntask = std::make_shared<ConcreteTask>();
1179     if (napiAsyntask == nullptr) {
1180         CLOGE("Create NapiAsyncTask failed");
1181         return GetUndefinedValue(env);
1182     }
1183 
1184     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
1185         constexpr size_t expectedArgc = 1;
1186         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
1187             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1188         napi_valuetype expectedTypes[expectedArgc] = { napi_number };
1189         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
1190         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
1191             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1192         napiAsyntask->volume_ = ParseInt32(env, argv[0]);
1193     };
1194     napiAsyntask->GetJSInfo(env, info, inputParser);
1195     auto executor = [napiAsyntask]() {
1196         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1197         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1198             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1199         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1200         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1201             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1202         int32_t ret = streamPlayer->SetVolume(napiAsyntask->volume_);
1203         if (ret != CAST_ENGINE_SUCCESS) {
1204             if (ret == ERR_NO_PERMISSION) {
1205                 napiAsyntask->errMessage = "SetVolume failed : no permission";
1206             } else if (ret == ERR_INVALID_PARAM) {
1207                 napiAsyntask->errMessage = "SetVolume failed : invalid parameters";
1208             } else {
1209                 napiAsyntask->errMessage = "SetVolume failed : native server exception";
1210             }
1211             napiAsyntask->status = napi_generic_failure;
1212             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1213         }
1214     };
1215 
1216     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1217     return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetVolume", executor, complete);
1218 }
1219 
SetLoopMode(napi_env env,napi_callback_info info)1220 napi_value NapiStreamPlayer::SetLoopMode(napi_env env, napi_callback_info info)
1221 {
1222     CLOGD("Start to set loop mode in");
1223     struct ConcreteTask : public NapiAsyncTask {
1224         LoopMode loopmode_;
1225     };
1226     auto napiAsyntask = std::make_shared<ConcreteTask>();
1227     if (napiAsyntask == nullptr) {
1228         CLOGE("Create NapiAsyncTask failed");
1229         return GetUndefinedValue(env);
1230     }
1231 
1232     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
1233         constexpr size_t expectedArgc = 1;
1234         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
1235             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1236         napi_valuetype expectedTypes[expectedArgc] = { napi_number };
1237         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
1238         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
1239             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1240         napiAsyntask->loopmode_ = static_cast<LoopMode>(ParseInt32(env, argv[0]));
1241     };
1242     napiAsyntask->GetJSInfo(env, info, inputParser);
1243     auto executor = [napiAsyntask]() {
1244         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1245         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1246             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1247         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1248         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1249             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1250         int32_t ret = streamPlayer->SetLoopMode(napiAsyntask->loopmode_);
1251         if (ret != CAST_ENGINE_SUCCESS) {
1252             if (ret == ERR_NO_PERMISSION) {
1253                 napiAsyntask->errMessage = "SetLoopMode failed : no permission";
1254             } else if (ret == ERR_INVALID_PARAM) {
1255                 napiAsyntask->errMessage = "SetLoopMode failed : invalid parameters";
1256             } else {
1257                 napiAsyntask->errMessage = "SetLoopMode failed : native server exception";
1258             }
1259             napiAsyntask->status = napi_generic_failure;
1260             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1261         }
1262     };
1263 
1264     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1265     return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetLoopMode", executor, complete);
1266 }
1267 
SetSpeed(napi_env env,napi_callback_info info)1268 napi_value NapiStreamPlayer::SetSpeed(napi_env env, napi_callback_info info)
1269 {
1270     CLOGD("Start to set speed in");
1271     struct ConcreteTask : public NapiAsyncTask {
1272         PlaybackSpeed speed_;
1273     };
1274     auto napiAsyntask = std::make_shared<ConcreteTask>();
1275     if (napiAsyntask == nullptr) {
1276         CLOGE("Create NapiAsyncTask failed");
1277         return GetUndefinedValue(env);
1278     }
1279 
1280     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
1281         constexpr size_t expectedArgc = 1;
1282         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
1283             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1284         napi_valuetype expectedTypes[expectedArgc] = { napi_number };
1285         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
1286         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
1287             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1288         napiAsyntask->speed_ = static_cast<PlaybackSpeed>(ParseInt32(env, argv[0]));
1289     };
1290     napiAsyntask->GetJSInfo(env, info, inputParser);
1291     auto executor = [napiAsyntask]() {
1292         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1293         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1294             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1295         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1296         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1297             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1298         int32_t ret = streamPlayer->SetSpeed(napiAsyntask->speed_);
1299         if (ret != CAST_ENGINE_SUCCESS) {
1300             if (ret == ERR_NO_PERMISSION) {
1301                 napiAsyntask->errMessage = "SetSpeed failed : no permission";
1302             } else if (ret == ERR_INVALID_PARAM) {
1303                 napiAsyntask->errMessage = "SetSpeed failed : invalid parameters";
1304             } else {
1305                 napiAsyntask->errMessage = "SetSpeed failed : native server exception";
1306             }
1307             napiAsyntask->status = napi_generic_failure;
1308             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1309         }
1310     };
1311 
1312     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1313     return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetSpeed", executor, complete);
1314 }
1315 
SetMute(napi_env env,napi_callback_info info)1316 napi_value NapiStreamPlayer::SetMute(napi_env env, napi_callback_info info)
1317 {
1318     CLOGD("Start to set mute in");
1319     struct ConcreteTask : public NapiAsyncTask {
1320         bool setMute_;
1321     };
1322     auto napiAsyntask = std::make_shared<ConcreteTask>();
1323     if (napiAsyntask == nullptr) {
1324         CLOGE("Create NapiAsyncTask failed");
1325         return GetUndefinedValue(env);
1326     }
1327 
1328     auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
1329         constexpr size_t expectedArgc = 1;
1330         CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
1331             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1332         napi_valuetype expectedTypes[expectedArgc] = { napi_boolean };
1333         bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
1334         CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
1335             NapiErrors::errcode_[ERR_INVALID_PARAM]);
1336         napiAsyntask->setMute_ = ParseBool(env, argv[0]);
1337     };
1338     napiAsyntask->GetJSInfo(env, info, inputParser);
1339     auto executor = [napiAsyntask]() {
1340         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1341         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1342             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1343         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1344         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1345             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1346         int32_t ret = streamPlayer->SetMute(napiAsyntask->setMute_);
1347         if (ret != CAST_ENGINE_SUCCESS) {
1348             if (ret == ERR_NO_PERMISSION) {
1349                 napiAsyntask->errMessage = "SetMute failed : no permission";
1350             } else {
1351                 napiAsyntask->errMessage = "SetMute failed : native server exception";
1352             }
1353             napiAsyntask->status = napi_generic_failure;
1354             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1355         }
1356     };
1357 
1358     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1359     return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetSpeed", executor, complete);
1360 }
1361 
GetPlayerStatus(napi_env env,napi_callback_info info)1362 napi_value NapiStreamPlayer::GetPlayerStatus(napi_env env, napi_callback_info info)
1363 {
1364     CLOGD("Start to get player status in");
1365     struct ConcreteTask : public NapiAsyncTask {
1366         PlayerStates playerStatus_;
1367     };
1368     auto napiAsyntask = std::make_shared<ConcreteTask>();
1369     if (napiAsyntask == nullptr) {
1370         CLOGE("Create NapiAsyncTask failed");
1371         return GetUndefinedValue(env);
1372     }
1373 
1374     napiAsyntask->GetJSInfo(env, info);
1375     auto executor = [napiAsyntask]() {
1376         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1377         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1378             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1379         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1380         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1381             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1382         int32_t ret = streamPlayer->GetPlayerStatus(napiAsyntask->playerStatus_);
1383         if (ret != CAST_ENGINE_SUCCESS) {
1384             if (ret == ERR_NO_PERMISSION) {
1385                 napiAsyntask->errMessage = "GetPlayerStatus failed : no permission";
1386             } else {
1387                 napiAsyntask->errMessage = "GetPlayerStatus failed : native server exception";
1388             }
1389             napiAsyntask->status = napi_generic_failure;
1390             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1391         }
1392     };
1393 
1394     auto complete = [env, napiAsyntask](napi_value &output) {
1395         napiAsyntask->status = napi_create_int32(env, static_cast<int32_t>(napiAsyntask->playerStatus_), &output);
1396         CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_int32 failed", NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1397     };
1398     return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetPlayerStatus", executor, complete);
1399 }
1400 
GetPosition(napi_env env,napi_callback_info info)1401 napi_value NapiStreamPlayer::GetPosition(napi_env env, napi_callback_info info)
1402 {
1403     CLOGD("Start to get position in");
1404     struct ConcreteTask : public NapiAsyncTask {
1405         int position_;
1406     };
1407     auto napiAsyntask = std::make_shared<ConcreteTask>();
1408     if (napiAsyntask == nullptr) {
1409         CLOGE("Create NapiAsyncTask failed");
1410         return GetUndefinedValue(env);
1411     }
1412 
1413     napiAsyntask->GetJSInfo(env, info);
1414     auto executor = [napiAsyntask]() {
1415         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1416         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1417             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1418         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1419         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1420             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1421         int32_t ret = streamPlayer->GetPosition(napiAsyntask->position_);
1422         if (ret != CAST_ENGINE_SUCCESS) {
1423             if (ret == ERR_NO_PERMISSION) {
1424                 napiAsyntask->errMessage = "GetPosition failed : no permission";
1425             } else {
1426                 napiAsyntask->errMessage = "GetPosition failed : native server exception";
1427             }
1428             napiAsyntask->status = napi_generic_failure;
1429             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1430         }
1431     };
1432 
1433     auto complete = [env, napiAsyntask](napi_value &output) {
1434         napiAsyntask->status = napi_create_int32(env, napiAsyntask->position_, &output);
1435         CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_int32 failed", NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1436     };
1437     return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetPosition", executor, complete);
1438 }
1439 
GetVolume(napi_env env,napi_callback_info info)1440 napi_value NapiStreamPlayer::GetVolume(napi_env env, napi_callback_info info)
1441 {
1442     CLOGD("Start to get volume in");
1443     struct ConcreteTask : public NapiAsyncTask {
1444         int volume_;
1445         int maxVolume_;
1446     };
1447     auto napiAsyntask = std::make_shared<ConcreteTask>();
1448     if (napiAsyntask == nullptr) {
1449         CLOGE("Create NapiAsyncTask failed");
1450         return GetUndefinedValue(env);
1451     }
1452 
1453     napiAsyntask->GetJSInfo(env, info);
1454     auto executor = [napiAsyntask]() {
1455         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1456         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1457             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1458         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1459         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1460             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1461         int32_t ret = streamPlayer->GetVolume(napiAsyntask->volume_, napiAsyntask->maxVolume_);
1462         if (ret != CAST_ENGINE_SUCCESS) {
1463             if (ret == ERR_NO_PERMISSION) {
1464                 napiAsyntask->errMessage = "GetVolume failed : no permission";
1465             } else {
1466                 napiAsyntask->errMessage = "GetVolume failed : native server exception";
1467             }
1468             napiAsyntask->status = napi_generic_failure;
1469             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1470         }
1471     };
1472 
1473     auto complete = [env, napiAsyntask](napi_value &output) {
1474         napiAsyntask->status = napi_create_int32(env, napiAsyntask->volume_, &output);
1475         CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_int32 failed", NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1476     };
1477     return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetVolume", executor, complete);
1478 }
1479 
GetMute(napi_env env,napi_callback_info info)1480 napi_value NapiStreamPlayer::GetMute(napi_env env, napi_callback_info info)
1481 {
1482     CLOGD("Start to get mute in");
1483     struct ConcreteTask : public NapiAsyncTask {
1484         bool isMute_;
1485     };
1486     auto napiAsyntask = std::make_shared<ConcreteTask>();
1487     if (napiAsyntask == nullptr) {
1488         CLOGE("Create NapiAsyncTask failed");
1489         return GetUndefinedValue(env);
1490     }
1491 
1492     napiAsyntask->GetJSInfo(env, info);
1493     auto executor = [napiAsyntask]() {
1494         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1495         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1496             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1497         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1498         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1499             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1500         int32_t ret = streamPlayer->GetMute(napiAsyntask->isMute_);
1501         if (ret != CAST_ENGINE_SUCCESS) {
1502             if (ret == ERR_NO_PERMISSION) {
1503                 napiAsyntask->errMessage = "GetMute failed : no permission";
1504             } else {
1505                 napiAsyntask->errMessage = "GetMute failed : native server exception";
1506             }
1507             napiAsyntask->status = napi_generic_failure;
1508             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1509         }
1510     };
1511 
1512     auto complete = [env, napiAsyntask](napi_value &output) {
1513         napiAsyntask->status = napi_create_int32(env, napiAsyntask->isMute_, &output);
1514         CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_int32 failed", NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1515     };
1516     return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetMute", executor, complete);
1517 }
1518 
GetLoopMode(napi_env env,napi_callback_info info)1519 napi_value NapiStreamPlayer::GetLoopMode(napi_env env, napi_callback_info info)
1520 {
1521     CLOGD("Start to get loop mode in");
1522     struct ConcreteTask : public NapiAsyncTask {
1523         LoopMode loopMode_;
1524     };
1525     auto napiAsyntask = std::make_shared<ConcreteTask>();
1526     if (napiAsyntask == nullptr) {
1527         CLOGE("Create NapiAsyncTask failed");
1528         return GetUndefinedValue(env);
1529     }
1530 
1531     napiAsyntask->GetJSInfo(env, info);
1532     auto executor = [napiAsyntask]() {
1533         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1534         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1535             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1536         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1537         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1538             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1539         int32_t ret = streamPlayer->GetLoopMode(napiAsyntask->loopMode_);
1540         if (ret != CAST_ENGINE_SUCCESS) {
1541             if (ret == ERR_NO_PERMISSION) {
1542                 napiAsyntask->errMessage = "GetLoopMode failed : no permission";
1543             } else {
1544                 napiAsyntask->errMessage = "GetLoopMode failed : native server exception";
1545             }
1546             napiAsyntask->status = napi_generic_failure;
1547             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1548         }
1549     };
1550 
1551     auto complete = [env, napiAsyntask](napi_value &output) {
1552         napiAsyntask->status = napi_create_int32(env, static_cast<int32_t>(napiAsyntask->loopMode_), &output);
1553         CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_int32 failed", NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1554     };
1555     return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetLoopMode", executor, complete);
1556 }
1557 
GetPlaySpeed(napi_env env,napi_callback_info info)1558 napi_value NapiStreamPlayer::GetPlaySpeed(napi_env env, napi_callback_info info)
1559 {
1560     CLOGD("Start to get play speed in");
1561     struct ConcreteTask : public NapiAsyncTask {
1562         PlaybackSpeed speed_;
1563     };
1564     auto napiAsyntask = std::make_shared<ConcreteTask>();
1565     if (napiAsyntask == nullptr) {
1566         CLOGE("Create NapiAsyncTask failed");
1567         return GetUndefinedValue(env);
1568     }
1569 
1570     napiAsyntask->GetJSInfo(env, info);
1571     auto executor = [napiAsyntask]() {
1572         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1573         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1574             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1575         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1576         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1577             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1578         int32_t ret = streamPlayer->GetPlaySpeed(napiAsyntask->speed_);
1579         if (ret != CAST_ENGINE_SUCCESS) {
1580             if (ret == ERR_NO_PERMISSION) {
1581                 napiAsyntask->errMessage = "GetPlaySpeed failed : no permission";
1582             } else {
1583                 napiAsyntask->errMessage = "GetPlaySpeed failed : native server exception";
1584             }
1585             napiAsyntask->status = napi_generic_failure;
1586             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1587         }
1588     };
1589 
1590     auto complete = [env, napiAsyntask](napi_value &output) {
1591         napiAsyntask->status = napi_create_int32(env, static_cast<int32_t>(napiAsyntask->speed_), &output);
1592         CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_int32 failed", NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1593     };
1594     return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetPlaySpeed", executor, complete);
1595 }
1596 
GetMediaInfoHolder(napi_env env,napi_callback_info info)1597 napi_value NapiStreamPlayer::GetMediaInfoHolder(napi_env env, napi_callback_info info)
1598 {
1599     CLOGD("Start to get play info holder in");
1600     struct ConcreteTask : public NapiAsyncTask {
1601         MediaInfoHolder mediaInfoHolder_;
1602     };
1603     auto napiAsyntask = std::make_shared<ConcreteTask>();
1604     if (napiAsyntask == nullptr) {
1605         CLOGE("Create NapiAsyncTask failed");
1606         return GetUndefinedValue(env);
1607     }
1608 
1609     napiAsyntask->GetJSInfo(env, info);
1610     auto executor = [napiAsyntask]() {
1611         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1612         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1613             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1614         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1615         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1616             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1617         int32_t ret = streamPlayer->GetMediaInfoHolder(napiAsyntask->mediaInfoHolder_);
1618         if (ret != CAST_ENGINE_SUCCESS) {
1619             if (ret == ERR_NO_PERMISSION) {
1620                 napiAsyntask->errMessage = "GetMediaInfoHolder failed : no permission";
1621             } else {
1622                 napiAsyntask->errMessage = "GetMediaInfoHolder failed : native server exception";
1623             }
1624             napiAsyntask->status = napi_generic_failure;
1625             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1626         }
1627     };
1628 
1629     auto complete = [napiAsyntask](napi_value &output) {
1630         output = ConvertMediaInfoHolderToJS(napiAsyntask->env, napiAsyntask->mediaInfoHolder_);
1631     };
1632     return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetMediaInfoHolder", executor, complete);
1633 }
1634 
Release(napi_env env,napi_callback_info info)1635 napi_value NapiStreamPlayer::Release(napi_env env, napi_callback_info info)
1636 {
1637     CLOGD("Start to release in");
1638     auto napiAsyntask = std::make_shared<NapiAsyncTask>();
1639     if (napiAsyntask == nullptr) {
1640         CLOGE("Create NapiAsyncTask failed");
1641         return GetUndefinedValue(env);
1642     }
1643     napiAsyntask->GetJSInfo(env, info);
1644 
1645     auto executor = [napiAsyntask]() {
1646         auto *napiStreamPlayer = reinterpret_cast<NapiStreamPlayer *>(napiAsyntask->native);
1647         CHECK_ARGS_RETURN_VOID(napiAsyntask, napiStreamPlayer != nullptr, "napiStreamPlayer is null",
1648             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1649         std::shared_ptr<IStreamPlayer> streamPlayer = napiStreamPlayer->GetStreamPlayer();
1650         CHECK_ARGS_RETURN_VOID(napiAsyntask, streamPlayer, "IStreamPlayer is null",
1651             NapiErrors::errcode_[CAST_ENGINE_ERROR]);
1652         int32_t ret = streamPlayer->Release();
1653         if (ret == CAST_ENGINE_SUCCESS) {
1654             napiStreamPlayer->Reset();
1655         } else if (ret == ERR_NO_PERMISSION) {
1656             napiAsyntask->errMessage = "Release failed : no permission";
1657             napiAsyntask->status = napi_generic_failure;
1658             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1659         } else {
1660             napiAsyntask->errMessage = "Release failed : native server exception";
1661             napiAsyntask->status = napi_generic_failure;
1662             napiAsyntask->errCode = NapiErrors::errcode_[ret];
1663         }
1664     };
1665 
1666     auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
1667     return NapiAsyncWork::Enqueue(env, napiAsyntask, "Release", executor, complete);
1668 }
1669 
NapiListenerGetter()1670 std::shared_ptr<NapiStreamPlayerListener> NapiStreamPlayer::NapiListenerGetter()
1671 {
1672     std::lock_guard<std::mutex> lock(mutex_);
1673     return listener_;
1674 }
1675 
NapiListenerSetter(std::shared_ptr<NapiStreamPlayerListener> listener)1676 void NapiStreamPlayer::NapiListenerSetter(std::shared_ptr<NapiStreamPlayerListener> listener)
1677 {
1678     std::lock_guard<std::mutex> lock(mutex_);
1679     listener_ = listener;
1680 }
1681 } // namespace CastEngineClient
1682 } // namespace CastEngine
1683 } // namespace OHOS