• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2025 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 <map>
17 #include <iostream>
18 #include <sstream>
19 #include <iomanip>
20 #include <uv.h>
21 #include "avplayer_napi.h"
22 #include "media_errors.h"
23 #include "media_log.h"
24 #include "player.h"
25 #include "scope_guard.h"
26 #include "event_queue.h"
27 #include "avplayer_callback.h"
28 
29 
30 namespace {
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_PLAYER, "AVPlayerCallback" };
32 constexpr int32_t ARGS_TWO = 2;
33 }
34 
35 namespace OHOS {
36 namespace Media {
37 class NapiCallback {
38 public:
39     struct Base {
40         std::weak_ptr<AutoRef> callback;
41         std::string callbackName = "unknown";
42         Base() = default;
43         virtual ~Base() = default;
UvWorkOHOS::Media::NapiCallback::Base44         virtual void UvWork()
45         {
46             std::shared_ptr<AutoRef> ref = callback.lock();
47             CHECK_AND_RETURN_LOG(ref != nullptr,
48                 "%{public}s AutoRef is nullptr", callbackName.c_str());
49 
50             napi_handle_scope scope = nullptr;
51             napi_open_handle_scope(ref->env_, &scope);
52             CHECK_AND_RETURN_LOG(scope != nullptr,
53                 "%{public}s scope is nullptr", callbackName.c_str());
54             ON_SCOPE_EXIT(0) {
55                 napi_close_handle_scope(ref->env_, scope);
56             };
57 
58             napi_value jsCallback = nullptr;
59             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
60             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
61                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
62 
63             // Call back function
64             napi_value result = nullptr;
65             status = napi_call_function(ref->env_, nullptr, jsCallback, 0, nullptr, &result);
66             CHECK_AND_RETURN_LOG(status == napi_ok,
67                 "%{public}s failed to napi_call_function", callbackName.c_str());
68         }
JsCallbackOHOS::Media::NapiCallback::Base69         virtual void JsCallback()
70         {
71             UvWork();
72             delete this;
73         }
74     };
75 
76     struct Error : public Base {
77         std::string errorMsg = "unknown";
78         MediaServiceExtErrCodeAPI9 errorCode = MSERR_EXT_API9_UNSUPPORT_FORMAT;
UvWorkOHOS::Media::NapiCallback::Error79         void UvWork() override
80         {
81             std::shared_ptr<AutoRef> errorRef = callback.lock();
82             CHECK_AND_RETURN_LOG(errorRef != nullptr,
83                 "%{public}s AutoRef is nullptr", callbackName.c_str());
84 
85             napi_handle_scope scope = nullptr;
86             napi_open_handle_scope(errorRef->env_, &scope);
87             CHECK_AND_RETURN_LOG(scope != nullptr,
88                 "%{public}s scope is nullptr", callbackName.c_str());
89             ON_SCOPE_EXIT(0) {
90                 napi_close_handle_scope(errorRef->env_, scope);
91             };
92 
93             napi_value jsCallback = nullptr;
94             napi_status napiStatus = napi_get_reference_value(errorRef->env_, errorRef->cb_, &jsCallback);
95             CHECK_AND_RETURN_LOG(napiStatus == napi_ok && jsCallback != nullptr,
96                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
97 
98             napi_value args[1] = {nullptr};
99             (void)CommonNapi::CreateError(errorRef->env_, errorCode, errorMsg, args[0]);
100 
101             // Call back function
102             napi_value result = nullptr;
103             napiStatus = napi_call_function(errorRef->env_, nullptr, jsCallback, 1, args, &result);
104             CHECK_AND_RETURN_LOG(napiStatus == napi_ok,
105                 "%{public}s failed to napi_call_function", callbackName.c_str());
106         }
107     };
108 
109     struct Int : public Base {
110         int32_t value = 0;
UvWorkOHOS::Media::NapiCallback::Int111         void UvWork() override
112         {
113             std::shared_ptr<AutoRef> intRef = callback.lock();
114             CHECK_AND_RETURN_LOG(intRef != nullptr,
115                 "%{public}s AutoRef is nullptr", callbackName.c_str());
116 
117             napi_handle_scope scope = nullptr;
118             napi_open_handle_scope(intRef->env_, &scope);
119             CHECK_AND_RETURN_LOG(scope != nullptr,
120                 "%{public}s scope is nullptr", callbackName.c_str());
121             ON_SCOPE_EXIT(0) {
122                 napi_close_handle_scope(intRef->env_, scope);
123             };
124 
125             napi_value jsCallback = nullptr;
126             napi_status status = napi_get_reference_value(intRef->env_, intRef->cb_, &jsCallback);
127             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
128                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
129 
130             napi_value args[1] = {nullptr}; // callback: (int)
131             (void)napi_create_int32(intRef->env_, value, &args[0]);
132 
133             napi_value result = nullptr;
134             status = napi_call_function(intRef->env_, nullptr, jsCallback, 1, args, &result);
135             CHECK_AND_RETURN_LOG(status == napi_ok,
136                 "%{public}s failed to napi_call_function", callbackName.c_str());
137         }
138     };
139 
140     struct IntVec : public Base {
141         std::vector<int32_t> valueVec;
UvWorkOHOS::Media::NapiCallback::IntVec142         void UvWork() override
143         {
144             std::shared_ptr<AutoRef> intVecRef = callback.lock();
145             CHECK_AND_RETURN_LOG(intVecRef != nullptr,
146                 "%{public}s AutoRef is nullptr", callbackName.c_str());
147 
148             napi_handle_scope scope = nullptr;
149             napi_open_handle_scope(intVecRef->env_, &scope);
150             CHECK_AND_RETURN_LOG(scope != nullptr,
151                 "%{public}s scope is nullptr", callbackName.c_str());
152             ON_SCOPE_EXIT(0) {
153                 napi_close_handle_scope(intVecRef->env_, scope);
154             };
155 
156             napi_value jsCallback = nullptr;
157             napi_status status = napi_get_reference_value(intVecRef->env_, intVecRef->cb_, &jsCallback);
158             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
159                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
160 
161             napi_value args[2] = {nullptr}; // callback: (int, int)
162             (void)napi_create_int32(intVecRef->env_, valueVec[0], &args[0]);
163             (void)napi_create_int32(intVecRef->env_, valueVec[1], &args[1]);
164 
165             const int32_t argCount = static_cast<int32_t>(valueVec.size());
166             napi_value result = nullptr;
167             status = napi_call_function(intVecRef->env_, nullptr, jsCallback, argCount, args, &result);
168             CHECK_AND_RETURN_LOG(status == napi_ok,
169                 "%{public}s failed to napi_call_function", callbackName.c_str());
170         }
171     };
172 
173     struct IntArray : public Base {
174         std::vector<int32_t> valueVec;
UvWorkOHOS::Media::NapiCallback::IntArray175         void UvWork() override
176         {
177             std::shared_ptr<AutoRef> intArrayRef = callback.lock();
178             CHECK_AND_RETURN_LOG(intArrayRef != nullptr,
179                 "%{public}s AutoRef is nullptr", callbackName.c_str());
180 
181             napi_handle_scope scope = nullptr;
182             napi_open_handle_scope(intArrayRef->env_, &scope);
183             CHECK_AND_RETURN_LOG(scope != nullptr,
184                 "%{public}s scope is nullptr", callbackName.c_str());
185             ON_SCOPE_EXIT(0) {
186                 napi_close_handle_scope(intArrayRef->env_, scope);
187             };
188 
189             napi_value jsCallback = nullptr;
190             napi_status status = napi_get_reference_value(intArrayRef->env_, intArrayRef->cb_, &jsCallback);
191             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
192                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
193 
194             napi_value array = nullptr;
195             (void)napi_create_array_with_length(intArrayRef->env_, valueVec.size(), &array);
196 
197             for (uint32_t i = 0; i < valueVec.size(); i++) {
198                 napi_value number = nullptr;
199                 (void)napi_create_int32(intArrayRef->env_, valueVec.at(i), &number);
200                 (void)napi_set_element(intArrayRef->env_, array, i, number);
201             }
202 
203             napi_value result = nullptr;
204             napi_value args[1] = {array};
205             status = napi_call_function(intArrayRef->env_, nullptr, jsCallback, 1, args, &result);
206             CHECK_AND_RETURN_LOG(status == napi_ok,
207                 "%{public}s failed to napi_call_function", callbackName.c_str());
208         }
209     };
210 
211     struct Double : public Base {
212         double value = 0.0;
UvWorkOHOS::Media::NapiCallback::Double213         void UvWork() override
214         {
215             std::shared_ptr<AutoRef> doubleRef = callback.lock();
216             CHECK_AND_RETURN_LOG(doubleRef != nullptr,
217                 "%{public}s AutoRef is nullptr", callbackName.c_str());
218 
219             napi_handle_scope scope = nullptr;
220             napi_open_handle_scope(doubleRef->env_, &scope);
221             CHECK_AND_RETURN_LOG(scope != nullptr,
222                 "%{public}s scope is nullptr", callbackName.c_str());
223             ON_SCOPE_EXIT(0) {
224                 napi_close_handle_scope(doubleRef->env_, scope);
225             };
226 
227             napi_value jsCallback = nullptr;
228             napi_status status = napi_get_reference_value(doubleRef->env_, doubleRef->cb_, &jsCallback);
229             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
230                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
231 
232             napi_value args[1] = {nullptr};
233             (void)napi_create_double(doubleRef->env_, value, &args[0]);
234 
235             napi_value result = nullptr;
236             status = napi_call_function(doubleRef->env_, nullptr, jsCallback, 1, args, &result);
237             CHECK_AND_RETURN_LOG(status == napi_ok,
238                 "%{public}s failed to napi_call_function", callbackName.c_str());
239         }
240     };
241 
242     struct FloatArray : public Base {
243         std::vector<float>valueVec;
UvWorkOHOS::Media::NapiCallback::FloatArray244         void UvWork() override
245         {
246             std::shared_ptr<AutoRef> floatArrayRef = callback.lock();
247             CHECK_AND_RETURN_LOG(floatArrayRef != nullptr,
248                 "%{public}s AutoRef is nullptr", callbackName.c_str());
249 
250             napi_handle_scope scope = nullptr;
251             napi_open_handle_scope(floatArrayRef->env_, &scope);
252             CHECK_AND_RETURN_LOG(scope != nullptr,
253                 "%{public}s scope is nullptr", callbackName.c_str());
254             ON_SCOPE_EXIT(0) {
255                 napi_close_handle_scope(floatArrayRef->env_, scope);
256             };
257 
258             napi_value jsCallback = nullptr;
259             napi_status status = napi_get_reference_value(floatArrayRef->env_, floatArrayRef->cb_, &jsCallback);
260             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
261                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
262 
263             napi_value array = nullptr;
264             (void)napi_create_array_with_length(floatArrayRef->env_, valueVec.size(), &array);
265 
266             for (uint32_t i = 0; i < valueVec.size(); i++) {
267                 napi_value number = nullptr;
268                 (void)napi_create_double(floatArrayRef->env_, valueVec.at(i), &number);
269                 (void)napi_set_element(floatArrayRef->env_, array, i, number);
270             }
271 
272             napi_value result = nullptr;
273             napi_value args[1] = {array};
274             status = napi_call_function(floatArrayRef->env_, nullptr, jsCallback, 1, args, &result);
275             CHECK_AND_RETURN_LOG(status == napi_ok,
276                 "%{public}s failed to napi_call_function", callbackName.c_str());
277         }
278     };
279 
280     struct Bool : public Base {
281         bool value = false;
UvWorkOHOS::Media::NapiCallback::Bool282         void UvWork() override
283         {
284             std::shared_ptr<AutoRef> boolRef = callback.lock();
285             CHECK_AND_RETURN_LOG(boolRef != nullptr,
286                 "%{public}s AutoRef is nullptr", callbackName.c_str());
287 
288             napi_handle_scope scope = nullptr;
289             napi_open_handle_scope(boolRef->env_, &scope);
290             CHECK_AND_RETURN_LOG(scope != nullptr,
291                 "%{public}s scope is nullptr", callbackName.c_str());
292             ON_SCOPE_EXIT(0) {
293                 napi_close_handle_scope(boolRef->env_, scope);
294             };
295 
296             napi_value jsCallback = nullptr;
297             napi_status status = napi_get_reference_value(boolRef->env_, boolRef->cb_, &jsCallback);
298             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
299                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
300 
301             napi_value args[1] = {nullptr}; // callback: (boolean)
302             (void)napi_get_boolean(boolRef->env_, value, &args[0]);
303 
304             napi_value result = nullptr;
305             status = napi_call_function(boolRef->env_, nullptr, jsCallback, 1, args, &result);
306             CHECK_AND_RETURN_LOG(status == napi_ok,
307                 "%{public}s failed to napi_call_function", callbackName.c_str());
308         }
309     };
310 
311     struct SubtitleProperty : public Base {
312         std::string text;
UvWorkOHOS::Media::NapiCallback::SubtitleProperty313         void UvWork() override
314         {
315             std::shared_ptr<AutoRef> subtitleRef = callback.lock();
316             CHECK_AND_RETURN_LOG(subtitleRef != nullptr,
317                 "%{public}s AutoRef is nullptr", callbackName.c_str());
318 
319             napi_handle_scope scope = nullptr;
320             napi_open_handle_scope(subtitleRef->env_, &scope);
321             CHECK_AND_RETURN_LOG(scope != nullptr,
322                 "%{public}s scope is nullptr", callbackName.c_str());
323             ON_SCOPE_EXIT(0) {
324                 napi_close_handle_scope(subtitleRef->env_, scope);
325             };
326 
327             napi_value jsCallback = nullptr;
328             napi_status status = napi_get_reference_value(subtitleRef->env_, subtitleRef->cb_, &jsCallback);
329             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
330                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
331 
332             // callback: (textInfo: TextInfoDescriptor)
333             napi_value args[1] = {nullptr};
334             napi_create_object(subtitleRef->env_, &args[0]);
335             (void)CommonNapi::SetPropertyString(subtitleRef->env_, args[0], "text", text);
336             napi_value result = nullptr;
337             status = napi_call_function(subtitleRef->env_, nullptr, jsCallback, 1, args, &result);
338             CHECK_AND_RETURN_LOG(status == napi_ok,
339                 "%{public}s fail to napi_call_function", callbackName.c_str());
340         }
341     };
342 
343     struct ObjectArray : public Base {
344         std::multimap<std::string, std::vector<uint8_t>> infoMap;
UvWorkOHOS::Media::NapiCallback::ObjectArray345         void UvWork() override
346         {
347             std::shared_ptr<AutoRef> mapRef = callback.lock();
348             CHECK_AND_RETURN_LOG(mapRef != nullptr,
349                 "%{public}s AutoRef is nullptr", callbackName.c_str());
350 
351             napi_handle_scope scope = nullptr;
352             napi_open_handle_scope(mapRef->env_, &scope);
353             CHECK_AND_RETURN_LOG(scope != nullptr,
354                 "%{public}s scope is nullptr", callbackName.c_str());
355             ON_SCOPE_EXIT(0) {
356                 napi_close_handle_scope(mapRef->env_, scope);
357             };
358 
359             napi_value jsCallback = nullptr;
360             napi_status status = napi_get_reference_value(mapRef->env_, mapRef->cb_, &jsCallback);
361             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
362                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
363 
364             uint32_t index = 0;
365             napi_value napiMap;
366             napi_create_array_with_length(mapRef->env_, infoMap.size(), &napiMap);
367             for (auto item : infoMap) {
368                 napi_value jsObject;
369                 napi_value jsUuid;
370                 napi_value jsPssh;
371                 napi_create_object(mapRef->env_, &jsObject);
372                 napi_create_string_utf8(mapRef->env_, item.first.c_str(), NAPI_AUTO_LENGTH, &jsUuid);
373                 napi_set_named_property(mapRef->env_, jsObject, "uuid", jsUuid);
374 
375                 status = napi_create_array_with_length(mapRef->env_, item.second.size(), &jsPssh);
376                 for (uint32_t i = 0; i < item.second.size(); i++) {
377                     napi_value number = nullptr;
378                     (void)napi_create_uint32(mapRef->env_, item.second[i], &number);
379                     (void)napi_set_element(mapRef->env_, jsPssh, i, number);
380                 }
381                 napi_set_named_property(mapRef->env_, jsObject, "pssh", jsPssh);
382                 napi_set_element(mapRef->env_, napiMap, index, jsObject);
383                 index++;
384             }
385 
386             const int32_t argCount = 1;
387             napi_value args[argCount] = { napiMap };
388             napi_value result = nullptr;
389             status = napi_call_function(mapRef->env_, nullptr, jsCallback, argCount, args, &result);
390             CHECK_AND_RETURN_LOG(status == napi_ok,
391                 "%{public}s failed to napi_call_function", callbackName.c_str());
392         }
393     };
394 
395     struct PropertyInt : public Base {
396         std::map<std::string, int32_t> valueMap;
UvWorkOHOS::Media::NapiCallback::PropertyInt397         void UvWork() override
398         {
399             std::shared_ptr<AutoRef> propertyIntRef = callback.lock();
400             CHECK_AND_RETURN_LOG(propertyIntRef != nullptr,
401                 "%{public}s AutoRef is nullptr", callbackName.c_str());
402 
403             napi_handle_scope scope = nullptr;
404             napi_open_handle_scope(propertyIntRef->env_, &scope);
405             CHECK_AND_RETURN_LOG(scope != nullptr,
406                 "%{public}s scope is nullptr", callbackName.c_str());
407             ON_SCOPE_EXIT(0) {
408                 napi_close_handle_scope(propertyIntRef->env_, scope);
409             };
410 
411             napi_value jsCallback = nullptr;
412             napi_status status = napi_get_reference_value(propertyIntRef->env_, propertyIntRef->cb_, &jsCallback);
413             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
414                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
415 
416             napi_value args[1] = {nullptr};
417             napi_create_object(propertyIntRef->env_, &args[0]);
418             for (auto &it : valueMap) {
419                 CommonNapi::SetPropertyInt32(propertyIntRef->env_, args[0], it.first, it.second);
420             }
421 
422             napi_value result = nullptr;
423             status = napi_call_function(propertyIntRef->env_, nullptr, jsCallback, 1, args, &result);
424             CHECK_AND_RETURN_LOG(status == napi_ok,
425                 "%{public}s fail to napi_call_function", callbackName.c_str());
426         }
427     };
428 
429     struct StateChange : public Base {
430         std::string state = "";
431         int32_t reason = 0;
UvWorkOHOS::Media::NapiCallback::StateChange432         void UvWork() override
433         {
434             std::shared_ptr<AutoRef> stateChangeRef = callback.lock();
435             CHECK_AND_RETURN_LOG(stateChangeRef != nullptr,
436                 "%{public}s AutoRef is nullptr", callbackName.c_str());
437 
438             napi_handle_scope scope = nullptr;
439             napi_open_handle_scope(stateChangeRef->env_, &scope);
440             CHECK_AND_RETURN_LOG(scope != nullptr,
441                 "%{public}s scope is nullptr", callbackName.c_str());
442             ON_SCOPE_EXIT(0) {
443                 napi_close_handle_scope(stateChangeRef->env_, scope);
444             };
445 
446             napi_value jsCallback = nullptr;
447             napi_status status = napi_get_reference_value(stateChangeRef->env_, stateChangeRef->cb_, &jsCallback);
448             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
449                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
450 
451             const int32_t argCount = 2;
452             // callback: (state: AVPlayerState, reason: StateChangeReason)
453             napi_value args[argCount] = {nullptr};
454             (void)napi_create_string_utf8(stateChangeRef->env_, state.c_str(), NAPI_AUTO_LENGTH, &args[0]);
455             (void)napi_create_int32(stateChangeRef->env_, reason, &args[1]);
456 
457             napi_value result = nullptr;
458             status = napi_call_function(stateChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
459             CHECK_AND_RETURN_LOG(status == napi_ok,
460                 "%{public}s fail to napi_call_function", callbackName.c_str());
461         }
462     };
463 
CompleteCallback(napi_env env,NapiCallback::Base * jsCb)464     static void CompleteCallback(napi_env env, NapiCallback::Base *jsCb)
465     {
466         CHECK_AND_RETURN_LOG(jsCb != nullptr, "jsCb is nullptr");
467         napi_status ret = napi_send_event(env, [jsCb] () {
468             CHECK_AND_RETURN_LOG(jsCb != nullptr, "Work thread is nullptr");
469             MEDIA_LOGD("JsCallBack %{public}s start", jsCb->callbackName.c_str());
470             jsCb->UvWork();
471             delete jsCb;
472         }, napi_eprio_immediate);
473         if (ret != napi_ok) {
474             MEDIA_LOGE("Failed to execute libuv work queue, ret = %{public}d", ret);
475             delete jsCb;
476         }
477     }
478 
479     struct TrackChange : public Base {
480         int32_t number = 0;
481         bool isSelect = false;
UvWorkOHOS::Media::NapiCallback::TrackChange482         void UvWork() override
483         {
484             std::shared_ptr<AutoRef> trackChangeRef = callback.lock();
485             CHECK_AND_RETURN_LOG(trackChangeRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
486 
487             napi_handle_scope scope = nullptr;
488             napi_open_handle_scope(trackChangeRef->env_, &scope);
489             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
490             ON_SCOPE_EXIT(0) {
491                 napi_close_handle_scope(trackChangeRef->env_, scope);
492             };
493 
494             napi_value jsCallback = nullptr;
495             napi_status status = napi_get_reference_value(trackChangeRef->env_, trackChangeRef->cb_, &jsCallback);
496             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
497                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
498 
499             const int32_t argCount = 2; // 2 prapm, callback: (index: number, isSelect: boolean)
500             napi_value args[argCount] = {nullptr};
501             (void)napi_create_int32(trackChangeRef->env_, number, &args[0]);
502             (void)napi_get_boolean(trackChangeRef->env_, isSelect, &args[1]);
503 
504             napi_value result = nullptr;
505             status = napi_call_function(trackChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
506             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
507         }
508     };
509 
510     struct SubtitleInfo : public Base {
511         struct SubtitleParam {
512             std::string text;
513             int32_t pts;
514             int32_t duration;
515         } valueMap;
UvWorkOHOS::Media::NapiCallback::SubtitleInfo516         void UvWork() override
517         {
518             std::shared_ptr<AutoRef> subtitleRef = callback.lock();
519             CHECK_AND_RETURN_LOG(subtitleRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
520 
521             napi_handle_scope scope = nullptr;
522             napi_open_handle_scope(subtitleRef->env_, &scope);
523             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
524             ON_SCOPE_EXIT(0) {
525                 napi_close_handle_scope(subtitleRef->env_, scope);
526             };
527 
528             napi_value jsCallback = nullptr;
529             napi_status status = napi_get_reference_value(subtitleRef->env_, subtitleRef->cb_, &jsCallback);
530             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
531                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
532 
533             napi_value args[1] = {nullptr};
534             napi_create_object(subtitleRef->env_, &args[0]);
535             CommonNapi::SetPropertyString(subtitleRef->env_, args[0], "text", valueMap.text);
536             CommonNapi::SetPropertyInt32(subtitleRef->env_, args[0], "startTime", valueMap.pts);
537             CommonNapi::SetPropertyInt32(subtitleRef->env_, args[0], "duration", valueMap.duration);
538             napi_value result = nullptr;
539             status = napi_call_function(subtitleRef->env_, nullptr, jsCallback, 1, args, &result);
540             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
541         }
542     };
543 
544     struct DeviceChangeNapi : public Base {
545         AudioStandard::AudioDeviceDescriptor deviceInfo =
546             AudioStandard::AudioDeviceDescriptor(AudioStandard::AudioDeviceDescriptor::DEVICE_INFO);
547         int32_t reason;
UvWorkOHOS::Media::NapiCallback::DeviceChangeNapi548         void UvWork() override
549         {
550             std::shared_ptr<AutoRef> deviceChangeRef = callback.lock();
551             CHECK_AND_RETURN_LOG(deviceChangeRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
552 
553             napi_handle_scope scope = nullptr;
554             napi_open_handle_scope(deviceChangeRef->env_, &scope);
555             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
556             ON_SCOPE_EXIT(0) {
557                 napi_close_handle_scope(deviceChangeRef->env_, scope);
558             };
559 
560             napi_value jsCallback = nullptr;
561             napi_status status = napi_get_reference_value(deviceChangeRef->env_, deviceChangeRef->cb_, &jsCallback);
562             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
563                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
564 
565             constexpr size_t argCount = 1;
566             napi_value args[argCount] = {};
567             napi_create_object(deviceChangeRef->env_, &args[0]);
568             napi_value deviceObj = nullptr;
569             status = CommonNapi::SetValueDeviceInfo(deviceChangeRef->env_, deviceInfo, deviceObj);
570             CHECK_AND_RETURN_LOG(status == napi_ok && deviceObj != nullptr,
571                 " fail to convert to jsobj");
572             napi_set_named_property(deviceChangeRef->env_, args[0], "devices", deviceObj);
573 
574             bool res = CommonNapi::SetPropertyInt32(deviceChangeRef->env_, args[0], "changeReason",
575                 static_cast<const int32_t> (reason));
576             CHECK_AND_RETURN_LOG(res && deviceObj != nullptr,
577                 " fail to convert to jsobj");
578 
579             napi_value result = nullptr;
580             status = napi_call_function(deviceChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
581             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
582         }
583     };
584 
585     struct TrackInfoUpdate : public Base {
586         std::vector<Format> trackInfo;
UvWorkOHOS::Media::NapiCallback::TrackInfoUpdate587         void UvWork() override
588         {
589             std::shared_ptr<AutoRef> trackInfoRef = callback.lock();
590             CHECK_AND_RETURN_LOG(trackInfoRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
591 
592             napi_handle_scope scope = nullptr;
593             napi_open_handle_scope(trackInfoRef->env_, &scope);
594             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
595             ON_SCOPE_EXIT(0) {
596                 napi_close_handle_scope(trackInfoRef->env_, scope);
597             };
598 
599             napi_value jsCallback = nullptr;
600             napi_status status = napi_get_reference_value(trackInfoRef->env_, trackInfoRef->cb_, &jsCallback);
601             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
602                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
603 
604             napi_value array = nullptr;
605             (void)napi_create_array_with_length(trackInfoRef->env_, trackInfo.size(), &array);
606 
607             for (uint32_t i = 0; i < trackInfo.size(); i++) {
608                 napi_value trackDescription = nullptr;
609                 trackDescription = CommonNapi::CreateFormatBuffer(trackInfoRef->env_, trackInfo[i]);
610                 (void)napi_set_element(trackInfoRef->env_, array, i, trackDescription);
611             }
612 
613             napi_value result = nullptr;
614             napi_value args[1] = {array};
615             status = napi_call_function(trackInfoRef->env_, nullptr, jsCallback, 1, args, &result);
616             CHECK_AND_RETURN_LOG(status == napi_ok,
617                 "%{public}s failed to napi_call_function", callbackName.c_str());
618         }
619     };
620 
621     struct SeiInfoUpadte : public Base {
622         int32_t playbackPosition;
623         std::vector<Format> payloadGroup;
624 
UvWorkOHOS::Media::NapiCallback::SeiInfoUpadte625         void UvWork() override
626         {
627             std::shared_ptr<AutoRef> seiInfoRef = callback.lock();
628             CHECK_AND_RETURN_LOG(seiInfoRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
629 
630             napi_handle_scope scope = nullptr;
631             napi_open_handle_scope(seiInfoRef->env_, &scope);
632             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
633             ON_SCOPE_EXIT(0) {
634                 napi_close_handle_scope(seiInfoRef->env_, scope);
635             };
636 
637             napi_value jsCallback = nullptr;
638             napi_status status = napi_get_reference_value(seiInfoRef->env_, seiInfoRef->cb_, &jsCallback);
639             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
640                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
641 
642             napi_value position = nullptr;
643             status = napi_create_int32(seiInfoRef->env_, playbackPosition, &position);
644             CHECK_AND_RETURN_LOG(status == napi_ok, "failed to create js number %{public}d", playbackPosition);
645 
646             napi_value array = nullptr;
647             status = napi_create_array_with_length(seiInfoRef->env_, payloadGroup.size(), &array);
648             CHECK_AND_RETURN_LOG(status == napi_ok, "failed to create js array len %{public}zu", payloadGroup.size());
649             for (uint32_t i = 0; i < payloadGroup.size(); i++) {
650                 napi_value seiPayload = nullptr;
651                 seiPayload = CommonNapi::CreateFormatBuffer(seiInfoRef->env_, payloadGroup[i]);
652                 status = napi_set_element(seiInfoRef->env_, array, i, seiPayload);
653                 CHECK_AND_RETURN_LOG(status == napi_ok, "failed to set sei element %{public}d", i);
654             }
655 
656             napi_value args[ARGS_TWO] = { array, position };
657             napi_value result = nullptr;
658             status = napi_call_function(seiInfoRef->env_, nullptr, jsCallback, ARGS_TWO, args, &result);
659             CHECK_AND_RETURN_LOG(status == napi_ok,
660                 "%{public}s failed to napi_call_function", callbackName.c_str());
661         }
662     };
663 };
664 
AVPlayerCallback(napi_env env,AVPlayerNotify * listener)665 AVPlayerCallback::AVPlayerCallback(napi_env env, AVPlayerNotify *listener)
666     : env_(env), listener_(listener)
667 {
668     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
669     InitInfoFuncsPart1();
670     InitInfoFuncsPart2();
671 }
672 
InitInfoFuncsPart1()673 void AVPlayerCallback::InitInfoFuncsPart1()
674 {
675     onInfoFuncs_ = {
676         { INFO_TYPE_STATE_CHANGE,
677             [this](const int32_t extra, const Format &infoBody) { OnStateChangeCb(extra, infoBody); } },
678         { INFO_TYPE_VOLUME_CHANGE,
679             [this](const int32_t extra, const Format &infoBody) { OnVolumeChangeCb(extra, infoBody); } },
680         { INFO_TYPE_SEEKDONE,
681             [this](const int32_t extra, const Format &infoBody) { OnSeekDoneCb(extra, infoBody); } },
682         { INFO_TYPE_SPEEDDONE,
683             [this](const int32_t extra, const Format &infoBody) { OnSpeedDoneCb(extra, infoBody); } },
684         { INFO_TYPE_BITRATEDONE,
685             [this](const int32_t extra, const Format &infoBody) { OnBitRateDoneCb(extra, infoBody); } },
686         { INFO_TYPE_POSITION_UPDATE,
687             [this](const int32_t extra, const Format &infoBody) { OnPositionUpdateCb(extra, infoBody); } },
688         { INFO_TYPE_DURATION_UPDATE,
689             [this](const int32_t extra, const Format &infoBody) { OnDurationUpdateCb(extra, infoBody); } },
690         { INFO_TYPE_BUFFERING_UPDATE,
691             [this](const int32_t extra, const Format &infoBody) { OnBufferingUpdateCb(extra, infoBody); } },
692         { INFO_TYPE_MESSAGE,
693             [this](const int32_t extra, const Format &infoBody) { OnMessageCb(extra, infoBody);} },
694         { INFO_TYPE_RESOLUTION_CHANGE,
695             [this](const int32_t extra, const Format &infoBody) { OnVideoSizeChangedCb(extra, infoBody); } },
696         { INFO_TYPE_INTERRUPT_EVENT,
697             [this](const int32_t extra, const Format &infoBody) { OnAudioInterruptCb(extra, infoBody); } },
698         { INFO_TYPE_BITRATE_COLLECT,
699              [this](const int32_t extra, const Format &infoBody) { OnBitRateCollectedCb(extra, infoBody); } },
700         { INFO_TYPE_EOS,
701             [this](const int32_t extra, const Format &infoBody) { OnEosCb(extra, infoBody); } },
702         { INFO_TYPE_IS_LIVE_STREAM,
703             [this](const int32_t extra, const Format &infoBody) { NotifyIsLiveStream(extra, infoBody); } },
704         { INFO_TYPE_SUBTITLE_UPDATE,
705             [this](const int32_t extra, const Format &infoBody) { OnSubtitleUpdateCb(extra, infoBody); } },
706         { INFO_TYPE_TRACKCHANGE,
707             [this](const int32_t extra, const Format &infoBody) { OnTrackChangedCb(extra, infoBody); } },
708         { INFO_TYPE_TRACK_INFO_UPDATE,
709             [this](const int32_t extra, const Format &infoBody) { OnTrackInfoUpdate(extra, infoBody); } },
710         { INFO_TYPE_DRM_INFO_UPDATED,
711             [this](const int32_t extra, const Format &infoBody) { OnDrmInfoUpdatedCb(extra, infoBody); } },
712         { INFO_TYPE_SET_DECRYPT_CONFIG_DONE,
713             [this](const int32_t extra, const Format &infoBody) { OnSetDecryptConfigDoneCb(extra, infoBody); } },
714         { INFO_TYPE_SUBTITLE_UPDATE_INFO,
715             [this](const int32_t extra, const Format &infoBody) { OnSubtitleInfoCb(extra, infoBody); } },
716         { INFO_TYPE_AUDIO_DEVICE_CHANGE,
717             [this](const int32_t extra, const Format &infoBody) { OnAudioDeviceChangeCb(extra, infoBody); } },
718         { INFO_TYPE_MAX_AMPLITUDE_COLLECT,
719             [this](const int32_t extra, const Format &infoBody) { OnMaxAmplitudeCollectedCb(extra, infoBody); } },
720         { INFO_TYPE_SEI_UPDATE_INFO,
721             [this](const int32_t extra, const Format &infoBody) { OnSeiInfoCb(extra, infoBody); } },
722     };
723 }
724 
InitInfoFuncsPart2()725 void AVPlayerCallback::InitInfoFuncsPart2()
726 {
727     onInfoFuncs_[INFO_TYPE_SUPER_RESOLUTION_CHANGED] =
728         [this](const int32_t extra, const Format &infoBody) { OnSuperResolutionChangedCb(extra, infoBody); };
729     onInfoFuncs_[INFO_TYPE_RATEDONE] =
730         [this](const int32_t extra, const Format &infoBody) { OnPlaybackRateDoneCb(extra, infoBody); };
731 }
732 
OnAudioDeviceChangeCb(const int32_t extra,const Format & infoBody)733 void AVPlayerCallback::OnAudioDeviceChangeCb(const int32_t extra, const Format &infoBody)
734 {
735     (void)extra;
736     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
737     if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE) == refMap_.end()) {
738         MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find audio AudioDeviceChange callback!", FAKE_POINTER(this));
739         return;
740     }
741 
742     NapiCallback::DeviceChangeNapi *cb = new(std::nothrow) NapiCallback::DeviceChangeNapi();
743     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new DeviceChangeNapi");
744 
745     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE);
746     cb->callbackName = AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE;
747 
748     uint8_t *parcelBuffer = nullptr;
749     size_t parcelSize;
750     infoBody.GetBuffer(PlayerKeys::AUDIO_DEVICE_CHANGE, &parcelBuffer, parcelSize);
751     Parcel parcel;
752     parcel.WriteBuffer(parcelBuffer, parcelSize);
753     AudioStandard::AudioDeviceDescriptor deviceInfo(AudioStandard::AudioDeviceDescriptor::DEVICE_INFO);
754     deviceInfo.UnmarshallingSelf(parcel);
755 
756     int32_t reason;
757     infoBody.GetIntValue(PlayerKeys::AUDIO_DEVICE_CHANGE_REASON, reason);
758 
759     cb->deviceInfo = deviceInfo;
760     cb->reason = reason;
761 
762     NapiCallback::CompleteCallback(env_, cb);
763 }
764 
~AVPlayerCallback()765 AVPlayerCallback::~AVPlayerCallback()
766 {
767     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
768 }
769 
OnError(int32_t errorCode,const std::string & errorMsg)770 void AVPlayerCallback::OnError(int32_t errorCode, const std::string &errorMsg)
771 {
772     MediaServiceExtErrCodeAPI9 errorCodeApi9 = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errorCode));
773     if (errorCodeApi9 == MSERR_EXT_API9_NO_PERMISSION ||
774         errorCodeApi9 == MSERR_EXT_API9_NO_MEMORY ||
775         errorCodeApi9 == MSERR_EXT_API9_TIMEOUT ||
776         errorCodeApi9 == MSERR_EXT_API9_SERVICE_DIED ||
777         errorCodeApi9 == MSERR_EXT_API9_UNSUPPORT_FORMAT) {
778         Format infoBody;
779         AVPlayerCallback::OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_STATE_ERROR, infoBody);
780     }
781     AVPlayerCallback::OnErrorCb(errorCodeApi9, errorMsg);
782 }
783 
OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode,const std::string & errorMsg)784 void AVPlayerCallback::OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode, const std::string &errorMsg)
785 {
786     std::string message = MSExtAVErrorToString(errorCode) + errorMsg;
787     MEDIA_LOGE("OnErrorCb:errorCode %{public}d, errorMsg %{public}s", errorCode, message.c_str());
788     std::lock_guard<std::mutex> lock(mutex_);
789     if (refMap_.find(AVPlayerEvent::EVENT_ERROR) == refMap_.end()) {
790         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find error callback!", FAKE_POINTER(this));
791         return;
792     }
793 
794     NapiCallback::Error *cb = new(std::nothrow) NapiCallback::Error();
795     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Error");
796 
797     cb->callback = refMap_.at(AVPlayerEvent::EVENT_ERROR);
798     cb->callbackName = AVPlayerEvent::EVENT_ERROR;
799     cb->errorCode = errorCode;
800     cb->errorMsg = message;
801     NapiCallback::CompleteCallback(env_, cb);
802 }
803 
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)804 void AVPlayerCallback::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
805 {
806     std::lock_guard<std::mutex> lock(mutex_);
807     MEDIA_LOGD("OnInfo is called, PlayerOnInfoType: %{public}d", type);
808     if (onInfoFuncs_.count(type) > 0) {
809         onInfoFuncs_[type](extra, infoBody);
810     } else {
811         MEDIA_LOGD("0x%{public}06" PRIXPTR " OnInfo: no member func supporting, %{public}d",
812             FAKE_POINTER(this), type);
813     }
814 }
815 
NotifyIsLiveStream(const int32_t extra,const Format & infoBody)816 void AVPlayerCallback::NotifyIsLiveStream(const int32_t extra, const Format &infoBody)
817 {
818     (void)extra;
819     (void)infoBody;
820     if (listener_ != nullptr) {
821         listener_->NotifyIsLiveStream();
822     }
823 }
824 
IsValidState(PlayerStates state,std::string & stateStr)825 bool AVPlayerCallback::IsValidState(PlayerStates state, std::string &stateStr)
826 {
827     switch (state) {
828         case PlayerStates::PLAYER_IDLE:
829             stateStr = AVPlayerState::STATE_IDLE;
830             break;
831         case PlayerStates::PLAYER_INITIALIZED:
832             stateStr = AVPlayerState::STATE_INITIALIZED;
833             break;
834         case PlayerStates::PLAYER_PREPARED:
835             stateStr = AVPlayerState::STATE_PREPARED;
836             break;
837         case PlayerStates::PLAYER_STARTED:
838             stateStr = AVPlayerState::STATE_PLAYING;
839             break;
840         case PlayerStates::PLAYER_PAUSED:
841             stateStr = AVPlayerState::STATE_PAUSED;
842             break;
843         case PlayerStates::PLAYER_STOPPED:
844             stateStr = AVPlayerState::STATE_STOPPED;
845             break;
846         case PlayerStates::PLAYER_PLAYBACK_COMPLETE:
847             stateStr = AVPlayerState::STATE_COMPLETED;
848             break;
849         case PlayerStates::PLAYER_RELEASED:
850             stateStr = AVPlayerState::STATE_RELEASED;
851             break;
852         case PlayerStates::PLAYER_STATE_ERROR:
853             stateStr = AVPlayerState::STATE_ERROR;
854             break;
855         default:
856             return false;
857     }
858     return true;
859 }
860 
OnStateChangeCb(const int32_t extra,const Format & infoBody)861 void AVPlayerCallback::OnStateChangeCb(const int32_t extra, const Format &infoBody)
862 {
863     PlayerStates state = static_cast<PlayerStates>(extra);
864     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instance OnStateChanged is called, current state: %{public}d",
865         FAKE_POINTER(this), state);
866 
867     if (listener_ != nullptr) {
868         listener_->NotifyState(state);
869     }
870 
871     if (state_ != state) {
872         state_ = state;
873         std::string stateStr;
874         if (IsValidState(state, stateStr)) {
875             if (refMap_.find(AVPlayerEvent::EVENT_STATE_CHANGE) == refMap_.end()) {
876                 MEDIA_LOGW("can not find state change callback!");
877                 return;
878             }
879             NapiCallback::StateChange *cb = new(std::nothrow) NapiCallback::StateChange();
880             CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new StateChange");
881 
882             int32_t reason = StateChangeReason::USER;
883             if (infoBody.ContainKey(PlayerKeys::PLAYER_STATE_CHANGED_REASON)) {
884                 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_STATE_CHANGED_REASON, reason);
885             }
886             cb->callback = refMap_.at(AVPlayerEvent::EVENT_STATE_CHANGE);
887             cb->callbackName = AVPlayerEvent::EVENT_STATE_CHANGE;
888             cb->state = stateStr;
889             cb->reason = reason;
890             NapiCallback::CompleteCallback(env_, cb);
891         }
892     }
893 }
894 
OnVolumeChangeCb(const int32_t extra,const Format & infoBody)895 void AVPlayerCallback::OnVolumeChangeCb(const int32_t extra, const Format &infoBody)
896 {
897     (void)extra;
898     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
899     float volumeLevel = 0.0;
900     (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_VOLUME_LEVEL, volumeLevel);
901 
902     isSetVolume_ = false;
903     MEDIA_LOGD("OnVolumeChangeCb in volume=%{public}f", volumeLevel);
904     if (refMap_.find(AVPlayerEvent::EVENT_VOLUME_CHANGE) == refMap_.end()) {
905         MEDIA_LOGD("can not find vol change callback!");
906         return;
907     }
908 
909     NapiCallback::Double *cb = new(std::nothrow) NapiCallback::Double();
910     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Double");
911     cb->callback = refMap_.at(AVPlayerEvent::EVENT_VOLUME_CHANGE);
912     cb->callbackName = AVPlayerEvent::EVENT_VOLUME_CHANGE;
913     cb->value = static_cast<double>(volumeLevel);
914     NapiCallback::CompleteCallback(env_, cb);
915 }
916 
OnSeekDoneCb(const int32_t extra,const Format & infoBody)917 void AVPlayerCallback::OnSeekDoneCb(const int32_t extra, const Format &infoBody)
918 {
919     (void)infoBody;
920     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
921     int32_t currentPositon = extra;
922     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSeekDone is called, currentPositon: %{public}d",
923         FAKE_POINTER(this), currentPositon);
924     if (refMap_.find(AVPlayerEvent::EVENT_SEEK_DONE) == refMap_.end()) {
925         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find seekdone callback!", FAKE_POINTER(this));
926         return;
927     }
928     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
929     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
930 
931     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SEEK_DONE);
932     cb->callbackName = AVPlayerEvent::EVENT_SEEK_DONE;
933     cb->value = currentPositon;
934     NapiCallback::CompleteCallback(env_, cb);
935 }
936 
OnSpeedDoneCb(const int32_t extra,const Format & infoBody)937 void AVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &infoBody)
938 {
939     (void)infoBody;
940     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
941     int32_t speedMode = extra;
942     MEDIA_LOGI("OnSpeedDoneCb is called, speedMode: %{public}d", speedMode);
943     if (refMap_.find(AVPlayerEvent::EVENT_SPEED_DONE) == refMap_.end()) {
944         MEDIA_LOGW("can not find speeddone callback!");
945         return;
946     }
947 
948     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
949     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
950 
951     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SPEED_DONE);
952     cb->callbackName = AVPlayerEvent::EVENT_SPEED_DONE;
953     cb->value = speedMode;
954     NapiCallback::CompleteCallback(env_, cb);
955 }
956 
OnPlaybackRateDoneCb(const int32_t extra,const Format & infoBody)957 void AVPlayerCallback::OnPlaybackRateDoneCb(const int32_t extra, const Format &infoBody)
958 {
959     (void)extra;
960     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
961     float speedRate = 0.0f;
962     (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_PLAYBACK_RATE, speedRate);
963     MEDIA_LOGI("OnPlaybackRateDoneCb is called, speedRate: %{public}f", speedRate);
964     if (refMap_.find(AVPlayerEvent::EVENT_RATE_DONE) == refMap_.end()) {
965         MEDIA_LOGW("can not find ratedone callback!");
966         return;
967     }
968 
969     NapiCallback::Double *cb = new(std::nothrow) NapiCallback::Double();
970     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new float");
971 
972     cb->callback = refMap_.at(AVPlayerEvent::EVENT_RATE_DONE);
973     cb->callbackName = AVPlayerEvent::EVENT_RATE_DONE;
974     cb->value = static_cast<double>(speedRate);
975     NapiCallback::CompleteCallback(env_, cb);
976 }
977 
OnBitRateDoneCb(const int32_t extra,const Format & infoBody)978 void AVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody)
979 {
980     (void)infoBody;
981     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
982     int32_t bitRate = extra;
983     MEDIA_LOGI("OnBitRateDoneCb is called, bitRate: %{public}d", bitRate);
984     if (refMap_.find(AVPlayerEvent::EVENT_BITRATE_DONE) == refMap_.end()) {
985         MEDIA_LOGW("can not find bitrate callback!");
986         return;
987     }
988 
989     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
990     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
991 
992     cb->callback = refMap_.at(AVPlayerEvent::EVENT_BITRATE_DONE);
993     cb->callbackName = AVPlayerEvent::EVENT_BITRATE_DONE;
994     cb->value = bitRate;
995     NapiCallback::CompleteCallback(env_, cb);
996 }
997 
OnPositionUpdateCb(const int32_t extra,const Format & infoBody)998 void AVPlayerCallback::OnPositionUpdateCb(const int32_t extra, const Format &infoBody)
999 {
1000     (void)infoBody;
1001     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1002     int32_t position = extra;
1003     MEDIA_LOGD("OnPositionUpdateCb is called, position: %{public}d", position);
1004 
1005     if (listener_ != nullptr) {
1006         listener_->NotifyPosition(position);
1007     }
1008 
1009     if (refMap_.find(AVPlayerEvent::EVENT_TIME_UPDATE) == refMap_.end()) {
1010         MEDIA_LOGD("can not find timeupdate callback!");
1011         return;
1012     }
1013     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
1014     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
1015 
1016     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TIME_UPDATE);
1017     cb->callbackName = AVPlayerEvent::EVENT_TIME_UPDATE;
1018     cb->value = position;
1019     NapiCallback::CompleteCallback(env_, cb);
1020 }
1021 
OnDurationUpdateCb(const int32_t extra,const Format & infoBody)1022 void AVPlayerCallback::OnDurationUpdateCb(const int32_t extra, const Format &infoBody)
1023 {
1024     (void)infoBody;
1025     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1026     int32_t duration = extra;
1027     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnDurationUpdateCb is called, duration: %{public}d",
1028         FAKE_POINTER(this), duration);
1029 
1030     if (listener_ != nullptr) {
1031         listener_->NotifyDuration(duration);
1032     }
1033 
1034     if (refMap_.find(AVPlayerEvent::EVENT_DURATION_UPDATE) == refMap_.end()) {
1035         MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find duration update callback!", FAKE_POINTER(this));
1036         return;
1037     }
1038 
1039     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
1040     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
1041 
1042     cb->callback = refMap_.at(AVPlayerEvent::EVENT_DURATION_UPDATE);
1043     cb->callbackName = AVPlayerEvent::EVENT_DURATION_UPDATE;
1044     cb->value = duration;
1045     NapiCallback::CompleteCallback(env_, cb);
1046 }
1047 
OnSubtitleUpdateCb(const int32_t extra,const Format & infoBody)1048 void AVPlayerCallback::OnSubtitleUpdateCb(const int32_t extra, const Format &infoBody)
1049 {
1050     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1051     if (refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE) == refMap_.end()) {
1052         MEDIA_LOGW("can not find subtitle update callback!");
1053         return;
1054     }
1055     NapiCallback::SubtitleProperty *cb = new(std::nothrow) NapiCallback::SubtitleProperty();
1056     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new SubtitleProperty");
1057     if (infoBody.ContainKey(PlayerKeys::SUBTITLE_TEXT)) {
1058         (void)infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, cb->text);
1059     }
1060     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE);
1061     cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE;
1062     NapiCallback::CompleteCallback(env_, cb);
1063 }
1064 
OnBufferingUpdateCb(const int32_t extra,const Format & infoBody)1065 void AVPlayerCallback::OnBufferingUpdateCb(const int32_t extra, const Format &infoBody)
1066 {
1067     (void)extra;
1068     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1069     if (refMap_.find(AVPlayerEvent::EVENT_BUFFERING_UPDATE) == refMap_.end()) {
1070         MEDIA_LOGD("can not find buffering update callback!");
1071         return;
1072     }
1073 
1074     int32_t val = 0;
1075     int32_t bufferingType = -1;
1076     if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_START))) {
1077         bufferingType = BUFFERING_START;
1078         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_START), val);
1079     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_END))) {
1080         bufferingType = BUFFERING_END;
1081         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_END), val);
1082     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT))) {
1083         bufferingType = BUFFERING_PERCENT;
1084         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), val);
1085     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_CACHED_DURATION))) {
1086         bufferingType = CACHED_DURATION;
1087         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION), val);
1088     } else {
1089         return;
1090     }
1091 
1092     MEDIA_LOGD("OnBufferingUpdateCb is called, buffering type: %{public}d value: %{public}d", bufferingType, val);
1093     NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
1094     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
1095 
1096     cb->callback = refMap_.at(AVPlayerEvent::EVENT_BUFFERING_UPDATE);
1097     cb->callbackName = AVPlayerEvent::EVENT_BUFFERING_UPDATE;
1098     cb->valueVec.push_back(bufferingType);
1099     cb->valueVec.push_back(val);
1100     NapiCallback::CompleteCallback(env_, cb);
1101 }
1102 
OnMessageCb(const int32_t extra,const Format & infoBody)1103 void AVPlayerCallback::OnMessageCb(const int32_t extra, const Format &infoBody)
1104 {
1105     (void)infoBody;
1106     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1107     MEDIA_LOGI("OnMessageCb is called, extra: %{public}d", extra);
1108     if (extra == PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START) {
1109         AVPlayerCallback::OnStartRenderFrameCb();
1110     }
1111 }
1112 
OnStartRenderFrameCb() const1113 void AVPlayerCallback::OnStartRenderFrameCb() const
1114 {
1115     MEDIA_LOGI("OnStartRenderFrameCb is called");
1116     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1117     if (refMap_.find(AVPlayerEvent::EVENT_START_RENDER_FRAME) == refMap_.end()) {
1118         MEDIA_LOGW("can not find start render callback!");
1119         return;
1120     }
1121 
1122     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1123     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1124 
1125     cb->callback = refMap_.at(AVPlayerEvent::EVENT_START_RENDER_FRAME);
1126     cb->callbackName = AVPlayerEvent::EVENT_START_RENDER_FRAME;
1127     NapiCallback::CompleteCallback(env_, cb);
1128 }
1129 
OnVideoSizeChangedCb(const int32_t extra,const Format & infoBody)1130 void AVPlayerCallback::OnVideoSizeChangedCb(const int32_t extra, const Format &infoBody)
1131 {
1132     (void)extra;
1133     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1134     int32_t width = 0;
1135     int32_t height = 0;
1136     (void)infoBody.GetIntValue(PlayerKeys::PLAYER_WIDTH, width);
1137     (void)infoBody.GetIntValue(PlayerKeys::PLAYER_HEIGHT, height);
1138     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnVideoSizeChangedCb is called, width = %{public}d, height = %{public}d",
1139         FAKE_POINTER(this), width, height);
1140 
1141     if (listener_ != nullptr) {
1142         listener_->NotifyVideoSize(width, height);
1143     }
1144 
1145     if (refMap_.find(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE) == refMap_.end()) {
1146         MEDIA_LOGW("can not find video size changed callback!");
1147         return;
1148     }
1149     NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
1150     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
1151 
1152     cb->callback = refMap_.at(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE);
1153     cb->callbackName = AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE;
1154     cb->valueVec.push_back(width);
1155     cb->valueVec.push_back(height);
1156     NapiCallback::CompleteCallback(env_, cb);
1157 }
1158 
OnAudioInterruptCb(const int32_t extra,const Format & infoBody)1159 void AVPlayerCallback::OnAudioInterruptCb(const int32_t extra, const Format &infoBody)
1160 {
1161     (void)extra;
1162     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1163     if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_INTERRUPT) == refMap_.end()) {
1164         MEDIA_LOGW("can not find audio interrupt callback!");
1165         return;
1166     }
1167 
1168     NapiCallback::PropertyInt *cb = new(std::nothrow) NapiCallback::PropertyInt();
1169     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new PropertyInt");
1170 
1171     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_INTERRUPT);
1172     cb->callbackName = AVPlayerEvent::EVENT_AUDIO_INTERRUPT;
1173     int32_t eventType = 0;
1174     int32_t forceType = 0;
1175     int32_t hintType = 0;
1176     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventType);
1177     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceType);
1178     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintType);
1179     MEDIA_LOGI("OnAudioInterruptCb is called, eventType = %{public}d, forceType = %{public}d, hintType = %{public}d",
1180         eventType, forceType, hintType);
1181     // ohos.multimedia.audio.d.ts interface InterruptEvent
1182     cb->valueMap["eventType"] = eventType;
1183     cb->valueMap["forceType"] = forceType;
1184     cb->valueMap["hintType"] = hintType;
1185     NapiCallback::CompleteCallback(env_, cb);
1186 }
1187 
OnBitRateCollectedCb(const int32_t extra,const Format & infoBody)1188 void AVPlayerCallback::OnBitRateCollectedCb(const int32_t extra, const Format &infoBody)
1189 {
1190     (void)extra;
1191     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1192     if (refMap_.find(AVPlayerEvent::EVENT_AVAILABLE_BITRATES) == refMap_.end()) {
1193         MEDIA_LOGW("can not find bitrate collected callback!");
1194         return;
1195     }
1196 
1197     std::vector<int32_t> bitrateVec;
1198     if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES))) {
1199         uint8_t *addr = nullptr;
1200         size_t size  = 0;
1201         infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES), &addr, size);
1202         CHECK_AND_RETURN_LOG(addr != nullptr, "bitrate addr is nullptr");
1203 
1204         MEDIA_LOGI("bitrate size = %{public}zu", size / sizeof(uint32_t));
1205         while (size > 0) {
1206             if (size < sizeof(uint32_t)) {
1207                 break;
1208             }
1209 
1210             uint32_t bitrate = *(static_cast<uint32_t *>(static_cast<void *>(addr)));
1211             MEDIA_LOGI("bitrate = %{public}u", bitrate);
1212             addr += sizeof(uint32_t);
1213             size -= sizeof(uint32_t);
1214             bitrateVec.push_back(static_cast<int32_t>(bitrate));
1215         }
1216     }
1217 
1218     NapiCallback::IntArray *cb = new(std::nothrow) NapiCallback::IntArray();
1219     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1220 
1221     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AVAILABLE_BITRATES);
1222     cb->callbackName = AVPlayerEvent::EVENT_AVAILABLE_BITRATES;
1223     cb->valueVec = bitrateVec;
1224     NapiCallback::CompleteCallback(env_, cb);
1225 }
1226 
OnMaxAmplitudeCollectedCb(const int32_t extra,const Format & infoBody)1227 void AVPlayerCallback::OnMaxAmplitudeCollectedCb(const int32_t extra, const Format &infoBody)
1228 {
1229     (void)extra;
1230     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1231     if (refMap_.find(AVPlayerEvent::EVENT_AMPLITUDE_UPDATE) == refMap_.end()) {
1232         MEDIA_LOGD("can not find max amplitude collected callback!");
1233         return;
1234     }
1235 
1236     std::vector<float> MaxAmplitudeVec;
1237     if (infoBody.ContainKey(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE))) {
1238         uint8_t *addr = nullptr;
1239         size_t size  = 0;
1240         infoBody.GetBuffer(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE), &addr, size);
1241         CHECK_AND_RETURN_LOG(addr != nullptr, "max amplitude addr is nullptr");
1242 
1243         MEDIA_LOGD("max amplitude size = %{public}zu", size / sizeof(float));
1244         while (size > 0) {
1245             if (size < sizeof(float)) {
1246                 break;
1247             }
1248 
1249             float maxAmplitude = *(static_cast<float *>(static_cast<void *>(addr)));
1250             MEDIA_LOGD("maxAmplitude = %{public}f", maxAmplitude);
1251             addr += sizeof(float);
1252             size -= sizeof(float);
1253             MaxAmplitudeVec.push_back(static_cast<float>(maxAmplitude));
1254         }
1255     }
1256 
1257     NapiCallback::FloatArray *cb = new(std::nothrow) NapiCallback::FloatArray();
1258     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1259 
1260     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AMPLITUDE_UPDATE);
1261     cb->callbackName = AVPlayerEvent::EVENT_AMPLITUDE_UPDATE;
1262     cb->valueVec = MaxAmplitudeVec;
1263     NapiCallback::CompleteCallback(env_, cb);
1264 }
1265 
OnSeiInfoCb(const int32_t extra,const Format & infoBody)1266 void AVPlayerCallback::OnSeiInfoCb(const int32_t extra, const Format &infoBody)
1267 {
1268     CHECK_AND_RETURN_LOG(
1269         refMap_.find(AVPlayerEvent::EVENT_SEI_MESSAGE_INFO) != refMap_.end(), "can not find on sei message callback!");
1270 
1271     (void)extra;
1272     int32_t playbackPosition = 0;
1273     bool res = infoBody.GetIntValue(Tag::AV_PLAYER_SEI_PLAYBACK_POSITION, playbackPosition);
1274     CHECK_AND_RETURN_LOG(res, "get playback position failed");
1275 
1276     std::vector<Format> formatVec;
1277     res = infoBody.GetFormatVector(Tag::AV_PLAYER_SEI_PLAYBACK_GROUP, formatVec);
1278     CHECK_AND_RETURN_LOG(res, "get sei payload group failed");
1279 
1280     NapiCallback::SeiInfoUpadte *cb = new(std::nothrow) NapiCallback::SeiInfoUpadte();
1281     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1282 
1283     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SEI_MESSAGE_INFO);
1284     cb->callbackName = AVPlayerEvent::EVENT_SEI_MESSAGE_INFO;
1285     cb->playbackPosition = playbackPosition;
1286     cb->payloadGroup = formatVec;
1287     NapiCallback::CompleteCallback(env_, cb);
1288 }
1289 
OnSuperResolutionChangedCb(const int32_t extra,const Format & infoBody)1290 void AVPlayerCallback::OnSuperResolutionChangedCb(const int32_t extra, const Format &infoBody)
1291 {
1292     (void)extra;
1293     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1294     int32_t enabled = 0;
1295     (void)infoBody.GetIntValue(PlayerKeys::SUPER_RESOLUTION_ENABLED, enabled);
1296     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSuperResolutionChangedCb is called, enabled = %{public}d",
1297         FAKE_POINTER(this), enabled);
1298 
1299     if (refMap_.find(AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED) == refMap_.end()) {
1300         MEDIA_LOGW("can not find super resolution changed callback!");
1301         return;
1302     }
1303     NapiCallback::Bool *cb = new(std::nothrow) NapiCallback::Bool();
1304     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Bool");
1305 
1306     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED);
1307     cb->callbackName = AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED;
1308     cb->value = enabled ? true : false;
1309     NapiCallback::CompleteCallback(env_, cb);
1310 }
1311 
SetDrmInfoData(const uint8_t * drmInfoAddr,int32_t infoCount,std::multimap<std::string,std::vector<uint8_t>> & drmInfoMap)1312 int32_t AVPlayerCallback::SetDrmInfoData(const uint8_t *drmInfoAddr, int32_t infoCount,
1313     std::multimap<std::string, std::vector<uint8_t>> &drmInfoMap)
1314 {
1315     DrmInfoItem *drmInfos = reinterpret_cast<DrmInfoItem*>(const_cast<uint8_t *>(drmInfoAddr));
1316     CHECK_AND_RETURN_RET_LOG(drmInfos != nullptr, MSERR_INVALID_VAL, "cast drmInfos nullptr");
1317     for (int32_t i = 0; i < infoCount; i++) {
1318         DrmInfoItem temp = drmInfos[i];
1319         std::stringstream ssConverter;
1320         std::string uuid;
1321         for (uint32_t index = 0; index < DrmConstant::DRM_MAX_M3U8_DRM_UUID_LEN; index++) {
1322             int32_t singleUuid = static_cast<int32_t>(temp.uuid[index]);
1323             ssConverter << std::hex << std::setfill('0') << std::setw(2) << singleUuid; // 2:w
1324             uuid = ssConverter.str();
1325         }
1326         if (temp.psshLen <= 0 || temp.psshLen > DrmConstant::DRM_MAX_M3U8_DRM_PSSH_LEN) {
1327             MEDIA_LOGW("drmInfoItem psshLen is invalid");
1328             continue;
1329         }
1330         std::vector<uint8_t> pssh(temp.pssh, temp.pssh + temp.psshLen);
1331         drmInfoMap.insert({ uuid, pssh });
1332     }
1333 
1334     if (listener_ != nullptr) {
1335         listener_->NotifyDrmInfoUpdated(drmInfoMap);
1336     }
1337     return MSERR_OK;
1338 }
1339 
OnDrmInfoUpdatedCb(const int32_t extra,const Format & infoBody)1340 void AVPlayerCallback::OnDrmInfoUpdatedCb(const int32_t extra, const Format &infoBody)
1341 {
1342     (void)extra;
1343     MEDIA_LOGI("AVPlayerCallback OnDrmInfoUpdatedCb is called");
1344     if (refMap_.find(AVPlayerEvent::EVENT_DRM_INFO_UPDATE) == refMap_.end()) {
1345         MEDIA_LOGW("can not find drm info updated callback!");
1346         return;
1347     }
1348     if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR))) {
1349         MEDIA_LOGW("there's no drminfo-update drm_info_addr key");
1350         return;
1351     }
1352     if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT))) {
1353         MEDIA_LOGW("there's no drminfo-update drm_info_count key");
1354         return;
1355     }
1356 
1357     uint8_t *drmInfoAddr = nullptr;
1358     size_t size  = 0;
1359     int32_t infoCount = 0;
1360     infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR), &drmInfoAddr, size);
1361     CHECK_AND_RETURN_LOG(drmInfoAddr != nullptr && size > 0, "get drminfo buffer failed");
1362     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT), infoCount);
1363     CHECK_AND_RETURN_LOG(infoCount > 0, "get drminfo count is illegal");
1364 
1365     std::multimap<std::string, std::vector<uint8_t>> drmInfoMap;
1366     int32_t ret = SetDrmInfoData(drmInfoAddr, infoCount, drmInfoMap);
1367     CHECK_AND_RETURN_LOG(ret == MSERR_OK, "SetDrmInfoData err");
1368     NapiCallback::ObjectArray *cb = new(std::nothrow) NapiCallback::ObjectArray();
1369     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new ObjectArray");
1370     cb->callback = refMap_.at(AVPlayerEvent::EVENT_DRM_INFO_UPDATE);
1371     cb->callbackName = AVPlayerEvent::EVENT_DRM_INFO_UPDATE;
1372     cb->infoMap = drmInfoMap;
1373     NapiCallback::CompleteCallback(env_, cb);
1374 }
1375 
OnSetDecryptConfigDoneCb(const int32_t extra,const Format & infoBody)1376 void AVPlayerCallback::OnSetDecryptConfigDoneCb(const int32_t extra, const Format &infoBody)
1377 {
1378     (void)extra;
1379     MEDIA_LOGI("AVPlayerCallback OnSetDecryptConfigDoneCb is called");
1380     if (refMap_.find(AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE) == refMap_.end()) {
1381         MEDIA_LOGW("can not find SetDecryptConfig Done callback!");
1382         return;
1383     }
1384 
1385     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1386     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1387 
1388     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE);
1389     cb->callbackName = AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE;
1390     NapiCallback::CompleteCallback(env_, cb);
1391 }
1392 
OnSubtitleInfoCb(const int32_t extra,const Format & infoBody)1393 void AVPlayerCallback::OnSubtitleInfoCb(const int32_t extra, const Format &infoBody)
1394 {
1395     (void)infoBody;
1396     int32_t pts = -1;
1397     int32_t duration = -1;
1398     std::string text;
1399     infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, text);
1400     infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_PTS), pts);
1401     infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_DURATION), duration);
1402     MEDIA_LOGI("OnSubtitleInfoCb pts %{public}d, duration = %{public}d", pts, duration);
1403 
1404     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_UPDATE) != refMap_.end(),
1405         "can not find Subtitle callback!");
1406 
1407     NapiCallback::SubtitleInfo *cb = new(std::nothrow) NapiCallback::SubtitleInfo();
1408     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Subtitle");
1409 
1410     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_UPDATE);
1411     cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_UPDATE;
1412     cb->valueMap.text = text;
1413     cb->valueMap.pts = pts;
1414     cb->valueMap.duration = duration;
1415 
1416     NapiCallback::CompleteCallback(env_, cb);
1417 }
1418 
OnEosCb(const int32_t extra,const Format & infoBody)1419 void AVPlayerCallback::OnEosCb(const int32_t extra, const Format &infoBody)
1420 {
1421     (void)infoBody;
1422     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1423     int32_t isLooping = extra;
1424     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnEndOfStream is called, isloop: %{public}d", FAKE_POINTER(this), isLooping);
1425     if (refMap_.find(AVPlayerEvent::EVENT_END_OF_STREAM) == refMap_.end()) {
1426         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find EndOfStream callback!", FAKE_POINTER(this));
1427         return;
1428     }
1429 
1430     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1431     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1432 
1433     cb->callback = refMap_.at(AVPlayerEvent::EVENT_END_OF_STREAM);
1434     cb->callbackName = AVPlayerEvent::EVENT_END_OF_STREAM;
1435     NapiCallback::CompleteCallback(env_, cb);
1436 }
1437 
OnTrackChangedCb(const int32_t extra,const Format & infoBody)1438 void AVPlayerCallback::OnTrackChangedCb(const int32_t extra, const Format &infoBody)
1439 {
1440     (void)extra;
1441     int32_t index = -1;
1442     int32_t isSelect = -1;
1443     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_TRACK_INDEX), index);
1444     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_IS_SELECT), isSelect);
1445     MEDIA_LOGI("OnTrackChangedCb index %{public}d, isSelect = %{public}d", index, isSelect);
1446 
1447     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACKCHANGE) != refMap_.end(),
1448         "can not find trackChange callback!");
1449 
1450     NapiCallback::TrackChange *cb = new(std::nothrow) NapiCallback::TrackChange();
1451     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackChange");
1452 
1453     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACKCHANGE);
1454     cb->callbackName = AVPlayerEvent::EVENT_TRACKCHANGE;
1455     cb->number = index;
1456     cb->isSelect = isSelect ? true : false;
1457     NapiCallback::CompleteCallback(env_, cb);
1458 }
1459 
OnTrackInfoUpdate(const int32_t extra,const Format & infoBody)1460 void AVPlayerCallback::OnTrackInfoUpdate(const int32_t extra, const Format &infoBody)
1461 {
1462     (void)extra;
1463     std::vector<Format> trackInfo;
1464     (void)infoBody.GetFormatVector(std::string(PlayerKeys::PLAYER_TRACK_INFO), trackInfo);
1465     MEDIA_LOGI("OnTrackInfoUpdate callback");
1466 
1467     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE) != refMap_.end(),
1468         "can not find trackInfoUpdate callback!");
1469 
1470     NapiCallback::TrackInfoUpdate *cb = new(std::nothrow) NapiCallback::TrackInfoUpdate();
1471     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackInfoUpdate");
1472 
1473     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE);
1474     cb->callbackName = AVPlayerEvent::EVENT_TRACK_INFO_UPDATE;
1475     cb->trackInfo = trackInfo;
1476     NapiCallback::CompleteCallback(env_, cb);
1477 }
1478 
SaveCallbackReference(const std::string & name,std::weak_ptr<AutoRef> ref)1479 void AVPlayerCallback::SaveCallbackReference(const std::string &name, std::weak_ptr<AutoRef> ref)
1480 {
1481     std::lock_guard<std::mutex> lock(mutex_);
1482     refMap_[name] = ref;
1483 }
1484 
ClearCallbackReference()1485 void AVPlayerCallback::ClearCallbackReference()
1486 {
1487     std::lock_guard<std::mutex> lock(mutex_);
1488     refMap_.clear();
1489 }
1490 
ClearCallbackReference(const std::string & name)1491 void AVPlayerCallback::ClearCallbackReference(const std::string &name)
1492 {
1493     std::lock_guard<std::mutex> lock(mutex_);
1494     refMap_.erase(name);
1495 }
1496 
Start()1497 void AVPlayerCallback::Start()
1498 {
1499     isloaded_ = true;
1500 }
1501 
Pause()1502 void AVPlayerCallback::Pause()
1503 {
1504     isloaded_ = false;
1505 }
1506 
Release()1507 void AVPlayerCallback::Release()
1508 {
1509     std::lock_guard<std::mutex> lock(mutex_);
1510 
1511     Format infoBody;
1512     AVPlayerCallback::OnStateChangeCb(PlayerStates::PLAYER_RELEASED, infoBody);
1513     listener_ = nullptr;
1514 }
1515 } // namespace Media
1516 } // namespace OHOS
1517