• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "avplayer_callback.h"
17 #include <uv.h>
18 #include "avplayer_napi.h"
19 #include "media_errors.h"
20 #include "media_log.h"
21 #include "scope_guard.h"
22 #include "event_queue.h"
23 
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVPlayerCallback"};
26 }
27 
28 namespace OHOS {
29 namespace Media {
30 class NapiCallback {
31 public:
32     struct Base {
33         std::weak_ptr<AutoRef> callback;
34         std::string callbackName = "unknown";
35         Base() = default;
36         virtual ~Base() = default;
UvWorkOHOS::Media::NapiCallback::Base37         virtual void UvWork()
38         {
39             std::shared_ptr<AutoRef> ref = callback.lock();
40             CHECK_AND_RETURN_LOG(ref != nullptr,
41                 "%{public}s AutoRef is nullptr", callbackName.c_str());
42 
43             napi_handle_scope scope = nullptr;
44             napi_open_handle_scope(ref->env_, &scope);
45             CHECK_AND_RETURN_LOG(scope != nullptr,
46                 "%{public}s scope is nullptr", callbackName.c_str());
47             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
48 
49             napi_value jsCallback = nullptr;
50             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
51             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
52                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
53 
54             // Call back function
55             napi_value result = nullptr;
56             status = napi_call_function(ref->env_, nullptr, jsCallback, 0, nullptr, &result);
57             CHECK_AND_RETURN_LOG(status == napi_ok,
58                 "%{public}s failed to napi_call_function", callbackName.c_str());
59         }
JsCallbackOHOS::Media::NapiCallback::Base60         virtual void JsCallback()
61         {
62             UvWork();
63             delete this;
64         }
65     };
66 
67     struct Error : public Base {
68         std::string errorMsg = "unknown";
69         MediaServiceExtErrCodeAPI9 errorCode = MSERR_EXT_API9_UNSUPPORT_FORMAT;
UvWorkOHOS::Media::NapiCallback::Error70         void UvWork() override
71         {
72             std::shared_ptr<AutoRef> ref = callback.lock();
73             CHECK_AND_RETURN_LOG(ref != nullptr,
74                 "%{public}s AutoRef is nullptr", callbackName.c_str());
75 
76             napi_handle_scope scope = nullptr;
77             napi_open_handle_scope(ref->env_, &scope);
78             CHECK_AND_RETURN_LOG(scope != nullptr,
79                 "%{public}s scope is nullptr", callbackName.c_str());
80             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
81 
82             napi_value jsCallback = nullptr;
83             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
84             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
85                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
86 
87             napi_value args[1] = {nullptr};
88             (void)CommonNapi::CreateError(ref->env_, errorCode, errorMsg, args[0]);
89 
90             // Call back function
91             napi_value result = nullptr;
92             status = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
93             CHECK_AND_RETURN_LOG(status == napi_ok,
94                 "%{public}s failed to napi_call_function", callbackName.c_str());
95         }
96     };
97 
98     struct Int : public Base {
99         int32_t value = 0;
UvWorkOHOS::Media::NapiCallback::Int100         void UvWork() override
101         {
102             std::shared_ptr<AutoRef> ref = callback.lock();
103             CHECK_AND_RETURN_LOG(ref != nullptr,
104                 "%{public}s AutoRef is nullptr", callbackName.c_str());
105 
106             napi_handle_scope scope = nullptr;
107             napi_open_handle_scope(ref->env_, &scope);
108             CHECK_AND_RETURN_LOG(scope != nullptr,
109                 "%{public}s scope is nullptr", callbackName.c_str());
110             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
111 
112             napi_value jsCallback = nullptr;
113             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
114             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
115                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
116 
117             napi_value args[1] = {nullptr}; // callback: (int)
118             (void)napi_create_int32(ref->env_, value, &args[0]);
119 
120             napi_value result = nullptr;
121             status = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
122             CHECK_AND_RETURN_LOG(status == napi_ok,
123                 "%{public}s failed to napi_call_function", callbackName.c_str());
124         }
125     };
126 
127     struct IntVec : public Base {
128         std::vector<int32_t> valueVec;
UvWorkOHOS::Media::NapiCallback::IntVec129         void UvWork() override
130         {
131             std::shared_ptr<AutoRef> ref = callback.lock();
132             CHECK_AND_RETURN_LOG(ref != nullptr,
133                 "%{public}s AutoRef is nullptr", callbackName.c_str());
134 
135             napi_handle_scope scope = nullptr;
136             napi_open_handle_scope(ref->env_, &scope);
137             CHECK_AND_RETURN_LOG(scope != nullptr,
138                 "%{public}s scope is nullptr", callbackName.c_str());
139             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
140 
141             napi_value jsCallback = nullptr;
142             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
143             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
144                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
145 
146             napi_value args[2] = {nullptr}; // callback: (int, int)
147             (void)napi_create_int32(ref->env_, valueVec[0], &args[0]);
148             (void)napi_create_int32(ref->env_, valueVec[1], &args[1]);
149 
150             const int32_t argCount = static_cast<int32_t>(valueVec.size());
151             napi_value result = nullptr;
152             status = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
153             CHECK_AND_RETURN_LOG(status == napi_ok,
154                 "%{public}s failed to napi_call_function", callbackName.c_str());
155         }
156     };
157 
158     struct IntArray : public Base {
159         std::vector<int32_t> valueVec;
UvWorkOHOS::Media::NapiCallback::IntArray160         void UvWork() override
161         {
162             std::shared_ptr<AutoRef> ref = callback.lock();
163             CHECK_AND_RETURN_LOG(ref != nullptr,
164                 "%{public}s AutoRef is nullptr", callbackName.c_str());
165 
166             napi_handle_scope scope = nullptr;
167             napi_open_handle_scope(ref->env_, &scope);
168             CHECK_AND_RETURN_LOG(scope != nullptr,
169                 "%{public}s scope is nullptr", callbackName.c_str());
170             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
171 
172             napi_value jsCallback = nullptr;
173             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
174             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
175                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
176 
177             napi_value array = nullptr;
178             (void)napi_create_array_with_length(ref->env_, valueVec.size(), &array);
179 
180             for (uint32_t i = 0; i < valueVec.size(); i++) {
181                 napi_value number = nullptr;
182                 (void)napi_create_int32(ref->env_, valueVec.at(i), &number);
183                 (void)napi_set_element(ref->env_, array, i, number);
184             }
185 
186             napi_value result = nullptr;
187             napi_value args[1] = {array};
188             status = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
189             CHECK_AND_RETURN_LOG(status == napi_ok,
190                 "%{public}s failed to napi_call_function", callbackName.c_str());
191         }
192     };
193 
194     struct Double : public Base {
195         double value = 0.0;
UvWorkOHOS::Media::NapiCallback::Double196         void UvWork() override
197         {
198             std::shared_ptr<AutoRef> ref = callback.lock();
199             CHECK_AND_RETURN_LOG(ref != nullptr,
200                 "%{public}s AutoRef is nullptr", callbackName.c_str());
201 
202             napi_handle_scope scope = nullptr;
203             napi_open_handle_scope(ref->env_, &scope);
204             CHECK_AND_RETURN_LOG(scope != nullptr,
205                 "%{public}s scope is nullptr", callbackName.c_str());
206             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
207 
208             napi_value jsCallback = nullptr;
209             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
210             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
211                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
212 
213             napi_value args[1] = {nullptr};
214             (void)napi_create_double(ref->env_, value, &args[0]);
215 
216             napi_value result = nullptr;
217             status = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
218             CHECK_AND_RETURN_LOG(status == napi_ok,
219                 "%{public}s failed to napi_call_function", callbackName.c_str());
220         }
221     };
222 
223     struct SubtitleProperty : public Base {
224         std::string text;
UvWorkOHOS::Media::NapiCallback::SubtitleProperty225         void UvWork() override
226         {
227             std::shared_ptr<AutoRef> ref = callback.lock();
228             CHECK_AND_RETURN_LOG(ref != nullptr,
229                 "%{public}s AutoRef is nullptr", callbackName.c_str());
230 
231             napi_handle_scope scope = nullptr;
232             napi_open_handle_scope(ref->env_, &scope);
233             CHECK_AND_RETURN_LOG(scope != nullptr,
234                 "%{public}s scope is nullptr", callbackName.c_str());
235             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
236 
237             napi_value jsCallback = nullptr;
238             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
239             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
240                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
241 
242             // callback: (textInfo: TextInfoDescriptor)
243             napi_value args[1] = {nullptr};
244             napi_create_object(ref->env_, &args[0]);
245             (void)CommonNapi::SetPropertyString(ref->env_, args[0], "text", text);
246             napi_value result = nullptr;
247             status = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
248             CHECK_AND_RETURN_LOG(status == napi_ok,
249                 "%{public}s fail to napi_call_function", callbackName.c_str());
250         }
251     };
252 
253     struct PropertyInt : public Base {
254         std::map<std::string, int32_t> valueMap;
UvWorkOHOS::Media::NapiCallback::PropertyInt255         void UvWork() override
256         {
257             std::shared_ptr<AutoRef> ref = callback.lock();
258             CHECK_AND_RETURN_LOG(ref != nullptr,
259                 "%{public}s AutoRef is nullptr", callbackName.c_str());
260 
261             napi_handle_scope scope = nullptr;
262             napi_open_handle_scope(ref->env_, &scope);
263             CHECK_AND_RETURN_LOG(scope != nullptr,
264                 "%{public}s scope is nullptr", callbackName.c_str());
265             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
266 
267             napi_value jsCallback = nullptr;
268             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
269             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
270                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
271 
272             napi_value args[1] = {nullptr};
273             napi_create_object(ref->env_, &args[0]);
274             for (auto &it : valueMap) {
275                 CommonNapi::SetPropertyInt32(ref->env_, args[0], it.first, it.second);
276             }
277 
278             napi_value result = nullptr;
279             status = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
280             CHECK_AND_RETURN_LOG(status == napi_ok,
281                 "%{public}s fail to napi_call_function", callbackName.c_str());
282         }
283     };
284 
285     struct StateChange : public Base {
286         std::string state = "";
287         int32_t reason = 0;
UvWorkOHOS::Media::NapiCallback::StateChange288         void UvWork() override
289         {
290             std::shared_ptr<AutoRef> ref = callback.lock();
291             CHECK_AND_RETURN_LOG(ref != nullptr,
292                 "%{public}s AutoRef is nullptr", callbackName.c_str());
293 
294             napi_handle_scope scope = nullptr;
295             napi_open_handle_scope(ref->env_, &scope);
296             CHECK_AND_RETURN_LOG(scope != nullptr,
297                 "%{public}s scope is nullptr", callbackName.c_str());
298             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
299 
300             napi_value jsCallback = nullptr;
301             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
302             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
303                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
304 
305             const int32_t argCount = 2;
306             // callback: (state: AVPlayerState, reason: StateChangeReason)
307             napi_value args[argCount] = {nullptr};
308             (void)napi_create_string_utf8(ref->env_, state.c_str(), NAPI_AUTO_LENGTH, &args[0]);
309             (void)napi_create_int32(ref->env_, reason, &args[1]);
310 
311             napi_value result = nullptr;
312             status = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
313             CHECK_AND_RETURN_LOG(status == napi_ok,
314                 "%{public}s fail to napi_call_function", callbackName.c_str());
315         }
316     };
317 
CompleteCallback(napi_env env,NapiCallback::Base * jsCb)318     static void CompleteCallback(napi_env env, NapiCallback::Base *jsCb)
319     {
320         ON_SCOPE_EXIT(0) { delete jsCb; };
321 
322         uv_loop_s *loop = nullptr;
323         napi_get_uv_event_loop(env, &loop);
324         CHECK_AND_RETURN_LOG(loop != nullptr, "Fail to napi_get_uv_event_loop");
325 
326         uv_work_t *work = new(std::nothrow) uv_work_t;
327         CHECK_AND_RETURN_LOG(work != nullptr, "Fail to new uv_work_t");
328 
329         work->data = reinterpret_cast<void *>(jsCb);
330         // async callback, jsWork and jsWork->data should be heap object.
331         int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
332             CHECK_AND_RETURN_LOG(work != nullptr, "Work thread is nullptr");
333             (void)status;
334             NapiCallback::Base *cb = reinterpret_cast<NapiCallback::Base *>(work->data);
335             if (cb != nullptr) {
336                 MEDIA_LOGI("JsCallBack %{public}s, uv_queue_work_with_qos start", cb->callbackName.c_str());
337                 cb->UvWork();
338                 delete cb;
339             }
340             delete work;
341         }, uv_qos_user_initiated);
342         if (ret != 0) {
343             MEDIA_LOGE("Failed to execute libuv work queue");
344             delete jsCb;
345             delete work;
346         }
347         CANCEL_SCOPE_EXIT_GUARD(0);
348     }
349 
CompleteCallbackInOrder(NapiCallback::Base * jsCb,std::shared_ptr<AppExecFwk::EventHandler> handler)350     static void CompleteCallbackInOrder(NapiCallback::Base *jsCb, std::shared_ptr<AppExecFwk::EventHandler> handler)
351     {
352         ON_SCOPE_EXIT(0) { delete jsCb; };
353         CHECK_AND_RETURN_LOG(handler != nullptr, "handler is nullptr");
354 
355         bool ret = handler->PostTask(std::bind(&Base::JsCallback, jsCb),
356             AppExecFwk::EventQueue::Priority::IMMEDIATE);
357         CHECK_AND_RETURN_LOG(ret, "Failed to execute PostTask");
358         CANCEL_SCOPE_EXIT_GUARD(0);
359     }
360 
361     struct TrackChange : public Base {
362         int32_t number = 0;
363         bool isSelect = false;
UvWorkOHOS::Media::NapiCallback::TrackChange364         void UvWork() override
365         {
366             std::shared_ptr<AutoRef> ref = callback.lock();
367             CHECK_AND_RETURN_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
368 
369             napi_handle_scope scope = nullptr;
370             napi_open_handle_scope(ref->env_, &scope);
371             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
372             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
373 
374             napi_value jsCallback = nullptr;
375             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
376             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
377                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
378 
379             const int32_t argCount = 2; // 2 prapm, callback: (index: number, isSelect: boolean)
380             napi_value args[argCount] = {nullptr};
381             (void)napi_create_int32(ref->env_, number, &args[0]);
382             (void)napi_get_boolean(ref->env_, isSelect, &args[1]);
383 
384             napi_value result = nullptr;
385             status = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
386             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
387         }
388     };
389 
390     struct TrackInfoUpdate : public Base {
391         std::vector<Format> trackInfo;
UvWorkOHOS::Media::NapiCallback::TrackInfoUpdate392         void UvWork() override
393         {
394             std::shared_ptr<AutoRef> ref = callback.lock();
395             CHECK_AND_RETURN_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
396 
397             napi_handle_scope scope = nullptr;
398             napi_open_handle_scope(ref->env_, &scope);
399             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
400             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
401 
402             napi_value jsCallback = nullptr;
403             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
404             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
405                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
406 
407             napi_value array = nullptr;
408             (void)napi_create_array_with_length(ref->env_, trackInfo.size(), &array);
409 
410             for (uint32_t i = 0; i < trackInfo.size(); i++) {
411                 napi_value trackDescription = nullptr;
412                 trackDescription = CommonNapi::CreateFormatBuffer(ref->env_, trackInfo[i]);
413                 (void)napi_set_element(ref->env_, array, i, trackDescription);
414             }
415 
416             napi_value result = nullptr;
417             napi_value args[1] = {array};
418             status = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
419             CHECK_AND_RETURN_LOG(status == napi_ok,
420                 "%{public}s failed to napi_call_function", callbackName.c_str());
421         }
422     };
423 };
424 
AVPlayerCallback(napi_env env,AVPlayerNotify * listener)425 AVPlayerCallback::AVPlayerCallback(napi_env env, AVPlayerNotify *listener)
426     : env_(env), listener_(listener)
427 {
428     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
429     auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
430     if (runner != nullptr) {
431         handler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
432     }
433 
434     onInfoFuncs_[INFO_TYPE_STATE_CHANGE] = &AVPlayerCallback::OnStateChangeCb;
435     onInfoFuncs_[INFO_TYPE_VOLUME_CHANGE] = &AVPlayerCallback::OnVolumeChangeCb;
436     onInfoFuncs_[INFO_TYPE_SEEKDONE] = &AVPlayerCallback::OnSeekDoneCb;
437     onInfoFuncs_[INFO_TYPE_SPEEDDONE] = &AVPlayerCallback::OnSpeedDoneCb;
438     onInfoFuncs_[INFO_TYPE_BITRATEDONE] = &AVPlayerCallback::OnBitRateDoneCb;
439     onInfoFuncs_[INFO_TYPE_POSITION_UPDATE] = &AVPlayerCallback::OnPositionUpdateCb;
440     onInfoFuncs_[INFO_TYPE_DURATION_UPDATE] = &AVPlayerCallback::OnDurationUpdateCb;
441     onInfoFuncs_[INFO_TYPE_BUFFERING_UPDATE] = &AVPlayerCallback::OnBufferingUpdateCb;
442     onInfoFuncs_[INFO_TYPE_MESSAGE] = &AVPlayerCallback::OnMessageCb;
443     onInfoFuncs_[INFO_TYPE_RESOLUTION_CHANGE] = &AVPlayerCallback::OnVideoSizeChangedCb;
444     onInfoFuncs_[INFO_TYPE_INTERRUPT_EVENT] = &AVPlayerCallback::OnAudioInterruptCb;
445     onInfoFuncs_[INFO_TYPE_BITRATE_COLLECT] = &AVPlayerCallback::OnBitRateCollectedCb;
446     onInfoFuncs_[INFO_TYPE_EOS] = &AVPlayerCallback::OnEosCb;
447     onInfoFuncs_[INFO_TYPE_IS_LIVE_STREAM] = &AVPlayerCallback::NotifyIsLiveStream;
448     onInfoFuncs_[INFO_TYPE_SUBTITLE_UPDATE] = &AVPlayerCallback::OnSubtitleUpdateCb;
449     onInfoFuncs_[INFO_TYPE_TRACKCHANGE] = &AVPlayerCallback::OnTrackChangedCb;
450     onInfoFuncs_[INFO_TYPE_TRACK_INFO_UPDATE] = &AVPlayerCallback::OnTrackInfoUpdate;
451 }
452 
~AVPlayerCallback()453 AVPlayerCallback::~AVPlayerCallback()
454 {
455     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
456 }
457 
OnError(int32_t errorCode,const std::string & errorMsg)458 void AVPlayerCallback::OnError(int32_t errorCode, const std::string &errorMsg)
459 {
460     MediaServiceExtErrCodeAPI9 errorCodeApi9 = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errorCode));
461     if (errorCodeApi9 == MSERR_EXT_API9_NO_PERMISSION ||
462         errorCodeApi9 == MSERR_EXT_API9_NO_MEMORY ||
463         errorCodeApi9 == MSERR_EXT_API9_TIMEOUT ||
464         errorCodeApi9 == MSERR_EXT_API9_SERVICE_DIED ||
465         errorCodeApi9 == MSERR_EXT_API9_UNSUPPORT_FORMAT) {
466         Format infoBody;
467         AVPlayerCallback::OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_STATE_ERROR, infoBody);
468     }
469     AVPlayerCallback::OnErrorCb(errorCodeApi9, errorMsg);
470 }
471 
OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode,const std::string & errorMsg)472 void AVPlayerCallback::OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode, const std::string &errorMsg)
473 {
474     std::string message = MSExtAVErrorToString(errorCode) + errorMsg;
475     MEDIA_LOGE("OnErrorCb:errorCode %{public}d, errorMsg %{public}s", errorCode, message.c_str());
476     std::lock_guard<std::mutex> lock(mutex_);
477     if (refMap_.find(AVPlayerEvent::EVENT_ERROR) == refMap_.end()) {
478         MEDIA_LOGW("can not find error callback!");
479         return;
480     }
481 
482     NapiCallback::Error *cb = new(std::nothrow) NapiCallback::Error();
483     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Error");
484 
485     cb->callback = refMap_.at(AVPlayerEvent::EVENT_ERROR);
486     cb->callbackName = AVPlayerEvent::EVENT_ERROR;
487     cb->errorCode = errorCode;
488     cb->errorMsg = message;
489     NapiCallback::CompleteCallback(env_, cb);
490 }
491 
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)492 void AVPlayerCallback::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
493 {
494     std::lock_guard<std::mutex> lock(mutex_);
495     MEDIA_LOGI("OnInfo is called, PlayerOnInfoType: %{public}d", type);
496     if (onInfoFuncs_.count(type) > 0) {
497         (this->*onInfoFuncs_[type])(extra, infoBody);
498     } else {
499         MEDIA_LOGI("OnInfo: no member func supporting, %{public}d", type);
500     }
501 }
502 
NotifyIsLiveStream(const int32_t extra,const Format & infoBody)503 void AVPlayerCallback::NotifyIsLiveStream(const int32_t extra, const Format &infoBody)
504 {
505     (void)extra;
506     (void)infoBody;
507     if (listener_ != nullptr) {
508         listener_->NotifyIsLiveStream();
509     }
510 }
511 
OnStateChangeCb(const int32_t extra,const Format & infoBody)512 void AVPlayerCallback::OnStateChangeCb(const int32_t extra, const Format &infoBody)
513 {
514     PlayerStates state = static_cast<PlayerStates>(extra);
515     MEDIA_LOGI("OnStateChanged is called, current state: %{public}d", state);
516 
517     if (listener_ != nullptr) {
518         listener_->NotifyState(state);
519     }
520 
521     if (state_ != state) {
522         state_ = state;
523         static std::map<PlayerStates, std::string> stateMap = {
524             { PLAYER_IDLE, AVPlayerState::STATE_IDLE },
525             { PLAYER_INITIALIZED, AVPlayerState::STATE_INITIALIZED },
526             { PLAYER_PREPARED, AVPlayerState::STATE_PREPARED },
527             { PLAYER_STARTED, AVPlayerState::STATE_PLAYING },
528             { PLAYER_PAUSED, AVPlayerState::STATE_PAUSED },
529             { PLAYER_STOPPED, AVPlayerState::STATE_STOPPED },
530             { PLAYER_PLAYBACK_COMPLETE, AVPlayerState::STATE_COMPLETED },
531             { PLAYER_RELEASED, AVPlayerState::STATE_RELEASED },
532             { PLAYER_STATE_ERROR, AVPlayerState::STATE_ERROR },
533         };
534 
535         if (stateMap.find(state) != stateMap.end()) {
536             if (refMap_.find(AVPlayerEvent::EVENT_STATE_CHANGE) == refMap_.end()) {
537                 MEDIA_LOGW("can not find state change callback!");
538                 return;
539             }
540             NapiCallback::StateChange *cb = new(std::nothrow) NapiCallback::StateChange();
541             CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new StateChange");
542 
543             int32_t reason = StateChangeReason::USER;
544             if (infoBody.ContainKey(PlayerKeys::PLAYER_STATE_CHANGED_REASON)) {
545                 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_STATE_CHANGED_REASON, reason);
546             }
547             cb->callback = refMap_.at(AVPlayerEvent::EVENT_STATE_CHANGE);
548             cb->callbackName = AVPlayerEvent::EVENT_STATE_CHANGE;
549             cb->state = stateMap.at(state);
550             cb->reason = reason;
551             NapiCallback::CompleteCallback(env_, cb);
552         }
553     }
554 }
555 
OnVolumeChangeCb(const int32_t extra,const Format & infoBody)556 void AVPlayerCallback::OnVolumeChangeCb(const int32_t extra, const Format &infoBody)
557 {
558     (void)extra;
559     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
560     float volumeLevel = 0.0;
561     (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_VOLUME_LEVEL, volumeLevel);
562 
563     MEDIA_LOGI("OnVolumeChangeCb in volume=%{public}f", volumeLevel);
564     if (refMap_.find(AVPlayerEvent::EVENT_VOLUME_CHANGE) == refMap_.end()) {
565         MEDIA_LOGW("can not find vol change callback!");
566         return;
567     }
568 
569     NapiCallback::Double *cb = new(std::nothrow) NapiCallback::Double();
570     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Double");
571     cb->callback = refMap_.at(AVPlayerEvent::EVENT_VOLUME_CHANGE);
572     cb->callbackName = AVPlayerEvent::EVENT_VOLUME_CHANGE;
573     cb->value = static_cast<double>(volumeLevel);
574     NapiCallback::CompleteCallback(env_, cb);
575 }
576 
OnSeekDoneCb(const int32_t extra,const Format & infoBody)577 void AVPlayerCallback::OnSeekDoneCb(const int32_t extra, const Format &infoBody)
578 {
579     (void)infoBody;
580     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
581     int32_t currentPositon = extra;
582     MEDIA_LOGI("OnSeekDone is called, currentPositon: %{public}d", currentPositon);
583     if (refMap_.find(AVPlayerEvent::EVENT_SEEK_DONE) == refMap_.end()) {
584         MEDIA_LOGW("can not find seekdone callback!");
585         return;
586     }
587 
588     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
589     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
590 
591     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SEEK_DONE);
592     cb->callbackName = AVPlayerEvent::EVENT_SEEK_DONE;
593     cb->value = currentPositon;
594     NapiCallback::CompleteCallback(env_, cb);
595 }
596 
OnSpeedDoneCb(const int32_t extra,const Format & infoBody)597 void AVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &infoBody)
598 {
599     (void)infoBody;
600     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
601     int32_t speedMode = extra;
602     MEDIA_LOGI("OnSpeedDoneCb is called, speedMode: %{public}d", speedMode);
603     if (refMap_.find(AVPlayerEvent::EVENT_SPEED_DONE) == refMap_.end()) {
604         MEDIA_LOGW("can not find speeddone callback!");
605         return;
606     }
607 
608     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
609     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
610 
611     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SPEED_DONE);
612     cb->callbackName = AVPlayerEvent::EVENT_SPEED_DONE;
613     cb->value = speedMode;
614     NapiCallback::CompleteCallback(env_, cb);
615 }
616 
OnBitRateDoneCb(const int32_t extra,const Format & infoBody)617 void AVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody)
618 {
619     (void)infoBody;
620     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
621     int32_t bitRate = extra;
622     MEDIA_LOGI("OnBitRateDoneCb is called, bitRate: %{public}d", bitRate);
623     if (refMap_.find(AVPlayerEvent::EVENT_BITRATE_DONE) == refMap_.end()) {
624         MEDIA_LOGW("can not find bitrate callback!");
625         return;
626     }
627 
628     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
629     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
630 
631     cb->callback = refMap_.at(AVPlayerEvent::EVENT_BITRATE_DONE);
632     cb->callbackName = AVPlayerEvent::EVENT_BITRATE_DONE;
633     cb->value = bitRate;
634     NapiCallback::CompleteCallback(env_, cb);
635 }
636 
OnPositionUpdateCb(const int32_t extra,const Format & infoBody)637 void AVPlayerCallback::OnPositionUpdateCb(const int32_t extra, const Format &infoBody)
638 {
639     (void)infoBody;
640     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
641     int32_t position = extra;
642     MEDIA_LOGI("OnPositionUpdateCb is called, position: %{public}d", position);
643 
644     if (listener_ != nullptr) {
645         listener_->NotifyPosition(position);
646     }
647 
648     if (refMap_.find(AVPlayerEvent::EVENT_TIME_UPDATE) == refMap_.end()) {
649         MEDIA_LOGW("can not find timeupdate callback!");
650         return;
651     }
652 
653     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
654     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
655 
656     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TIME_UPDATE);
657     cb->callbackName = AVPlayerEvent::EVENT_TIME_UPDATE;
658     cb->value = position;
659     NapiCallback::CompleteCallback(env_, cb);
660 }
661 
OnDurationUpdateCb(const int32_t extra,const Format & infoBody)662 void AVPlayerCallback::OnDurationUpdateCb(const int32_t extra, const Format &infoBody)
663 {
664     (void)infoBody;
665     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
666     int32_t duration = extra;
667     MEDIA_LOGI("OnDurationUpdateCb is called, duration: %{public}d", duration);
668 
669     if (listener_ != nullptr) {
670         listener_->NotifyDuration(duration);
671     }
672 
673     if (refMap_.find(AVPlayerEvent::EVENT_DURATION_UPDATE) == refMap_.end()) {
674         MEDIA_LOGW("can not find duration update callback!");
675         return;
676     }
677 
678     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
679     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
680 
681     cb->callback = refMap_.at(AVPlayerEvent::EVENT_DURATION_UPDATE);
682     cb->callbackName = AVPlayerEvent::EVENT_DURATION_UPDATE;
683     cb->value = duration;
684     NapiCallback::CompleteCallback(env_, cb);
685 }
686 
OnSubtitleUpdateCb(const int32_t extra,const Format & infoBody)687 void AVPlayerCallback::OnSubtitleUpdateCb(const int32_t extra, const Format &infoBody)
688 {
689     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
690     if (refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE) == refMap_.end()) {
691         MEDIA_LOGW("can not find subtitle update callback!");
692         return;
693     }
694     NapiCallback::SubtitleProperty *cb = new(std::nothrow) NapiCallback::SubtitleProperty();
695     if (infoBody.ContainKey(PlayerKeys::SUBTITLE_TEXT)) {
696         (void)infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, cb->text);
697     }
698     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE);
699     cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE;
700     NapiCallback::CompleteCallback(env_, cb);
701 }
702 
OnBufferingUpdateCb(const int32_t extra,const Format & infoBody)703 void AVPlayerCallback::OnBufferingUpdateCb(const int32_t extra, const Format &infoBody)
704 {
705     (void)extra;
706     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
707     if (refMap_.find(AVPlayerEvent::EVENT_BUFFERING_UPDATE) == refMap_.end()) {
708         MEDIA_LOGW("can not find buffering update callback!");
709         return;
710     }
711 
712     int32_t value = 0;
713     int32_t bufferingType = -1;
714     if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_START))) {
715         bufferingType = BUFFERING_START;
716         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_START), value);
717     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_END))) {
718         bufferingType = BUFFERING_END;
719         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_END), value);
720     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT))) {
721         bufferingType = BUFFERING_PERCENT;
722         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), value);
723     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_CACHED_DURATION))) {
724         bufferingType = CACHED_DURATION;
725         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION), value);
726     } else {
727         return;
728     }
729 
730     MEDIA_LOGI("OnBufferingUpdateCb is called, buffering type: %{public}d value: %{public}d", bufferingType, value);
731     NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
732     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
733 
734     cb->callback = refMap_.at(AVPlayerEvent::EVENT_BUFFERING_UPDATE);
735     cb->callbackName = AVPlayerEvent::EVENT_BUFFERING_UPDATE;
736     cb->valueVec.push_back(bufferingType);
737     cb->valueVec.push_back(value);
738     NapiCallback::CompleteCallbackInOrder(cb, handler_);
739 }
740 
OnMessageCb(const int32_t extra,const Format & infoBody)741 void AVPlayerCallback::OnMessageCb(const int32_t extra, const Format &infoBody)
742 {
743     (void)infoBody;
744     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
745     MEDIA_LOGI("OnMessageCb is called, extra: %{public}d", extra);
746     if (extra == PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START) {
747         AVPlayerCallback::OnStartRenderFrameCb();
748     }
749 }
750 
OnStartRenderFrameCb() const751 void AVPlayerCallback::OnStartRenderFrameCb() const
752 {
753     MEDIA_LOGI("OnStartRenderFrameCb is called");
754     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
755     if (refMap_.find(AVPlayerEvent::EVENT_START_RENDER_FRAME) == refMap_.end()) {
756         MEDIA_LOGW("can not find start render callback!");
757         return;
758     }
759 
760     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
761     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
762 
763     cb->callback = refMap_.at(AVPlayerEvent::EVENT_START_RENDER_FRAME);
764     cb->callbackName = AVPlayerEvent::EVENT_START_RENDER_FRAME;
765     NapiCallback::CompleteCallback(env_, cb);
766 }
767 
OnVideoSizeChangedCb(const int32_t extra,const Format & infoBody)768 void AVPlayerCallback::OnVideoSizeChangedCb(const int32_t extra, const Format &infoBody)
769 {
770     (void)extra;
771     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
772     int32_t width = 0;
773     int32_t height = 0;
774     (void)infoBody.GetIntValue(PlayerKeys::PLAYER_WIDTH, width);
775     (void)infoBody.GetIntValue(PlayerKeys::PLAYER_HEIGHT, height);
776     MEDIA_LOGI("OnVideoSizeChangedCb is called, width = %{public}d, height = %{public}d", width, height);
777 
778     if (listener_ != nullptr) {
779         listener_->NotifyVideoSize(width, height);
780     }
781 
782     if (refMap_.find(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE) == refMap_.end()) {
783         MEDIA_LOGW("can not find video size changed callback!");
784         return;
785     }
786     NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
787     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
788 
789     cb->callback = refMap_.at(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE);
790     cb->callbackName = AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE;
791     cb->valueVec.push_back(width);
792     cb->valueVec.push_back(height);
793     NapiCallback::CompleteCallback(env_, cb);
794 }
795 
OnAudioInterruptCb(const int32_t extra,const Format & infoBody)796 void AVPlayerCallback::OnAudioInterruptCb(const int32_t extra, const Format &infoBody)
797 {
798     (void)extra;
799     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
800     if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_INTERRUPT) == refMap_.end()) {
801         MEDIA_LOGW("can not find audio interrupt callback!");
802         return;
803     }
804 
805     NapiCallback::PropertyInt *cb = new(std::nothrow) NapiCallback::PropertyInt();
806     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new PropertyInt");
807 
808     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_INTERRUPT);
809     cb->callbackName = AVPlayerEvent::EVENT_AUDIO_INTERRUPT;
810     int32_t eventType = 0;
811     int32_t forceType = 0;
812     int32_t hintType = 0;
813     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventType);
814     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceType);
815     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintType);
816     MEDIA_LOGI("OnAudioInterruptCb is called, eventType = %{public}d, forceType = %{public}d, hintType = %{public}d",
817         eventType, forceType, hintType);
818     // ohos.multimedia.audio.d.ts interface InterruptEvent
819     cb->valueMap["eventType"] = eventType;
820     cb->valueMap["forceType"] = forceType;
821     cb->valueMap["hintType"] = hintType;
822     NapiCallback::CompleteCallback(env_, cb);
823 }
824 
OnBitRateCollectedCb(const int32_t extra,const Format & infoBody)825 void AVPlayerCallback::OnBitRateCollectedCb(const int32_t extra, const Format &infoBody)
826 {
827     (void)extra;
828     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
829     if (refMap_.find(AVPlayerEvent::EVENT_AVAILABLE_BITRATES) == refMap_.end()) {
830         MEDIA_LOGW("can not find bitrate collected callback!");
831         return;
832     }
833 
834     std::vector<int32_t> bitrateVec;
835     if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BITRATE))) {
836         uint8_t *addr = nullptr;
837         size_t size  = 0;
838         infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_BITRATE), &addr, size);
839         CHECK_AND_RETURN_LOG(addr != nullptr, "bitrate addr is nullptr");
840 
841         MEDIA_LOGI("bitrate size = %{public}zu", size / sizeof(uint32_t));
842         while (size > 0) {
843             if (size < sizeof(uint32_t)) {
844                 break;
845             }
846 
847             uint32_t bitrate = *(static_cast<uint32_t *>(static_cast<void *>(addr)));
848             MEDIA_LOGI("bitrate = %{public}u", bitrate);
849             addr += sizeof(uint32_t);
850             size -= sizeof(uint32_t);
851             bitrateVec.push_back(static_cast<int32_t>(bitrate));
852         }
853     }
854 
855     NapiCallback::IntArray *cb = new(std::nothrow) NapiCallback::IntArray();
856     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
857 
858     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AVAILABLE_BITRATES);
859     cb->callbackName = AVPlayerEvent::EVENT_AVAILABLE_BITRATES;
860     cb->valueVec = bitrateVec;
861     NapiCallback::CompleteCallback(env_, cb);
862 }
863 
OnEosCb(const int32_t extra,const Format & infoBody)864 void AVPlayerCallback::OnEosCb(const int32_t extra, const Format &infoBody)
865 {
866     (void)infoBody;
867     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
868     int32_t isLooping = extra;
869     MEDIA_LOGI("OnEndOfStream is called, isloop: %{public}d", isLooping);
870     if (refMap_.find(AVPlayerEvent::EVENT_END_OF_STREAM) == refMap_.end()) {
871         MEDIA_LOGW("can not find EndOfStream callback!");
872         return;
873     }
874 
875     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
876     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
877 
878     cb->callback = refMap_.at(AVPlayerEvent::EVENT_END_OF_STREAM);
879     cb->callbackName = AVPlayerEvent::EVENT_END_OF_STREAM;
880     NapiCallback::CompleteCallback(env_, cb);
881 }
882 
OnTrackChangedCb(const int32_t extra,const Format & infoBody)883 void AVPlayerCallback::OnTrackChangedCb(const int32_t extra, const Format &infoBody)
884 {
885     (void)extra;
886     int32_t index = -1;
887     int32_t isSelect = -1;
888     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_TRACK_INDEX), index);
889     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_IS_SELECT), isSelect);
890     MEDIA_LOGI("OnTrackChangedCb index %{public}d, isSelect = %{public}d", index, isSelect);
891 
892     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACKCHANGE) != refMap_.end(),
893         "can not find trackChange callback!");
894 
895     NapiCallback::TrackChange *cb = new(std::nothrow) NapiCallback::TrackChange();
896     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackChange");
897 
898     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACKCHANGE);
899     cb->callbackName = AVPlayerEvent::EVENT_TRACKCHANGE;
900     cb->number = index;
901     cb->isSelect = isSelect ? true : false;
902     NapiCallback::CompleteCallback(env_, cb);
903 }
904 
OnTrackInfoUpdate(const int32_t extra,const Format & infoBody)905 void AVPlayerCallback::OnTrackInfoUpdate(const int32_t extra, const Format &infoBody)
906 {
907     (void)extra;
908     std::vector<Format> trackInfo;
909     (void)infoBody.GetFormatVector(std::string(PlayerKeys::PLAYER_TRACK_INFO), trackInfo);
910     MEDIA_LOGI("OnTrackInfoUpdate callback");
911 
912     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE) != refMap_.end(),
913         "can not find trackInfoUpdate callback!");
914 
915     NapiCallback::TrackInfoUpdate *cb = new(std::nothrow) NapiCallback::TrackInfoUpdate();
916     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackInfoUpdate");
917 
918     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE);
919     cb->callbackName = AVPlayerEvent::EVENT_TRACK_INFO_UPDATE;
920     cb->trackInfo = trackInfo;
921     NapiCallback::CompleteCallback(env_, cb);
922 }
923 
SaveCallbackReference(const std::string & name,std::weak_ptr<AutoRef> ref)924 void AVPlayerCallback::SaveCallbackReference(const std::string &name, std::weak_ptr<AutoRef> ref)
925 {
926     std::lock_guard<std::mutex> lock(mutex_);
927     refMap_[name] = ref;
928 }
929 
ClearCallbackReference()930 void AVPlayerCallback::ClearCallbackReference()
931 {
932     std::lock_guard<std::mutex> lock(mutex_);
933     refMap_.clear();
934 }
935 
ClearCallbackReference(const std::string & name)936 void AVPlayerCallback::ClearCallbackReference(const std::string &name)
937 {
938     std::lock_guard<std::mutex> lock(mutex_);
939     refMap_.erase(name);
940 }
941 
Start()942 void AVPlayerCallback::Start()
943 {
944     isloaded_ = true;
945 }
946 
Pause()947 void AVPlayerCallback::Pause()
948 {
949     isloaded_ = false;
950 }
951 
Release()952 void AVPlayerCallback::Release()
953 {
954     std::lock_guard<std::mutex> lock(mutex_);
955 
956     Format infoBody;
957     AVPlayerCallback::OnStateChangeCb(PlayerStates::PLAYER_RELEASED, infoBody);
958     listener_ = nullptr;
959 }
960 } // namespace Media
961 } // namespace OHOS