1 /*
2  * Copyright (c) 2021 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 "core/components/video/resource/player.h"
17 
18 #include <iomanip>
19 #include <sstream>
20 
21 #include "base/log/log.h"
22 
23 namespace OHOS::Ace {
24 
25 const char PLAYER_PARAM_WIDTH[] = "width";
26 const char PLAYER_PARAM_HEIGHT[] = "height";
27 const char PLAYER_PARAM_DURATION[] = "duration";
28 const char PLAYER_PARAM_CURRENTPOS[] = "currentpos";
29 const char PLAYER_PARAM_ISPLAYING[] = "isplaying";
30 const char PLAYER_PARAM_SRC[] = "src";
31 const char PLAYER_PARAM_ISAUTOPLAY[] = "autoplay";
32 const char PLAYER_PARAM_ISMUTE[] = "mute";
33 const char PLAYER_PARAM_TEXTURE[] = "texture";
34 const char PLAYER_PARAM_NEEDFRESHFORCE[] = "needRefreshForce";
35 const char PLAYER_PARAM_LOOP[] = "loop";
36 const char PLAYER_PARAM_SEEKMODE[] = "seekMode";
37 const char PLAYER_PARAM_ISTEXTURE[] = "isTexture";
38 
39 const char PLAYER_METHOD_INIT[] = "init";
40 const char PLAYER_METHOD_GETPOSITION[] = "getposition";
41 const char PLAYER_METHOD_START[] = "start";
42 const char PLAYER_METHOD_PAUSE[] = "pause";
43 const char PLAYER_METHOD_SEEKTO[] = "seekto";
44 const char PLAYER_METHOD_STOP[] = "stop";
45 const char PLAYER_METHOD_SETVOLUME[] = "setvolume";
46 const char PLAYER_METHOD_FULLSCREEN[] = "fullscreen";
47 const char PLAYER_METHOD_ENABLE_LOOPING[] = "enablelooping";
48 const char PLAYER_METHOD_SETSPEED[] = "setspeed";
49 const char PLAYER_METHOD_SETDIRECTION[] = "setdirection";
50 const char PLAYER_METHOD_SETLANDSCAPE[] = "setlandscape";
51 const char PLAYER_METHOD_SETSURFACE[] = "setsurface";
52 const char PLAYER_METHOD_UPDATERESOURCE[] = "updateresource";
53 
54 const char PLAYER_EVENT_PREPARED[] = "prepared";
55 const char PLAYER_EVENT_COMPLETION[] = "completion";
56 const char PLAYER_EVENT_SEEKCOMPLETE[] = "seekcomplete";
57 const char PLAYER_EVENT_ONPLAYSTATUS[] = "onplaystatus";
58 const char PLAYER_EVENT_ONGETCURRENTTIME[] = "ongetcurrenttime";
59 
60 const char PLAYER_ERROR_CODE_CREATEFAIL[] = "error_video_000001";
61 const char PLAYER_ERROR_MSG_CREATEFAIL[] = "Create player failed.";
62 const char PLAYER_ERROR_CODE_FILEINVALID[] = "error_video_000002";
63 const char PLAYER_ERROR_MSG_FILEINVALID[] = "File invalid.";
64 const int32_t DURATION_THOUSAND = 1000;
65 
Create(const std::function<void (int64_t)> & onCreate)66 void Player::Create(const std::function<void(int64_t)>& onCreate)
67 {
68     scheduler_ = SchedulerBuilder::Build(
69         [weak = WeakClaim(this)](uint64_t timestamp) {
70             auto player = weak.Upgrade();
71             if (player) {
72                 player->OnTick(timestamp);
73             }
74         },
75         context_);
76     auto context = context_.Upgrade();
77     if (!context) {
78         LOGE("fail to get context to create player");
79         return;
80     }
81 
82     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
83 
84     platformTaskExecutor.PostTask([weak = WeakClaim(this), onCreate] {
85         auto player = weak.Upgrade();
86         if (player) {
87             player->CreatePlayer(onCreate);
88         }
89     }, "ArkUIVideoCreatePlayer");
90 }
91 
CreatePlayer(const std::function<void (int64_t)> & onCreate)92 void Player::CreatePlayer(const std::function<void(int64_t)>& onCreate)
93 {
94     auto context = context_.Upgrade();
95     if (!context) {
96         return;
97     }
98     auto resRegister = context->GetPlatformResRegister();
99     if (resRegister == nullptr) {
100         return;
101     }
102     std::stringstream paramStream;
103     paramStream << PLAYER_PARAM_TEXTURE << PARAM_EQUALS << textureId_;
104     std::string param = paramStream.str();
105     id_ = resRegister->CreateResource(type_, param);
106     if (id_ == INVALID_ID) {
107         if (onError_) {
108             onError_(PLAYER_ERROR_CODE_CREATEFAIL, PLAYER_ERROR_MSG_CREATEFAIL);
109         }
110         return;
111     }
112     hash_ = MakeResourceHash();
113     resRegister->RegisterEvent(
114         MakeEventHash(PLAYER_EVENT_PREPARED), [weak = WeakClaim(this)](const std::string& param) {
115             auto player = weak.Upgrade();
116             if (player) {
117                 player->OnPrepared(param);
118             }
119         });
120     resRegister->RegisterEvent(
121         MakeEventHash(PLAYER_EVENT_COMPLETION), [weak = WeakClaim(this)](const std::string& param) {
122             auto player = weak.Upgrade();
123             if (player) {
124                 player->OnCompletion(param);
125             }
126         });
127     resRegister->RegisterEvent(
128         MakeEventHash(PLAYER_EVENT_SEEKCOMPLETE), [weak = WeakClaim(this)](const std::string& param) {
129             auto player = weak.Upgrade();
130             if (player) {
131                 player->OnSeekComplete(param);
132             }
133         });
134     resRegister->RegisterEvent(
135         MakeEventHash(PLAYER_EVENT_ONPLAYSTATUS), [weak = WeakClaim(this)](const std::string& param) {
136             auto player = weak.Upgrade();
137             if (player) {
138                 player->OnPlayStatus(param);
139             }
140         });
141     resRegister->RegisterEvent(
142         MakeEventHash(PLAYER_EVENT_ONGETCURRENTTIME), [weak = WeakClaim(this)](const std::string& param) {
143             auto player = weak.Upgrade();
144             if (player) {
145                 player->OnTimeGetted(param);
146             }
147         });
148     if (onCreate) {
149         onCreate(id_);
150     }
151     InitPlay();
152 }
153 
InitPlay()154 void Player::InitPlay()
155 {
156     std::stringstream paramStream;
157     paramStream << PLAYER_PARAM_SRC << PARAM_EQUALS << src_ << PARAM_AND << PLAYER_PARAM_ISMUTE << PARAM_EQUALS
158                 << (isMute_ ? 1 : 0) << PARAM_AND << PLAYER_PARAM_ISAUTOPLAY << PARAM_EQUALS << (isAutoPlay_ ? 1 : 0);
159 
160     std::string param = paramStream.str();
161     CallResRegisterMethod(MakeMethodHash(PLAYER_METHOD_INIT), param, [weak = WeakClaim(this)](std::string& result) {
162         auto player = weak.Upgrade();
163         if (player) {
164             if (!player->IsResultSuccess(result)) {
165                 player->OnError(PLAYER_ERROR_CODE_FILEINVALID, PLAYER_ERROR_MSG_FILEINVALID);
166             }
167         }
168     });
169 
170     isInit_ = true;
171 }
172 
SetSource(const std::string & src)173 void Player::SetSource(const std::string& src)
174 {
175     src_ = src;
176     if (isInit_) {
177         std::stringstream paramStream;
178         paramStream << PLAYER_PARAM_SRC << PARAM_EQUALS << src_;
179         std::string param = paramStream.str();
180         CallResRegisterMethod(MakeMethodHash(PLAYER_METHOD_UPDATERESOURCE), param,
181             [weak = WeakClaim(this)](std::string& result) {
182                 auto player = weak.Upgrade();
183                 if (player) {
184                     if (!player->IsResultSuccess(result)) {
185                         player->OnError(PLAYER_ERROR_CODE_FILEINVALID, PLAYER_ERROR_MSG_FILEINVALID);
186                     }
187                 }
188             });
189     }
190 }
191 
SetSurfaceId(int64_t id,bool isTexture)192 void Player::SetSurfaceId(int64_t id, bool isTexture)
193 {
194     textureId_ = id;
195     std::stringstream paramStream;
196     paramStream << PARAM_VALUE << PARAM_EQUALS << textureId_ << PARAM_AND
197         << PLAYER_PARAM_ISTEXTURE << PARAM_EQUALS << (isTexture ? "1" : "0");
198     std::string param = paramStream.str();
199     CallResRegisterMethod(MakeMethodHash(PLAYER_METHOD_SETSURFACE), param);
200 }
201 
OnPrepared(const std::string & param)202 void Player::OnPrepared(const std::string& param)
203 {
204     currentPos_ = 0;
205     width_ = static_cast<uint32_t>(GetIntParam(param, PLAYER_PARAM_WIDTH));
206     height_ = static_cast<uint32_t>(GetIntParam(param, PLAYER_PARAM_HEIGHT));
207     duration_ = static_cast<uint32_t>(GetIntParam(param, PLAYER_PARAM_DURATION) / DURATION_THOUSAND);
208     isPlaying_ = GetIntParam(param, PLAYER_PARAM_ISPLAYING) == 1;
209     isNeedFreshForce_ = GetIntParam(param, PLAYER_PARAM_NEEDFRESHFORCE) == 1;
210     isPrepared_ = true;
211     if (width_ == 0 || height_ == 0 || duration_ == 0) {
212         if (onError_) {
213             onError_(PLAYER_ERROR_CODE_FILEINVALID, PLAYER_ERROR_MSG_FILEINVALID);
214         }
215         return;
216     }
217     getCurrentPosMethod_ = MakeMethodHash(PLAYER_METHOD_GETPOSITION);
218     playMethod_ = MakeMethodHash(PLAYER_METHOD_START);
219     pauseMethod_ = MakeMethodHash(PLAYER_METHOD_PAUSE);
220     seekMethod_ = MakeMethodHash(PLAYER_METHOD_SEEKTO);
221     stopMethod_ = MakeMethodHash(PLAYER_METHOD_STOP);
222     setVolumeMethod_ = MakeMethodHash(PLAYER_METHOD_SETVOLUME);
223     fullscreenMethod_ = MakeMethodHash(PLAYER_METHOD_FULLSCREEN);
224     enableloopingMethod_ = MakeMethodHash(PLAYER_METHOD_ENABLE_LOOPING);
225     setSpeedMethod_ = MakeMethodHash(PLAYER_METHOD_SETSPEED);
226     setDirectionMethod_ = MakeMethodHash(PLAYER_METHOD_SETDIRECTION);
227     setLandsacpeMethod_ = MakeMethodHash(PLAYER_METHOD_SETLANDSCAPE);
228 
229     if (isPlaying_) {
230         SetTickActive(true);
231     }
232 
233     for (const auto& listener : onPreparedListener_) {
234         listener(width_, height_, isPlaying_, duration_, currentPos_, true);
235     }
236 }
237 
OnCompletion(const std::string & param)238 void Player::OnCompletion(const std::string& param)
239 {
240     isPlaying_ = false;
241     currentPos_ = duration_;
242     SetTickActive(isPlaying_);
243     for (const auto& listener : onCompletionListener_) {
244         listener();
245     }
246 }
247 
OnSeekComplete(const std::string & param)248 void Player::OnSeekComplete(const std::string& param)
249 {
250     currentPos_ = static_cast<uint32_t>(GetIntParam(param, PLAYER_PARAM_CURRENTPOS));
251     if (!onCurrentPosListener_.empty()) {
252         onCurrentPosListener_.back()(currentPos_);
253     }
254 }
255 
OnPlayStatus(const std::string & param)256 void Player::OnPlayStatus(const std::string& param)
257 {
258     isPlaying_ = GetIntParam(param, PLAYER_PARAM_ISPLAYING) == 1;
259     SetTickActive(isPlaying_);
260     for (const auto& listener : onPlayStatusListener_) {
261         listener(isPlaying_);
262     }
263 }
264 
SetTickActive(bool isActive)265 void Player::SetTickActive(bool isActive)
266 {
267     auto context = context_.Upgrade();
268     if (!context) {
269         LOGE("fail to get context to set tick active");
270         return;
271     }
272 
273     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
274     uiTaskExecutor.PostSyncTask(
275         [this, isActive] {
276             if (scheduler_) {
277                 if (isActive) {
278                     scheduler_->Start();
279                 } else {
280                     scheduler_->Stop();
281                 }
282             }
283         },
284         "ArkUIVideoSetTickActive");
285 }
286 
OnTick(uint64_t timeStamp)287 void Player::OnTick(uint64_t timeStamp)
288 {
289     timeStamp_ += timeStamp;
290     if (isNeedFreshForce_) {
291         if (!onRefreshRenderListener_.empty()) {
292             onRefreshRenderListener_.back()();
293         }
294     }
295     if (timeStamp_ > FREAUENCY_GET_CURRENT_TIME) {
296         GetCurrentTime();
297         timeStamp_ -= FREAUENCY_GET_CURRENT_TIME;
298     }
299 }
300 
GetCurrentTime()301 void Player::GetCurrentTime()
302 {
303     CallResRegisterMethod(getCurrentPosMethod_, PARAM_NONE);
304 }
305 
OnTimeGetted(const std::string & result)306 void Player::OnTimeGetted(const std::string& result)
307 {
308     currentPos_ = static_cast<uint32_t>(GetIntParam(result, PLAYER_PARAM_CURRENTPOS));
309     if (!onCurrentPosListener_.empty()) {
310         onCurrentPosListener_.back()(currentPos_);
311     }
312 }
313 
Start()314 void Player::Start()
315 {
316     CallResRegisterMethod(playMethod_, PARAM_NONE, [weak = WeakClaim(this)](std::string& result) {
317         auto player = weak.Upgrade();
318         if (player) {
319             player->OnStarted();
320         }
321     });
322 }
323 
OnStarted()324 void Player::OnStarted()
325 {
326     isPlaying_ = true;
327     SetTickActive(isPlaying_);
328 
329     for (const auto& listener : onPlayStatusListener_) {
330         listener(isPlaying_);
331     }
332 }
333 
Pause()334 void Player::Pause()
335 {
336     CallResRegisterMethod(pauseMethod_, PARAM_NONE, [weak = WeakClaim(this)](std::string& result) {
337         auto player = weak.Upgrade();
338         if (player) {
339             player->OnPaused();
340         }
341     });
342 }
343 
OnPaused()344 void Player::OnPaused()
345 {
346     isPlaying_ = false;
347     SetTickActive(isPlaying_);
348 
349     for (const auto& listener : onPlayStatusListener_) {
350         listener(isPlaying_);
351     }
352 }
353 
Stop()354 void Player::Stop()
355 {
356     if (scheduler_) {
357         scheduler_->Stop();
358     }
359 
360     CallResRegisterMethod(stopMethod_, PARAM_NONE, [weak = WeakClaim(this)](std::string& result) {
361         LOGI("callback play OnStop.");
362         auto player = weak.Upgrade();
363         if (player) {
364             player->OnStop();
365         }
366     });
367 }
368 
OnStop()369 void Player::OnStop()
370 {
371     isPlaying_ = false;
372     currentPos_ = 0;
373     SetTickActive(isPlaying_);
374 
375     for (const auto& listener : onPlayStatusListener_) {
376         listener(isPlaying_);
377     }
378 }
379 
UnregisterEvent()380 void Player::UnregisterEvent()
381 {
382     auto context = context_.Upgrade();
383     if (!context) {
384         LOGE("fail to get context");
385         return;
386     }
387     auto resRegister = context->GetPlatformResRegister();
388     if (resRegister == nullptr) {
389         return;
390     }
391     resRegister->UnregisterEvent(MakeEventHash(PLAYER_EVENT_PREPARED));
392     resRegister->UnregisterEvent(MakeEventHash(PLAYER_EVENT_COMPLETION));
393     resRegister->UnregisterEvent(MakeEventHash(PLAYER_EVENT_SEEKCOMPLETE));
394     resRegister->UnregisterEvent(MakeEventHash(PLAYER_EVENT_ONPLAYSTATUS));
395 }
396 
EnterFullScreen()397 void Player::EnterFullScreen()
398 {
399     CallResRegisterMethod(fullscreenMethod_, PARAM_NONE);
400 }
401 
SeekTo(uint32_t pos)402 void Player::SeekTo(uint32_t pos)
403 {
404     std::stringstream paramStream;
405     paramStream << PARAM_VALUE << PARAM_EQUALS << pos;
406 
407     std::string param = paramStream.str();
408     CallResRegisterMethod(seekMethod_, param);
409 }
410 
SeekTo(uint32_t pos,uint32_t mode)411 void Player::SeekTo(uint32_t pos, uint32_t mode)
412 {
413     std::stringstream paramStream;
414     paramStream << PARAM_VALUE << PARAM_EQUALS << pos << PARAM_AND <<
415         PLAYER_PARAM_SEEKMODE << PARAM_EQUALS << mode;
416 
417     std::string param = paramStream.str();
418     CallResRegisterMethod(seekMethod_, param);
419 }
420 
SetVolume(float volume)421 void Player::SetVolume(float volume)
422 {
423     std::stringstream paramStream;
424     paramStream << PARAM_VALUE << PARAM_EQUALS << volume;
425 
426     std::string param = paramStream.str();
427     CallResRegisterMethod(setVolumeMethod_, param);
428 }
429 
AddPreparedListener(PreparedListener && listener)430 void Player::AddPreparedListener(PreparedListener&& listener)
431 {
432     auto context = context_.Upgrade();
433     if (!context) {
434         LOGE("fail to get context");
435         return;
436     }
437 
438     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
439     platformTaskExecutor.PostTask(
440         [weak = WeakClaim(this), listener = std::move(listener)]() mutable {
441             auto player = weak.Upgrade();
442             if (player) {
443                 player->OnAddPreparedListener(std::move(listener));
444             }
445         },
446         "ArkUIVideoAddPreparedListener");
447 }
448 
OnAddPreparedListener(PreparedListener && listener)449 void Player::OnAddPreparedListener(PreparedListener&& listener)
450 {
451     onPreparedListener_.push_back(std::move(listener));
452     if (isPrepared_) {
453         onPreparedListener_.back()(width_, height_, isPlaying_, duration_, currentPos_, false);
454     }
455 }
456 
AddPlayStatusListener(PlayStatusListener && listener)457 void Player::AddPlayStatusListener(PlayStatusListener&& listener)
458 {
459     auto context = context_.Upgrade();
460     if (!context) {
461         LOGE("fail to get context");
462         return;
463     }
464 
465     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
466     platformTaskExecutor.PostTask(
467         [weak = WeakClaim(this), listener = std::move(listener)]() mutable {
468             auto player = weak.Upgrade();
469             if (player) {
470                 player->OnAddPlayStatusListener(std::move(listener));
471             }
472         },
473         "ArkUIVideoAddPlayStatusListener");
474 }
475 
OnAddPlayStatusListener(PlayStatusListener && listener)476 void Player::OnAddPlayStatusListener(PlayStatusListener&& listener)
477 {
478     onPlayStatusListener_.push_back(std::move(listener));
479 }
480 
AddCurrentPosListener(CurrentPosListener && listener)481 void Player::AddCurrentPosListener(CurrentPosListener&& listener)
482 {
483     auto context = context_.Upgrade();
484     if (!context) {
485         LOGE("fail to get context");
486         return;
487     }
488 
489     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
490     platformTaskExecutor.PostTask(
491         [weak = WeakClaim(this), listener = std::move(listener)]() mutable {
492             auto player = weak.Upgrade();
493             if (player) {
494                 player->OnAddCurrentPosListener(std::move(listener));
495             }
496         },
497         "ArkUIVideoAddCurrentPosListener");
498 }
499 
OnAddCurrentPosListener(CurrentPosListener && listener)500 void Player::OnAddCurrentPosListener(CurrentPosListener&& listener)
501 {
502     onCurrentPosListener_.push_back(std::move(listener));
503 }
504 
AddCompletionListener(CompletionListener && listener)505 void Player::AddCompletionListener(CompletionListener&& listener)
506 {
507     auto context = context_.Upgrade();
508     if (!context) {
509         LOGE("fail to get context");
510         return;
511     }
512 
513     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
514     platformTaskExecutor.PostTask(
515         [weak = WeakClaim(this), listener = std::move(listener)]() mutable {
516             auto player = weak.Upgrade();
517             if (player) {
518                 player->OnAddCompletionListener(std::move(listener));
519             }
520         },
521         "ArkUIVideoAddCompletionListener");
522 }
523 
OnAddCompletionListener(CompletionListener && listener)524 void Player::OnAddCompletionListener(CompletionListener&& listener)
525 {
526     onCompletionListener_.push_back(std::move(listener));
527 }
528 
PopListener()529 void Player::PopListener()
530 {
531     onRefreshRenderListener_.pop_back();
532     auto context = context_.Upgrade();
533     if (!context) {
534         LOGE("fail to get context");
535         return;
536     }
537 
538     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
539     platformTaskExecutor.PostTask(
540         [weak = WeakClaim(this)] {
541             auto player = weak.Upgrade();
542             if (player) {
543                 player->OnPopListener();
544             }
545         },
546         "ArkUIVideoPopListener");
547 }
548 
AddRefreshRenderListener(RefreshRenderListener && listener)549 void Player::AddRefreshRenderListener(RefreshRenderListener&& listener)
550 {
551     onRefreshRenderListener_.push_back(std::move(listener));
552 }
553 
EnableLooping(bool loop)554 void Player::EnableLooping(bool loop)
555 {
556     std::stringstream paramStream;
557     paramStream << PLAYER_PARAM_LOOP << PARAM_EQUALS << (loop ? "1" : "0");
558 
559     std::string param = paramStream.str();
560     CallResRegisterMethod(enableloopingMethod_, param);
561 }
562 
SetSpeed(float speed)563 void Player::SetSpeed(float speed)
564 {
565     std::stringstream paramStream;
566     paramStream << PARAM_VALUE << PARAM_EQUALS << speed;
567 
568     std::string param = paramStream.str();
569     CallResRegisterMethod(setSpeedMethod_, param);
570 }
571 
SetDirection(std::string & direction)572 void Player::SetDirection(std::string& direction)
573 {
574     std::stringstream paramStream;
575     paramStream << PARAM_VALUE << PARAM_EQUALS << direction;
576 
577     std::string param = paramStream.str();
578     CallResRegisterMethod(setDirectionMethod_, param);
579 }
580 
SetLandscape()581 void Player::SetLandscape()
582 {
583     CallResRegisterMethod(setLandsacpeMethod_, PARAM_NONE);
584 }
585 
OnPopListener()586 void Player::OnPopListener()
587 {
588     onPreparedListener_.pop_back();
589     onPlayStatusListener_.pop_back();
590     onCurrentPosListener_.pop_back();
591     onCompletionListener_.pop_back();
592     if (!onCurrentPosListener_.empty()) {
593         onCurrentPosListener_.back()(currentPos_);
594     }
595 }
596 
SetFullScreenChange(bool isFullScreen)597 void Player::SetFullScreenChange(bool isFullScreen)
598 {
599     std::stringstream paramStream;
600     paramStream << PARAM_VALUE << PARAM_EQUALS << (isFullScreen ? "1" : "0");
601 
602     std::string param = paramStream.str();
603     CallResRegisterMethod(fullscreenMethod_, param);
604 }
605 
Release(const std::function<void (bool)> & onRelease)606 void Player::Release(const std::function<void(bool)>& onRelease)
607 {
608     // The destructor will be executed at platform thread, so destroy scheduler at here.
609     if (scheduler_) {
610         scheduler_.Reset();
611     }
612 
613     auto context = context_.Upgrade();
614     if (!context) {
615         LOGE("fail to get context");
616         return;
617     }
618     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
619     if (platformTaskExecutor.IsRunOnCurrentThread()) {
620         UnregisterEvent();
621     } else {
622         platformTaskExecutor.PostTask(
623             [weak = WeakClaim(this)] {
624                 auto player = weak.Upgrade();
625                 if (player) {
626                     player->UnregisterEvent();
627                 }
628             },
629             "ArkUIVideoPlayerUnregisterEvent");
630     }
631 
632     Resource::Release(onRelease);
633 
634     isInit_ = false;
635 }
636 } // namespace OHOS::Ace