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 }
730
OnAudioDeviceChangeCb(const int32_t extra,const Format & infoBody)731 void AVPlayerCallback::OnAudioDeviceChangeCb(const int32_t extra, const Format &infoBody)
732 {
733 (void)extra;
734 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
735 if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE) == refMap_.end()) {
736 MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find audio AudioDeviceChange callback!", FAKE_POINTER(this));
737 return;
738 }
739
740 NapiCallback::DeviceChangeNapi *cb = new(std::nothrow) NapiCallback::DeviceChangeNapi();
741 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new DeviceChangeNapi");
742
743 cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE);
744 cb->callbackName = AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE;
745
746 uint8_t *parcelBuffer = nullptr;
747 size_t parcelSize;
748 infoBody.GetBuffer(PlayerKeys::AUDIO_DEVICE_CHANGE, &parcelBuffer, parcelSize);
749 Parcel parcel;
750 parcel.WriteBuffer(parcelBuffer, parcelSize);
751 AudioStandard::AudioDeviceDescriptor deviceInfo(AudioStandard::AudioDeviceDescriptor::DEVICE_INFO);
752 deviceInfo.Unmarshalling(parcel);
753
754 int32_t reason;
755 infoBody.GetIntValue(PlayerKeys::AUDIO_DEVICE_CHANGE_REASON, reason);
756
757 cb->deviceInfo = deviceInfo;
758 cb->reason = reason;
759
760 NapiCallback::CompleteCallback(env_, cb);
761 }
762
~AVPlayerCallback()763 AVPlayerCallback::~AVPlayerCallback()
764 {
765 MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
766 }
767
OnError(int32_t errorCode,const std::string & errorMsg)768 void AVPlayerCallback::OnError(int32_t errorCode, const std::string &errorMsg)
769 {
770 MediaServiceExtErrCodeAPI9 errorCodeApi9 = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errorCode));
771 if (errorCodeApi9 == MSERR_EXT_API9_NO_PERMISSION ||
772 errorCodeApi9 == MSERR_EXT_API9_NO_MEMORY ||
773 errorCodeApi9 == MSERR_EXT_API9_TIMEOUT ||
774 errorCodeApi9 == MSERR_EXT_API9_SERVICE_DIED ||
775 errorCodeApi9 == MSERR_EXT_API9_UNSUPPORT_FORMAT) {
776 Format infoBody;
777 AVPlayerCallback::OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_STATE_ERROR, infoBody);
778 }
779 AVPlayerCallback::OnErrorCb(errorCodeApi9, errorMsg);
780 }
781
OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode,const std::string & errorMsg)782 void AVPlayerCallback::OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode, const std::string &errorMsg)
783 {
784 std::string message = MSExtAVErrorToString(errorCode) + errorMsg;
785 MEDIA_LOGE("OnErrorCb:errorCode %{public}d, errorMsg %{public}s", errorCode, message.c_str());
786 std::lock_guard<std::mutex> lock(mutex_);
787 if (refMap_.find(AVPlayerEvent::EVENT_ERROR) == refMap_.end()) {
788 MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find error callback!", FAKE_POINTER(this));
789 return;
790 }
791
792 NapiCallback::Error *cb = new(std::nothrow) NapiCallback::Error();
793 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Error");
794
795 cb->callback = refMap_.at(AVPlayerEvent::EVENT_ERROR);
796 cb->callbackName = AVPlayerEvent::EVENT_ERROR;
797 cb->errorCode = errorCode;
798 cb->errorMsg = message;
799 NapiCallback::CompleteCallback(env_, cb);
800 }
801
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)802 void AVPlayerCallback::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
803 {
804 std::lock_guard<std::mutex> lock(mutex_);
805 MEDIA_LOGD("OnInfo is called, PlayerOnInfoType: %{public}d", type);
806 if (onInfoFuncs_.count(type) > 0) {
807 onInfoFuncs_[type](extra, infoBody);
808 } else {
809 MEDIA_LOGD("0x%{public}06" PRIXPTR " OnInfo: no member func supporting, %{public}d",
810 FAKE_POINTER(this), type);
811 }
812 }
813
NotifyIsLiveStream(const int32_t extra,const Format & infoBody)814 void AVPlayerCallback::NotifyIsLiveStream(const int32_t extra, const Format &infoBody)
815 {
816 (void)extra;
817 (void)infoBody;
818 if (listener_ != nullptr) {
819 listener_->NotifyIsLiveStream();
820 }
821 }
822
IsValidState(PlayerStates state,std::string & stateStr)823 bool AVPlayerCallback::IsValidState(PlayerStates state, std::string &stateStr)
824 {
825 switch (state) {
826 case PlayerStates::PLAYER_IDLE:
827 stateStr = AVPlayerState::STATE_IDLE;
828 break;
829 case PlayerStates::PLAYER_INITIALIZED:
830 stateStr = AVPlayerState::STATE_INITIALIZED;
831 break;
832 case PlayerStates::PLAYER_PREPARED:
833 stateStr = AVPlayerState::STATE_PREPARED;
834 break;
835 case PlayerStates::PLAYER_STARTED:
836 stateStr = AVPlayerState::STATE_PLAYING;
837 break;
838 case PlayerStates::PLAYER_PAUSED:
839 stateStr = AVPlayerState::STATE_PAUSED;
840 break;
841 case PlayerStates::PLAYER_STOPPED:
842 stateStr = AVPlayerState::STATE_STOPPED;
843 break;
844 case PlayerStates::PLAYER_PLAYBACK_COMPLETE:
845 stateStr = AVPlayerState::STATE_COMPLETED;
846 break;
847 case PlayerStates::PLAYER_RELEASED:
848 stateStr = AVPlayerState::STATE_RELEASED;
849 break;
850 case PlayerStates::PLAYER_STATE_ERROR:
851 stateStr = AVPlayerState::STATE_ERROR;
852 break;
853 default:
854 return false;
855 }
856 return true;
857 }
858
OnStateChangeCb(const int32_t extra,const Format & infoBody)859 void AVPlayerCallback::OnStateChangeCb(const int32_t extra, const Format &infoBody)
860 {
861 PlayerStates state = static_cast<PlayerStates>(extra);
862 MEDIA_LOGI("0x%{public}06" PRIXPTR " Instance OnStateChanged is called, current state: %{public}d",
863 FAKE_POINTER(this), state);
864
865 if (listener_ != nullptr) {
866 listener_->NotifyState(state);
867 }
868
869 if (state_ != state) {
870 state_ = state;
871 std::string stateStr;
872 if (IsValidState(state, stateStr)) {
873 if (refMap_.find(AVPlayerEvent::EVENT_STATE_CHANGE) == refMap_.end()) {
874 MEDIA_LOGW("can not find state change callback!");
875 return;
876 }
877 NapiCallback::StateChange *cb = new(std::nothrow) NapiCallback::StateChange();
878 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new StateChange");
879
880 int32_t reason = StateChangeReason::USER;
881 if (infoBody.ContainKey(PlayerKeys::PLAYER_STATE_CHANGED_REASON)) {
882 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_STATE_CHANGED_REASON, reason);
883 }
884 cb->callback = refMap_.at(AVPlayerEvent::EVENT_STATE_CHANGE);
885 cb->callbackName = AVPlayerEvent::EVENT_STATE_CHANGE;
886 cb->state = stateStr;
887 cb->reason = reason;
888 NapiCallback::CompleteCallback(env_, cb);
889 }
890 }
891 }
892
OnVolumeChangeCb(const int32_t extra,const Format & infoBody)893 void AVPlayerCallback::OnVolumeChangeCb(const int32_t extra, const Format &infoBody)
894 {
895 (void)extra;
896 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
897 float volumeLevel = 0.0;
898 (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_VOLUME_LEVEL, volumeLevel);
899
900 isSetVolume_ = false;
901 MEDIA_LOGD("OnVolumeChangeCb in volume=%{public}f", volumeLevel);
902 if (refMap_.find(AVPlayerEvent::EVENT_VOLUME_CHANGE) == refMap_.end()) {
903 MEDIA_LOGD("can not find vol change callback!");
904 return;
905 }
906
907 NapiCallback::Double *cb = new(std::nothrow) NapiCallback::Double();
908 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Double");
909 cb->callback = refMap_.at(AVPlayerEvent::EVENT_VOLUME_CHANGE);
910 cb->callbackName = AVPlayerEvent::EVENT_VOLUME_CHANGE;
911 cb->value = static_cast<double>(volumeLevel);
912 NapiCallback::CompleteCallback(env_, cb);
913 }
914
OnSeekDoneCb(const int32_t extra,const Format & infoBody)915 void AVPlayerCallback::OnSeekDoneCb(const int32_t extra, const Format &infoBody)
916 {
917 (void)infoBody;
918 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
919 int32_t currentPositon = extra;
920 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSeekDone is called, currentPositon: %{public}d",
921 FAKE_POINTER(this), currentPositon);
922 if (refMap_.find(AVPlayerEvent::EVENT_SEEK_DONE) == refMap_.end()) {
923 MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find seekdone callback!", FAKE_POINTER(this));
924 return;
925 }
926 NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
927 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
928
929 cb->callback = refMap_.at(AVPlayerEvent::EVENT_SEEK_DONE);
930 cb->callbackName = AVPlayerEvent::EVENT_SEEK_DONE;
931 cb->value = currentPositon;
932 NapiCallback::CompleteCallback(env_, cb);
933 }
934
OnSpeedDoneCb(const int32_t extra,const Format & infoBody)935 void AVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &infoBody)
936 {
937 (void)infoBody;
938 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
939 int32_t speedMode = extra;
940 MEDIA_LOGI("OnSpeedDoneCb is called, speedMode: %{public}d", speedMode);
941 if (refMap_.find(AVPlayerEvent::EVENT_SPEED_DONE) == refMap_.end()) {
942 MEDIA_LOGW("can not find speeddone callback!");
943 return;
944 }
945
946 NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
947 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
948
949 cb->callback = refMap_.at(AVPlayerEvent::EVENT_SPEED_DONE);
950 cb->callbackName = AVPlayerEvent::EVENT_SPEED_DONE;
951 cb->value = speedMode;
952 NapiCallback::CompleteCallback(env_, cb);
953 }
954
OnBitRateDoneCb(const int32_t extra,const Format & infoBody)955 void AVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody)
956 {
957 (void)infoBody;
958 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
959 int32_t bitRate = extra;
960 MEDIA_LOGI("OnBitRateDoneCb is called, bitRate: %{public}d", bitRate);
961 if (refMap_.find(AVPlayerEvent::EVENT_BITRATE_DONE) == refMap_.end()) {
962 MEDIA_LOGW("can not find bitrate callback!");
963 return;
964 }
965
966 NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
967 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
968
969 cb->callback = refMap_.at(AVPlayerEvent::EVENT_BITRATE_DONE);
970 cb->callbackName = AVPlayerEvent::EVENT_BITRATE_DONE;
971 cb->value = bitRate;
972 NapiCallback::CompleteCallback(env_, cb);
973 }
974
OnPositionUpdateCb(const int32_t extra,const Format & infoBody)975 void AVPlayerCallback::OnPositionUpdateCb(const int32_t extra, const Format &infoBody)
976 {
977 (void)infoBody;
978 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
979 int32_t position = extra;
980 MEDIA_LOGD("OnPositionUpdateCb is called, position: %{public}d", position);
981
982 if (listener_ != nullptr) {
983 listener_->NotifyPosition(position);
984 }
985
986 if (refMap_.find(AVPlayerEvent::EVENT_TIME_UPDATE) == refMap_.end()) {
987 MEDIA_LOGD("can not find timeupdate callback!");
988 return;
989 }
990 NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
991 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
992
993 cb->callback = refMap_.at(AVPlayerEvent::EVENT_TIME_UPDATE);
994 cb->callbackName = AVPlayerEvent::EVENT_TIME_UPDATE;
995 cb->value = position;
996 NapiCallback::CompleteCallback(env_, cb);
997 }
998
OnDurationUpdateCb(const int32_t extra,const Format & infoBody)999 void AVPlayerCallback::OnDurationUpdateCb(const int32_t extra, const Format &infoBody)
1000 {
1001 (void)infoBody;
1002 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1003 int32_t duration = extra;
1004 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnDurationUpdateCb is called, duration: %{public}d",
1005 FAKE_POINTER(this), duration);
1006
1007 if (listener_ != nullptr) {
1008 listener_->NotifyDuration(duration);
1009 }
1010
1011 if (refMap_.find(AVPlayerEvent::EVENT_DURATION_UPDATE) == refMap_.end()) {
1012 MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find duration update callback!", FAKE_POINTER(this));
1013 return;
1014 }
1015
1016 NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
1017 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
1018
1019 cb->callback = refMap_.at(AVPlayerEvent::EVENT_DURATION_UPDATE);
1020 cb->callbackName = AVPlayerEvent::EVENT_DURATION_UPDATE;
1021 cb->value = duration;
1022 NapiCallback::CompleteCallback(env_, cb);
1023 }
1024
OnSubtitleUpdateCb(const int32_t extra,const Format & infoBody)1025 void AVPlayerCallback::OnSubtitleUpdateCb(const int32_t extra, const Format &infoBody)
1026 {
1027 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1028 if (refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE) == refMap_.end()) {
1029 MEDIA_LOGW("can not find subtitle update callback!");
1030 return;
1031 }
1032 NapiCallback::SubtitleProperty *cb = new(std::nothrow) NapiCallback::SubtitleProperty();
1033 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new SubtitleProperty");
1034 if (infoBody.ContainKey(PlayerKeys::SUBTITLE_TEXT)) {
1035 (void)infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, cb->text);
1036 }
1037 cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE);
1038 cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE;
1039 NapiCallback::CompleteCallback(env_, cb);
1040 }
1041
OnBufferingUpdateCb(const int32_t extra,const Format & infoBody)1042 void AVPlayerCallback::OnBufferingUpdateCb(const int32_t extra, const Format &infoBody)
1043 {
1044 (void)extra;
1045 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1046 if (refMap_.find(AVPlayerEvent::EVENT_BUFFERING_UPDATE) == refMap_.end()) {
1047 MEDIA_LOGD("can not find buffering update callback!");
1048 return;
1049 }
1050
1051 int32_t val = 0;
1052 int32_t bufferingType = -1;
1053 if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_START))) {
1054 bufferingType = BUFFERING_START;
1055 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_START), val);
1056 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_END))) {
1057 bufferingType = BUFFERING_END;
1058 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_END), val);
1059 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT))) {
1060 bufferingType = BUFFERING_PERCENT;
1061 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), val);
1062 } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_CACHED_DURATION))) {
1063 bufferingType = CACHED_DURATION;
1064 (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION), val);
1065 } else {
1066 return;
1067 }
1068
1069 MEDIA_LOGD("OnBufferingUpdateCb is called, buffering type: %{public}d value: %{public}d", bufferingType, val);
1070 NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
1071 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
1072
1073 cb->callback = refMap_.at(AVPlayerEvent::EVENT_BUFFERING_UPDATE);
1074 cb->callbackName = AVPlayerEvent::EVENT_BUFFERING_UPDATE;
1075 cb->valueVec.push_back(bufferingType);
1076 cb->valueVec.push_back(val);
1077 NapiCallback::CompleteCallback(env_, cb);
1078 }
1079
OnMessageCb(const int32_t extra,const Format & infoBody)1080 void AVPlayerCallback::OnMessageCb(const int32_t extra, const Format &infoBody)
1081 {
1082 (void)infoBody;
1083 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1084 MEDIA_LOGI("OnMessageCb is called, extra: %{public}d", extra);
1085 if (extra == PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START) {
1086 AVPlayerCallback::OnStartRenderFrameCb();
1087 }
1088 }
1089
OnStartRenderFrameCb() const1090 void AVPlayerCallback::OnStartRenderFrameCb() const
1091 {
1092 MEDIA_LOGI("OnStartRenderFrameCb is called");
1093 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1094 if (refMap_.find(AVPlayerEvent::EVENT_START_RENDER_FRAME) == refMap_.end()) {
1095 MEDIA_LOGW("can not find start render callback!");
1096 return;
1097 }
1098
1099 NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1100 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1101
1102 cb->callback = refMap_.at(AVPlayerEvent::EVENT_START_RENDER_FRAME);
1103 cb->callbackName = AVPlayerEvent::EVENT_START_RENDER_FRAME;
1104 NapiCallback::CompleteCallback(env_, cb);
1105 }
1106
OnVideoSizeChangedCb(const int32_t extra,const Format & infoBody)1107 void AVPlayerCallback::OnVideoSizeChangedCb(const int32_t extra, const Format &infoBody)
1108 {
1109 (void)extra;
1110 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1111 int32_t width = 0;
1112 int32_t height = 0;
1113 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_WIDTH, width);
1114 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_HEIGHT, height);
1115 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnVideoSizeChangedCb is called, width = %{public}d, height = %{public}d",
1116 FAKE_POINTER(this), width, height);
1117
1118 if (listener_ != nullptr) {
1119 listener_->NotifyVideoSize(width, height);
1120 }
1121
1122 if (refMap_.find(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE) == refMap_.end()) {
1123 MEDIA_LOGW("can not find video size changed callback!");
1124 return;
1125 }
1126 NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
1127 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
1128
1129 cb->callback = refMap_.at(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE);
1130 cb->callbackName = AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE;
1131 cb->valueVec.push_back(width);
1132 cb->valueVec.push_back(height);
1133 NapiCallback::CompleteCallback(env_, cb);
1134 }
1135
OnAudioInterruptCb(const int32_t extra,const Format & infoBody)1136 void AVPlayerCallback::OnAudioInterruptCb(const int32_t extra, const Format &infoBody)
1137 {
1138 (void)extra;
1139 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1140 if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_INTERRUPT) == refMap_.end()) {
1141 MEDIA_LOGW("can not find audio interrupt callback!");
1142 return;
1143 }
1144
1145 NapiCallback::PropertyInt *cb = new(std::nothrow) NapiCallback::PropertyInt();
1146 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new PropertyInt");
1147
1148 cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_INTERRUPT);
1149 cb->callbackName = AVPlayerEvent::EVENT_AUDIO_INTERRUPT;
1150 int32_t eventType = 0;
1151 int32_t forceType = 0;
1152 int32_t hintType = 0;
1153 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventType);
1154 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceType);
1155 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintType);
1156 MEDIA_LOGI("OnAudioInterruptCb is called, eventType = %{public}d, forceType = %{public}d, hintType = %{public}d",
1157 eventType, forceType, hintType);
1158 // ohos.multimedia.audio.d.ts interface InterruptEvent
1159 cb->valueMap["eventType"] = eventType;
1160 cb->valueMap["forceType"] = forceType;
1161 cb->valueMap["hintType"] = hintType;
1162 NapiCallback::CompleteCallback(env_, cb);
1163 }
1164
OnBitRateCollectedCb(const int32_t extra,const Format & infoBody)1165 void AVPlayerCallback::OnBitRateCollectedCb(const int32_t extra, const Format &infoBody)
1166 {
1167 (void)extra;
1168 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1169 if (refMap_.find(AVPlayerEvent::EVENT_AVAILABLE_BITRATES) == refMap_.end()) {
1170 MEDIA_LOGW("can not find bitrate collected callback!");
1171 return;
1172 }
1173
1174 std::vector<int32_t> bitrateVec;
1175 if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES))) {
1176 uint8_t *addr = nullptr;
1177 size_t size = 0;
1178 infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES), &addr, size);
1179 CHECK_AND_RETURN_LOG(addr != nullptr, "bitrate addr is nullptr");
1180
1181 MEDIA_LOGI("bitrate size = %{public}zu", size / sizeof(uint32_t));
1182 while (size > 0) {
1183 if (size < sizeof(uint32_t)) {
1184 break;
1185 }
1186
1187 uint32_t bitrate = *(static_cast<uint32_t *>(static_cast<void *>(addr)));
1188 MEDIA_LOGI("bitrate = %{public}u", bitrate);
1189 addr += sizeof(uint32_t);
1190 size -= sizeof(uint32_t);
1191 bitrateVec.push_back(static_cast<int32_t>(bitrate));
1192 }
1193 }
1194
1195 NapiCallback::IntArray *cb = new(std::nothrow) NapiCallback::IntArray();
1196 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1197
1198 cb->callback = refMap_.at(AVPlayerEvent::EVENT_AVAILABLE_BITRATES);
1199 cb->callbackName = AVPlayerEvent::EVENT_AVAILABLE_BITRATES;
1200 cb->valueVec = bitrateVec;
1201 NapiCallback::CompleteCallback(env_, cb);
1202 }
1203
OnMaxAmplitudeCollectedCb(const int32_t extra,const Format & infoBody)1204 void AVPlayerCallback::OnMaxAmplitudeCollectedCb(const int32_t extra, const Format &infoBody)
1205 {
1206 (void)extra;
1207 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1208 if (refMap_.find(AVPlayerEvent::EVENT_AMPLITUDE_UPDATE) == refMap_.end()) {
1209 MEDIA_LOGD("can not find max amplitude collected callback!");
1210 return;
1211 }
1212
1213 std::vector<float> MaxAmplitudeVec;
1214 if (infoBody.ContainKey(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE))) {
1215 uint8_t *addr = nullptr;
1216 size_t size = 0;
1217 infoBody.GetBuffer(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE), &addr, size);
1218 CHECK_AND_RETURN_LOG(addr != nullptr, "max amplitude addr is nullptr");
1219
1220 MEDIA_LOGD("max amplitude size = %{public}zu", size / sizeof(float));
1221 while (size > 0) {
1222 if (size < sizeof(float)) {
1223 break;
1224 }
1225
1226 float maxAmplitude = *(static_cast<float *>(static_cast<void *>(addr)));
1227 MEDIA_LOGD("maxAmplitude = %{public}f", maxAmplitude);
1228 addr += sizeof(float);
1229 size -= sizeof(float);
1230 MaxAmplitudeVec.push_back(static_cast<float>(maxAmplitude));
1231 }
1232 }
1233
1234 NapiCallback::FloatArray *cb = new(std::nothrow) NapiCallback::FloatArray();
1235 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1236
1237 cb->callback = refMap_.at(AVPlayerEvent::EVENT_AMPLITUDE_UPDATE);
1238 cb->callbackName = AVPlayerEvent::EVENT_AMPLITUDE_UPDATE;
1239 cb->valueVec = MaxAmplitudeVec;
1240 NapiCallback::CompleteCallback(env_, cb);
1241 }
1242
OnSeiInfoCb(const int32_t extra,const Format & infoBody)1243 void AVPlayerCallback::OnSeiInfoCb(const int32_t extra, const Format &infoBody)
1244 {
1245 CHECK_AND_RETURN_LOG(
1246 refMap_.find(AVPlayerEvent::EVENT_SEI_MESSAGE_INFO) != refMap_.end(), "can not find on sei message callback!");
1247
1248 (void)extra;
1249 int32_t playbackPosition = 0;
1250 bool res = infoBody.GetIntValue(Tag::AV_PLAYER_SEI_PLAYBACK_POSITION, playbackPosition);
1251 CHECK_AND_RETURN_LOG(res, "get playback position failed");
1252
1253 std::vector<Format> formatVec;
1254 res = infoBody.GetFormatVector(Tag::AV_PLAYER_SEI_PLAYBACK_GROUP, formatVec);
1255 CHECK_AND_RETURN_LOG(res, "get sei payload group failed");
1256
1257 NapiCallback::SeiInfoUpadte *cb = new(std::nothrow) NapiCallback::SeiInfoUpadte();
1258 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1259
1260 cb->callback = refMap_.at(AVPlayerEvent::EVENT_SEI_MESSAGE_INFO);
1261 cb->callbackName = AVPlayerEvent::EVENT_SEI_MESSAGE_INFO;
1262 cb->playbackPosition = playbackPosition;
1263 cb->payloadGroup = formatVec;
1264 NapiCallback::CompleteCallback(env_, cb);
1265 }
1266
OnSuperResolutionChangedCb(const int32_t extra,const Format & infoBody)1267 void AVPlayerCallback::OnSuperResolutionChangedCb(const int32_t extra, const Format &infoBody)
1268 {
1269 (void)extra;
1270 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1271 int32_t enabled = 0;
1272 (void)infoBody.GetIntValue(PlayerKeys::SUPER_RESOLUTION_ENABLED, enabled);
1273 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSuperResolutionChangedCb is called, enabled = %{public}d",
1274 FAKE_POINTER(this), enabled);
1275
1276 if (refMap_.find(AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED) == refMap_.end()) {
1277 MEDIA_LOGW("can not find super resolution changed callback!");
1278 return;
1279 }
1280 NapiCallback::Bool *cb = new(std::nothrow) NapiCallback::Bool();
1281 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Bool");
1282
1283 cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED);
1284 cb->callbackName = AVPlayerEvent::EVENT_SUPER_RESOLUTION_CHANGED;
1285 cb->value = enabled ? true : false;
1286 NapiCallback::CompleteCallback(env_, cb);
1287 }
1288
SetDrmInfoData(const uint8_t * drmInfoAddr,int32_t infoCount,std::multimap<std::string,std::vector<uint8_t>> & drmInfoMap)1289 int32_t AVPlayerCallback::SetDrmInfoData(const uint8_t *drmInfoAddr, int32_t infoCount,
1290 std::multimap<std::string, std::vector<uint8_t>> &drmInfoMap)
1291 {
1292 DrmInfoItem *drmInfos = reinterpret_cast<DrmInfoItem*>(const_cast<uint8_t *>(drmInfoAddr));
1293 CHECK_AND_RETURN_RET_LOG(drmInfos != nullptr, MSERR_INVALID_VAL, "cast drmInfos nullptr");
1294 for (int32_t i = 0; i < infoCount; i++) {
1295 DrmInfoItem temp = drmInfos[i];
1296 std::stringstream ssConverter;
1297 std::string uuid;
1298 for (uint32_t index = 0; index < DrmConstant::DRM_MAX_M3U8_DRM_UUID_LEN; index++) {
1299 int32_t singleUuid = static_cast<int32_t>(temp.uuid[index]);
1300 ssConverter << std::hex << std::setfill('0') << std::setw(2) << singleUuid; // 2:w
1301 uuid = ssConverter.str();
1302 }
1303 std::vector<uint8_t> pssh(temp.pssh, temp.pssh + temp.psshLen);
1304 drmInfoMap.insert({ uuid, pssh });
1305 }
1306
1307 if (listener_ != nullptr) {
1308 listener_->NotifyDrmInfoUpdated(drmInfoMap);
1309 }
1310 return MSERR_OK;
1311 }
1312
OnDrmInfoUpdatedCb(const int32_t extra,const Format & infoBody)1313 void AVPlayerCallback::OnDrmInfoUpdatedCb(const int32_t extra, const Format &infoBody)
1314 {
1315 (void)extra;
1316 MEDIA_LOGI("AVPlayerCallback OnDrmInfoUpdatedCb is called");
1317 if (refMap_.find(AVPlayerEvent::EVENT_DRM_INFO_UPDATE) == refMap_.end()) {
1318 MEDIA_LOGW("can not find drm info updated callback!");
1319 return;
1320 }
1321 if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR))) {
1322 MEDIA_LOGW("there's no drminfo-update drm_info_addr key");
1323 return;
1324 }
1325 if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT))) {
1326 MEDIA_LOGW("there's no drminfo-update drm_info_count key");
1327 return;
1328 }
1329
1330 uint8_t *drmInfoAddr = nullptr;
1331 size_t size = 0;
1332 int32_t infoCount = 0;
1333 infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR), &drmInfoAddr, size);
1334 CHECK_AND_RETURN_LOG(drmInfoAddr != nullptr && size > 0, "get drminfo buffer failed");
1335 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT), infoCount);
1336 CHECK_AND_RETURN_LOG(infoCount > 0, "get drminfo count is illegal");
1337
1338 std::multimap<std::string, std::vector<uint8_t>> drmInfoMap;
1339 int32_t ret = SetDrmInfoData(drmInfoAddr, infoCount, drmInfoMap);
1340 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "SetDrmInfoData err");
1341 NapiCallback::ObjectArray *cb = new(std::nothrow) NapiCallback::ObjectArray();
1342 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new ObjectArray");
1343 cb->callback = refMap_.at(AVPlayerEvent::EVENT_DRM_INFO_UPDATE);
1344 cb->callbackName = AVPlayerEvent::EVENT_DRM_INFO_UPDATE;
1345 cb->infoMap = drmInfoMap;
1346 NapiCallback::CompleteCallback(env_, cb);
1347 }
1348
OnSetDecryptConfigDoneCb(const int32_t extra,const Format & infoBody)1349 void AVPlayerCallback::OnSetDecryptConfigDoneCb(const int32_t extra, const Format &infoBody)
1350 {
1351 (void)extra;
1352 MEDIA_LOGI("AVPlayerCallback OnSetDecryptConfigDoneCb is called");
1353 if (refMap_.find(AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE) == refMap_.end()) {
1354 MEDIA_LOGW("can not find SetDecryptConfig Done callback!");
1355 return;
1356 }
1357
1358 NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1359 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1360
1361 cb->callback = refMap_.at(AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE);
1362 cb->callbackName = AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE;
1363 NapiCallback::CompleteCallback(env_, cb);
1364 }
1365
OnSubtitleInfoCb(const int32_t extra,const Format & infoBody)1366 void AVPlayerCallback::OnSubtitleInfoCb(const int32_t extra, const Format &infoBody)
1367 {
1368 (void)infoBody;
1369 int32_t pts = -1;
1370 int32_t duration = -1;
1371 std::string text;
1372 infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, text);
1373 infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_PTS), pts);
1374 infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_DURATION), duration);
1375 MEDIA_LOGI("OnSubtitleInfoCb pts %{public}d, duration = %{public}d", pts, duration);
1376
1377 CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_UPDATE) != refMap_.end(),
1378 "can not find Subtitle callback!");
1379
1380 NapiCallback::SubtitleInfo *cb = new(std::nothrow) NapiCallback::SubtitleInfo();
1381 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Subtitle");
1382
1383 cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_UPDATE);
1384 cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_UPDATE;
1385 cb->valueMap.text = text;
1386 cb->valueMap.pts = pts;
1387 cb->valueMap.duration = duration;
1388
1389 NapiCallback::CompleteCallback(env_, cb);
1390 }
1391
OnEosCb(const int32_t extra,const Format & infoBody)1392 void AVPlayerCallback::OnEosCb(const int32_t extra, const Format &infoBody)
1393 {
1394 (void)infoBody;
1395 CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1396 int32_t isLooping = extra;
1397 MEDIA_LOGI("0x%{public}06" PRIXPTR " OnEndOfStream is called, isloop: %{public}d", FAKE_POINTER(this), isLooping);
1398 if (refMap_.find(AVPlayerEvent::EVENT_END_OF_STREAM) == refMap_.end()) {
1399 MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find EndOfStream callback!", FAKE_POINTER(this));
1400 return;
1401 }
1402
1403 NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1404 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1405
1406 cb->callback = refMap_.at(AVPlayerEvent::EVENT_END_OF_STREAM);
1407 cb->callbackName = AVPlayerEvent::EVENT_END_OF_STREAM;
1408 NapiCallback::CompleteCallback(env_, cb);
1409 }
1410
OnTrackChangedCb(const int32_t extra,const Format & infoBody)1411 void AVPlayerCallback::OnTrackChangedCb(const int32_t extra, const Format &infoBody)
1412 {
1413 (void)extra;
1414 int32_t index = -1;
1415 int32_t isSelect = -1;
1416 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_TRACK_INDEX), index);
1417 infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_IS_SELECT), isSelect);
1418 MEDIA_LOGI("OnTrackChangedCb index %{public}d, isSelect = %{public}d", index, isSelect);
1419
1420 CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACKCHANGE) != refMap_.end(),
1421 "can not find trackChange callback!");
1422
1423 NapiCallback::TrackChange *cb = new(std::nothrow) NapiCallback::TrackChange();
1424 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackChange");
1425
1426 cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACKCHANGE);
1427 cb->callbackName = AVPlayerEvent::EVENT_TRACKCHANGE;
1428 cb->number = index;
1429 cb->isSelect = isSelect ? true : false;
1430 NapiCallback::CompleteCallback(env_, cb);
1431 }
1432
OnTrackInfoUpdate(const int32_t extra,const Format & infoBody)1433 void AVPlayerCallback::OnTrackInfoUpdate(const int32_t extra, const Format &infoBody)
1434 {
1435 (void)extra;
1436 std::vector<Format> trackInfo;
1437 (void)infoBody.GetFormatVector(std::string(PlayerKeys::PLAYER_TRACK_INFO), trackInfo);
1438 MEDIA_LOGI("OnTrackInfoUpdate callback");
1439
1440 CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE) != refMap_.end(),
1441 "can not find trackInfoUpdate callback!");
1442
1443 NapiCallback::TrackInfoUpdate *cb = new(std::nothrow) NapiCallback::TrackInfoUpdate();
1444 CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackInfoUpdate");
1445
1446 cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE);
1447 cb->callbackName = AVPlayerEvent::EVENT_TRACK_INFO_UPDATE;
1448 cb->trackInfo = trackInfo;
1449 NapiCallback::CompleteCallback(env_, cb);
1450 }
1451
SaveCallbackReference(const std::string & name,std::weak_ptr<AutoRef> ref)1452 void AVPlayerCallback::SaveCallbackReference(const std::string &name, std::weak_ptr<AutoRef> ref)
1453 {
1454 std::lock_guard<std::mutex> lock(mutex_);
1455 refMap_[name] = ref;
1456 }
1457
ClearCallbackReference()1458 void AVPlayerCallback::ClearCallbackReference()
1459 {
1460 std::lock_guard<std::mutex> lock(mutex_);
1461 refMap_.clear();
1462 }
1463
ClearCallbackReference(const std::string & name)1464 void AVPlayerCallback::ClearCallbackReference(const std::string &name)
1465 {
1466 std::lock_guard<std::mutex> lock(mutex_);
1467 refMap_.erase(name);
1468 }
1469
Start()1470 void AVPlayerCallback::Start()
1471 {
1472 isloaded_ = true;
1473 }
1474
Pause()1475 void AVPlayerCallback::Pause()
1476 {
1477 isloaded_ = false;
1478 }
1479
Release()1480 void AVPlayerCallback::Release()
1481 {
1482 std::lock_guard<std::mutex> lock(mutex_);
1483
1484 Format infoBody;
1485 AVPlayerCallback::OnStateChangeCb(PlayerStates::PLAYER_RELEASED, infoBody);
1486 listener_ = nullptr;
1487 }
1488 } // namespace Media
1489 } // namespace OHOS
1490