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