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