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