• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "frameworks/bridge/declarative_frontend/jsview/js_video.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "bridge/declarative_frontend/jsview/js_video_controller.h"
20 #include "bridge/declarative_frontend/jsview/models/video_model_impl.h"
21 #include "core/components_ng/pattern/video/video_model_ng.h"
22 
23 namespace OHOS::Ace {
24 
25 std::unique_ptr<VideoModel> VideoModel::instance_ = nullptr;
26 
GetInstance()27 VideoModel* VideoModel::GetInstance()
28 {
29     if (!instance_) {
30 #ifdef NG_BUILD
31         instance_.reset(new NG::VideoModelNG());
32 #else
33         if (Container::IsCurrentUseNewPipeline()) {
34             instance_.reset(new NG::VideoModelNG());
35         } else {
36             instance_.reset(new Framework::VideoModelImpl());
37         }
38 #endif
39     }
40     return instance_.get();
41 }
42 
43 } // namespace OHOS::Ace
44 
45 namespace OHOS::Ace::Framework {
46 
Create(const JSCallbackInfo & info)47 void JSVideo::Create(const JSCallbackInfo& info)
48 {
49     if (info.Length() <= 0 || !info[0]->IsObject()) {
50         LOGE("JSVideo: info is invalid.");
51         return;
52     }
53     JSRef<JSObject> videoObj = JSRef<JSObject>::Cast(info[0]);
54     JSRef<JSVal> srcValue = videoObj->GetProperty("src");
55     JSRef<JSVal> previewUriValue = videoObj->GetProperty("previewUri");
56     JSRef<JSVal> currentProgressRateValue = videoObj->GetProperty("currentProgressRate");
57 
58     auto controllerObj = videoObj->GetProperty("controller");
59     RefPtr<VideoControllerV2> videoController = nullptr;
60     if (controllerObj->IsObject()) {
61         auto* jsVideoController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSVideoController>();
62         if (jsVideoController) {
63             videoController = jsVideoController->GetController();
64         }
65     }
66     VideoModel::GetInstance()->Create(videoController);
67 
68     // Parse the src, if it is invalid, use the empty string.
69     std::string videoSrc;
70     if (!ParseJsMedia(srcValue, videoSrc)) {
71         LOGW("Video parse src failed.");
72     }
73     VideoModel::GetInstance()->SetSrc(videoSrc);
74 
75     // Parse the rate, if it is invalid, set it as 1.0.
76     double currentProgressRate = 1.0;
77     if (ParseJsDouble(currentProgressRateValue, currentProgressRate)) {
78         LOGW("Video parse currentProgressRate failed.");
79     }
80     VideoModel::GetInstance()->SetProgressRate(currentProgressRate);
81 
82     std::string previewUri;
83     if (previewUriValue->IsUndefined() || previewUriValue->IsNull()) {
84         // When it is undefined, just set the empty image.
85         LOGW("Video parse previewUri failed, it is null.");
86         VideoModel::GetInstance()->SetPosterSourceInfo(previewUri);
87         return;
88     }
89     auto noPixMap = ParseJsMedia(previewUriValue, previewUri);
90     if (noPixMap) {
91         // Src is a string or resource
92         VideoModel::GetInstance()->SetPosterSourceInfo(previewUri);
93     } else {
94         // Src is a pixelmap.
95         LOGE("can not support pixel map");
96     }
97 }
98 
JsMuted(const JSCallbackInfo & info)99 void JSVideo::JsMuted(const JSCallbackInfo& info)
100 {
101     bool muted = false;
102     if (info[0]->IsBoolean()) {
103         muted = info[0]->ToBoolean();
104     }
105     VideoModel::GetInstance()->SetMuted(muted);
106 }
107 
JsAutoPlay(const JSCallbackInfo & info)108 void JSVideo::JsAutoPlay(const JSCallbackInfo& info)
109 {
110     bool autoPlay = false;
111     if (info[0]->IsBoolean()) {
112         autoPlay = info[0]->ToBoolean();
113     }
114     VideoModel::GetInstance()->SetAutoPlay(autoPlay);
115 }
116 
JsControls(const JSCallbackInfo & info)117 void JSVideo::JsControls(const JSCallbackInfo& info)
118 {
119     bool controls = true;
120     if (info[0]->IsBoolean()) {
121         controls = info[0]->ToBoolean();
122     }
123     VideoModel::GetInstance()->SetControls(controls);
124 }
125 
JsLoop(const JSCallbackInfo & info)126 void JSVideo::JsLoop(const JSCallbackInfo& info)
127 {
128     bool loop = false;
129     if (info[0]->IsBoolean()) {
130         loop = info[0]->ToBoolean();
131     }
132     VideoModel::GetInstance()->SetLoop(loop);
133 }
134 
JsObjectFit(const JSCallbackInfo & info)135 void JSVideo::JsObjectFit(const JSCallbackInfo& info)
136 {
137     ImageFit imageFit = ImageFit::COVER;
138     // The default value of Imagefit is FILL, but in the video the default value is COVER.
139     // So the default value need to be converted.
140     if (info[0]->IsUndefined()) {
141         LOGW("JSVideo: objectfit is undefined.");
142         VideoModel::GetInstance()->SetObjectFit(imageFit);
143         return;
144     }
145     if (info[0]->IsNumber()) {
146         imageFit = static_cast<ImageFit>(info[0]->ToNumber<int>());
147     }
148     VideoModel::GetInstance()->SetObjectFit(imageFit);
149 }
150 
JsOnStart(const JSCallbackInfo & args)151 void JSVideo::JsOnStart(const JSCallbackInfo& args)
152 {
153     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
154     auto onStart = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
155         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
156         ACE_SCORING_EVENT("Video.onStart");
157         std::vector<std::string> keys = { "start" };
158         func->Execute(keys, param);
159     };
160     VideoModel::GetInstance()->SetOnStart(std::move(onStart));
161 }
162 
JsOnPause(const JSCallbackInfo & args)163 void JSVideo::JsOnPause(const JSCallbackInfo& args)
164 {
165     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
166     auto onPause = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
167         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
168         ACE_SCORING_EVENT("Video.onPause");
169         std::vector<std::string> keys = { "pause" };
170         func->Execute(keys, param);
171     };
172     VideoModel::GetInstance()->SetOnPause(std::move(onPause));
173 }
174 
JsOnFinish(const JSCallbackInfo & args)175 void JSVideo::JsOnFinish(const JSCallbackInfo& args)
176 {
177     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
178     auto onFinish = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
179         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
180         ACE_SCORING_EVENT("Video.onFinish");
181         std::vector<std::string> keys = { "finish" };
182         func->Execute(keys, param);
183     };
184     VideoModel::GetInstance()->SetOnFinish(std::move(onFinish));
185 }
186 
JsOnFullscreenChange(const JSCallbackInfo & args)187 void JSVideo::JsOnFullscreenChange(const JSCallbackInfo& args)
188 {
189     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
190     auto OnFullScreenChange = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](
191                                   const std::string& param) {
192         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
193         ACE_SCORING_EVENT("Video.OnFullScreenChange");
194         std::vector<std::string> keys = { "fullscreen" };
195         func->Execute(keys, param);
196     };
197     VideoModel::GetInstance()->SetOnFullScreenChange(std::move(OnFullScreenChange));
198 }
199 
JsOnPrepared(const JSCallbackInfo & args)200 void JSVideo::JsOnPrepared(const JSCallbackInfo& args)
201 {
202     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
203     auto onPrepared = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
204         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
205         ACE_SCORING_EVENT("Video.onPrepared");
206         std::vector<std::string> keys = { "duration" };
207         func->Execute(keys, param);
208     };
209     VideoModel::GetInstance()->SetOnPrepared(std::move(onPrepared));
210 }
211 
JsOnSeeking(const JSCallbackInfo & args)212 void JSVideo::JsOnSeeking(const JSCallbackInfo& args)
213 {
214     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
215     auto onSeeking = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
216         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
217         ACE_SCORING_EVENT("Video.onSeeking");
218         std::vector<std::string> keys = { "time" };
219         func->Execute(keys, param);
220     };
221     VideoModel::GetInstance()->SetOnSeeking(std::move(onSeeking));
222 }
223 
JsOnSeeked(const JSCallbackInfo & args)224 void JSVideo::JsOnSeeked(const JSCallbackInfo& args)
225 {
226     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
227     auto onSeeked = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
228         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
229         ACE_SCORING_EVENT("Video.onSeeked");
230         std::vector<std::string> keys = { "time" };
231         func->Execute(keys, param);
232     };
233     VideoModel::GetInstance()->SetOnSeeked(std::move(onSeeked));
234 }
235 
JsOnUpdate(const JSCallbackInfo & args)236 void JSVideo::JsOnUpdate(const JSCallbackInfo& args)
237 {
238     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
239     auto onUpdate = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
240         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
241         ACE_SCORING_EVENT("Video.onUpdate");
242         std::vector<std::string> keys = { "time" };
243         func->Execute(keys, param);
244     };
245     VideoModel::GetInstance()->SetOnUpdate(std::move(onUpdate));
246 }
247 
JsOnError(const JSCallbackInfo & args)248 void JSVideo::JsOnError(const JSCallbackInfo& args)
249 {
250     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
251     auto onError = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
252         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
253         ACE_SCORING_EVENT("Video.onError");
254         std::vector<std::string> keys = { "error" };
255         func->Execute(keys, param);
256     };
257     VideoModel::GetInstance()->SetOnError(std::move(onError));
258 }
259 
GetEventMarker(const JSCallbackInfo & info,const std::vector<std::string> & keys)260 EventMarker JSVideo::GetEventMarker(const JSCallbackInfo& info, const std::vector<std::string>& keys)
261 {
262     if (!info[0]->IsFunction()) {
263         LOGE("info[0] is not a function.");
264         return EventMarker();
265     }
266 
267     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
268     auto eventMarker =
269         EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys](const std::string& param) {
270             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
271             func->Execute(keys, param);
272         });
273     return eventMarker;
274 }
275 
JSBind(BindingTarget globalObj)276 void JSVideo::JSBind(BindingTarget globalObj)
277 {
278     JSClass<JSVideo>::Declare("Video");
279     MethodOptions opt = MethodOptions::NONE;
280     JSClass<JSVideo>::StaticMethod("create", &JSVideo::Create, opt);
281     JSClass<JSVideo>::StaticMethod("muted", &JSVideo::JsMuted, opt);
282     JSClass<JSVideo>::StaticMethod("autoPlay", &JSVideo::JsAutoPlay, opt);
283     JSClass<JSVideo>::StaticMethod("controls", &JSVideo::JsControls, opt);
284     JSClass<JSVideo>::StaticMethod("loop", &JSVideo::JsLoop, opt);
285     JSClass<JSVideo>::StaticMethod("objectFit", &JSVideo::JsObjectFit, opt);
286 
287     JSClass<JSVideo>::StaticMethod("onStart", &JSVideo::JsOnStart);
288     JSClass<JSVideo>::StaticMethod("onPause", &JSVideo::JsOnPause);
289     JSClass<JSVideo>::StaticMethod("onFinish", &JSVideo::JsOnFinish);
290     JSClass<JSVideo>::StaticMethod("onFullscreenChange", &JSVideo::JsOnFullscreenChange);
291     JSClass<JSVideo>::StaticMethod("onPrepared", &JSVideo::JsOnPrepared);
292     JSClass<JSVideo>::StaticMethod("onSeeking", &JSVideo::JsOnSeeking);
293     JSClass<JSVideo>::StaticMethod("onSeeked", &JSVideo::JsOnSeeked);
294     JSClass<JSVideo>::StaticMethod("onUpdate", &JSVideo::JsOnUpdate);
295     JSClass<JSVideo>::StaticMethod("onError", &JSVideo::JsOnError);
296 
297     JSClass<JSVideo>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
298     JSClass<JSVideo>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
299     JSClass<JSVideo>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
300     JSClass<JSVideo>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
301     JSClass<JSVideo>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
302     JSClass<JSVideo>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
303     JSClass<JSVideo>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
304     JSClass<JSVideo>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
305 
306     JSClass<JSVideo>::Inherit<JSViewAbstract>();
307     // override method
308     JSClass<JSVideo>::StaticMethod("opacity", &JSViewAbstract::JsOpacityPassThrough);
309     JSClass<JSVideo>::StaticMethod("transition", &JSViewAbstract::JsTransitionPassThrough);
310     JSClass<JSVideo>::Bind<>(globalObj);
311 }
312 
313 } // namespace OHOS::Ace::Framework
314