1 /*
2 * Copyright (c) 2024 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 "native_media_player_impl.h"
17
18 #include "napi_common_macros.h"
19 #include "napi_native_media_player.h"
20 #include "napi_parse_utils.h"
21 #include "nweb_log.h"
22
23 namespace OHOS::NWeb {
24
NWebNativeMediaPlayerBridgeImpl(int32_t nwebId,napi_env env,napi_value value)25 NWebNativeMediaPlayerBridgeImpl::NWebNativeMediaPlayerBridgeImpl(int32_t nwebId, napi_env env, napi_value value)
26 : nwebId_(nwebId), env_(env), value_(value)
27 {}
28
UpdateRect(double x,double y,double width,double height)29 void NWebNativeMediaPlayerBridgeImpl::UpdateRect(double x, double y, double width, double height)
30 {
31 WVLOG_D("begin to update rect,nweb id is %{public}d", nwebId_);
32
33 napi_value callback = nullptr;
34 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "updateRect", callback);
35
36 napi_value argv[INTEGER_FOUR] = { nullptr };
37 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, x, &argv[INTEGER_ZERO]));
38 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, y, &argv[INTEGER_ONE]));
39 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, width, &argv[INTEGER_TWO]));
40 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, height, &argv[INTEGER_THREE]));
41
42 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_FOUR, argv, nullptr));
43 }
44
Play()45 void NWebNativeMediaPlayerBridgeImpl::Play()
46 {
47 WVLOG_D("begin to play,nweb id is %{public}d", nwebId_);
48
49 napi_value callback = nullptr;
50 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "play", callback);
51
52 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ZERO, nullptr, nullptr));
53 }
54
Pause()55 void NWebNativeMediaPlayerBridgeImpl::Pause()
56 {
57 WVLOG_D("begin to pause,nweb id is %{public}d", nwebId_);
58
59 napi_value callback = nullptr;
60 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "pause", callback);
61
62 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ZERO, nullptr, nullptr));
63 }
64
Seek(double time)65 void NWebNativeMediaPlayerBridgeImpl::Seek(double time)
66 {
67 WVLOG_D("begin to seek,nweb id is %{public}d,time is %{public}f", nwebId_, time);
68
69 napi_value callback = nullptr;
70 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "seek", callback);
71
72 napi_value argv[INTEGER_ONE] = { nullptr };
73 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, time, &argv[INTEGER_ZERO]));
74
75 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ONE, argv, nullptr));
76 }
77
SetVolume(double volume)78 void NWebNativeMediaPlayerBridgeImpl::SetVolume(double volume)
79 {
80 WVLOG_D("begin to set volume,nweb id is %{public}d,volume is %{public}f", nwebId_, volume);
81
82 napi_value callback = nullptr;
83 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "setVolume", callback);
84
85 napi_value argv[INTEGER_ONE] = { nullptr };
86 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, volume, &argv[INTEGER_ZERO]));
87
88 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ONE, argv, nullptr));
89 }
90
SetMuted(bool isMuted)91 void NWebNativeMediaPlayerBridgeImpl::SetMuted(bool isMuted)
92 {
93 WVLOG_D("begin to set muted,nweb id is %{public}d,muted flag is %{public}d", nwebId_, isMuted);
94
95 napi_value callback = nullptr;
96 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "setMuted", callback);
97
98 napi_value argv[INTEGER_ONE] = { nullptr };
99 NAPI_CALL_RETURN_VOID(env_, napi_get_boolean(env_, isMuted, &argv[INTEGER_ZERO]));
100
101 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ONE, argv, nullptr));
102 }
103
SetPlaybackRate(double playbackRate)104 void NWebNativeMediaPlayerBridgeImpl::SetPlaybackRate(double playbackRate)
105 {
106 WVLOG_D("begin to set playback rate,nweb id is %{public}d,playback rate is %{public}f", nwebId_, playbackRate);
107
108 napi_value callback = nullptr;
109 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "setPlaybackRate", callback);
110
111 napi_value argv[INTEGER_ONE] = { nullptr };
112 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, playbackRate, &argv[INTEGER_ZERO]));
113
114 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ONE, argv, nullptr));
115 }
116
Release()117 void NWebNativeMediaPlayerBridgeImpl::Release()
118 {
119 WVLOG_D("begin to release,nweb id is %{public}d", nwebId_);
120
121 napi_value callback = nullptr;
122 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "release", callback);
123
124 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ZERO, nullptr, nullptr));
125 }
126
EnterFullScreen()127 void NWebNativeMediaPlayerBridgeImpl::EnterFullScreen()
128 {
129 WVLOG_D("begin to enter full screen,nweb id is %{public}d", nwebId_);
130
131 napi_value callback = nullptr;
132 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "enterFullscreen", callback);
133
134 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ZERO, nullptr, nullptr));
135 }
136
ExitFullScreen()137 void NWebNativeMediaPlayerBridgeImpl::ExitFullScreen()
138 {
139 WVLOG_D("begin to exit full screen,nweb id is %{public}d", nwebId_);
140
141 napi_value callback = nullptr;
142 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "exitFullscreen", callback);
143
144 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ZERO, nullptr, nullptr));
145 }
146
ResumeMediaPlayer()147 void NWebNativeMediaPlayerBridgeImpl::ResumeMediaPlayer()
148 {
149 WVLOG_D("begin to resume media player,nweb id is %{public}d", nwebId_);
150
151 napi_value callback = nullptr;
152 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "resumePlayer", callback);
153
154 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ZERO, nullptr, nullptr));
155 }
156
SuspendMediaPlayer(SuspendType type)157 void NWebNativeMediaPlayerBridgeImpl::SuspendMediaPlayer(SuspendType type)
158 {
159 WVLOG_D("begin to suspend media player,nweb id is %{public}d", nwebId_);
160
161 napi_value callback = nullptr;
162 NAPI_GET_CALLBACK_RETURN_VOID(env_, value_, "suspendPlayer", callback);
163
164 napi_value argv[INTEGER_ONE] = { nullptr };
165 NAPI_CALL_RETURN_VOID(env_, napi_create_int32(env_, static_cast<int>(type), &argv[INTEGER_ZERO]));
166
167 NAPI_CALL_RETURN_VOID(env_, napi_call_function(env_, value_, callback, INTEGER_ONE, argv, nullptr));
168 }
169
NWebCreateNativeMediaPlayerCallbackImpl(int32_t nwebId,napi_env env,napi_ref callback)170 NWebCreateNativeMediaPlayerCallbackImpl::NWebCreateNativeMediaPlayerCallbackImpl(
171 int32_t nwebId, napi_env env, napi_ref callback)
172 : nwebId_(nwebId), env_(env), callback_(callback)
173 {}
174
~NWebCreateNativeMediaPlayerCallbackImpl()175 NWebCreateNativeMediaPlayerCallbackImpl::~NWebCreateNativeMediaPlayerCallbackImpl()
176 {
177 napi_delete_reference(env_, callback_);
178 }
179
OnCreate(std::shared_ptr<NWebNativeMediaPlayerHandler> handler,std::shared_ptr<NWebMediaInfo> mediaInfo)180 std::shared_ptr<NWebNativeMediaPlayerBridge> NWebCreateNativeMediaPlayerCallbackImpl::OnCreate(
181 std::shared_ptr<NWebNativeMediaPlayerHandler> handler, std::shared_ptr<NWebMediaInfo> mediaInfo)
182 {
183 WVLOG_D("begin to create native media player,nweb id is %{public}d", nwebId_);
184
185 if (!callback_) {
186 WVLOG_E("callback is null,nweb id is %{public}d", nwebId_);
187 return nullptr;
188 }
189
190 if (!handler || !mediaInfo) {
191 WVLOG_E("param is null,nweb id is %{public}d", nwebId_);
192 return nullptr;
193 }
194
195 napi_value callback = nullptr;
196 napi_get_reference_value(env_, callback_, &callback);
197 if (callback == nullptr) {
198 WVLOG_E("failed to get callback func,nweb id is %{public}d", nwebId_);
199 return nullptr;
200 }
201
202 napi_value argv[INTEGER_TWO] = { nullptr };
203 ConstructHandler(&argv[INTEGER_ZERO], handler);
204 ConstructMediaInfo(&argv[INTEGER_ONE], mediaInfo);
205
206 napi_value result = nullptr;
207 NAPI_CALL(env_, napi_call_function(env_, nullptr, callback, INTEGER_TWO, argv, &result));
208
209 napi_valuetype valueType = napi_undefined;
210 napi_typeof(env_, result, &valueType);
211 if (valueType != napi_object) {
212 WVLOG_E("result type is invalid,nweb id is %{public}d", nwebId_);
213 return nullptr;
214 }
215
216 return std::make_shared<NWebNativeMediaPlayerBridgeImpl>(nwebId_, env_, result);
217 }
218
ConstructRect(napi_value * value,std::shared_ptr<NWebNativeMediaPlayerSurfaceInfo> surfaceInfo)219 void NWebCreateNativeMediaPlayerCallbackImpl::ConstructRect(
220 napi_value* value, std::shared_ptr<NWebNativeMediaPlayerSurfaceInfo> surfaceInfo)
221 {
222 NAPI_CALL_RETURN_VOID(env_, napi_create_object(env_, value));
223
224 napi_value x = nullptr;
225 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, surfaceInfo->GetX(), &x));
226 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "x", x));
227
228 napi_value y = nullptr;
229 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, surfaceInfo->GetY(), &y));
230 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "y", y));
231
232 napi_value width = nullptr;
233 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, surfaceInfo->GetWidth(), &width));
234 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "width", width));
235
236 napi_value height = nullptr;
237 NAPI_CALL_RETURN_VOID(env_, napi_create_double(env_, surfaceInfo->GetHeight(), &height));
238 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "height", height));
239 }
240
ConstructHandler(napi_value * value,std::shared_ptr<NWebNativeMediaPlayerHandler> handler)241 void NWebCreateNativeMediaPlayerCallbackImpl::ConstructHandler(
242 napi_value* value, std::shared_ptr<NWebNativeMediaPlayerHandler> handler)
243 {
244 NAPI_CALL_RETURN_VOID(env_, napi_create_object(env_, value));
245
246 napi_wrap(
247 env_, *value, new NapiNativeMediaPlayerHandlerImpl(nwebId_, handler),
248 [](napi_env /*env*/, void* data, void* /*hint*/) {
249 NapiNativeMediaPlayerHandlerImpl* handler = (NapiNativeMediaPlayerHandlerImpl*)data;
250 delete handler;
251 },
252 nullptr, nullptr);
253 NAPI_CALL_RETURN_VOID(env_, NapiNativeMediaPlayerHandler::DefineProperties(env_, value));
254 }
255
ConstructControls(napi_value * value,const std::vector<std::string> & controls)256 void NWebCreateNativeMediaPlayerCallbackImpl::ConstructControls(
257 napi_value* value, const std::vector<std::string>& controls)
258 {
259 NAPI_CALL_RETURN_VOID(env_, napi_create_array_with_length(env_, controls.size(), value));
260
261 for (unsigned int i = 0; i < controls.size(); i++) {
262 napi_value control = nullptr;
263 NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(
264 env_, controls[i].c_str(), controls[i].length(), &control));
265 NAPI_CALL_RETURN_VOID(env_, napi_set_element(env_, *value, i, control));
266 }
267 }
268
ConstructHeaders(napi_value * value,const std::map<std::string,std::string> & headers)269 void NWebCreateNativeMediaPlayerCallbackImpl::ConstructHeaders(
270 napi_value* value, const std::map<std::string, std::string>& headers)
271 {
272 NAPI_CALL_RETURN_VOID(env_, napi_create_object(env_, value));
273
274 for (const auto& header : headers) {
275 napi_value argv = nullptr;
276 NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(
277 env_, header.second.c_str(), header.second.length(), &argv));
278 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, header.first.c_str(), argv));
279 }
280 }
281
ConstructAttributes(napi_value * value,const std::map<std::string,std::string> & attributes)282 void NWebCreateNativeMediaPlayerCallbackImpl::ConstructAttributes(
283 napi_value* value, const std::map<std::string, std::string>& attributes)
284 {
285 NAPI_CALL_RETURN_VOID(env_, napi_create_object(env_, value));
286
287 for (const auto& attribute : attributes) {
288 napi_value argv = nullptr;
289 NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(
290 env_, attribute.second.c_str(), attribute.second.length(), &argv));
291 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, attribute.first.c_str(), argv));
292 }
293 }
294
ConstructMediaInfo(napi_value * value,std::shared_ptr<NWebMediaInfo> mediaInfo)295 void NWebCreateNativeMediaPlayerCallbackImpl::ConstructMediaInfo(
296 napi_value* value, std::shared_ptr<NWebMediaInfo> mediaInfo)
297 {
298 NAPI_CALL_RETURN_VOID(env_, napi_create_object(env_, value));
299
300 napi_value embedId = nullptr;
301 std::string id = mediaInfo->GetEmbedId();
302 NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(env_, id.c_str(), id.length(), &embedId));
303 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "embedID", embedId));
304
305 napi_value mediaType = nullptr;
306 NAPI_CALL_RETURN_VOID(env_, napi_create_int32(env_, static_cast<int>(mediaInfo->GetMediaType()), &mediaType));
307 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "mediaType", mediaType));
308
309 napi_value mediaSrcList = nullptr;
310 ConstructSourceInfos(&mediaSrcList, mediaInfo->GetSourceInfos());
311 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "mediaSrcList", mediaSrcList));
312
313 napi_value surfaceInfo = nullptr;
314 ConstructSurfaceInfo(&surfaceInfo, mediaInfo->GetSurfaceInfo());
315 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "surfaceInfo", surfaceInfo));
316
317 napi_value isControlsShown = nullptr;
318 NAPI_CALL_RETURN_VOID(env_, napi_get_boolean(env_, mediaInfo->GetIsControlsShown(), &isControlsShown));
319 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "controlsShown", isControlsShown));
320
321 napi_value controlList = nullptr;
322 ConstructControls(&controlList, mediaInfo->GetControls());
323 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "controlList", controlList));
324
325 napi_value headers = nullptr;
326 ConstructHeaders(&headers, mediaInfo->GetHeaders());
327 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "headers", headers));
328
329 napi_value attributes = nullptr;
330 ConstructAttributes(&attributes, mediaInfo->GetAttributes());
331 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "attributes", attributes));
332
333 napi_value isMuted = nullptr;
334 NAPI_CALL_RETURN_VOID(env_, napi_get_boolean(env_, mediaInfo->GetIsMuted(), &isMuted));
335 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "muted", isMuted));
336
337 napi_value posterUrl = nullptr;
338 std::string url = mediaInfo->GetPosterUrl();
339 NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(env_, url.c_str(), url.length(), &posterUrl));
340 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "posterUrl", posterUrl));
341
342 napi_value preload = nullptr;
343 NAPI_CALL_RETURN_VOID(env_, napi_create_int32(env_, static_cast<int>(mediaInfo->GetPreload()), &preload));
344 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "preload", preload));
345 }
346
ConstructSourceInfos(napi_value * value,const std::vector<std::shared_ptr<NWebMediaSourceInfo>> & sourceInfos)347 void NWebCreateNativeMediaPlayerCallbackImpl::ConstructSourceInfos(
348 napi_value* value, const std::vector<std::shared_ptr<NWebMediaSourceInfo>>& sourceInfos)
349 {
350 NAPI_CALL_RETURN_VOID(env_, napi_create_array_with_length(env_, sourceInfos.size(), value));
351
352 for (unsigned int i = 0; i < sourceInfos.size(); i++) {
353 if (!sourceInfos[i]) {
354 continue;
355 }
356
357 napi_value sourceInfo = nullptr;
358 NAPI_CALL_RETURN_VOID(env_, napi_create_object(env_, &sourceInfo));
359
360 napi_value type = nullptr;
361 NAPI_CALL_RETURN_VOID(env_, napi_create_int32(env_, static_cast<int>(sourceInfos[i]->GetType()), &type));
362 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, sourceInfo, "type", type));
363
364 napi_value source = nullptr;
365 std::string mediaSource = sourceInfos[i]->GetSource();
366 NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(env_, mediaSource.c_str(), mediaSource.length(), &source));
367 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, sourceInfo, "source", source));
368
369 napi_value format = nullptr;
370 std::string mediaFormat = sourceInfos[i]->GetFormat();
371 NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(env_, mediaFormat.c_str(), mediaFormat.length(), &format));
372 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, sourceInfo, "format", format));
373
374 NAPI_CALL_RETURN_VOID(env_, napi_set_element(env_, *value, i, sourceInfo));
375 }
376 }
377
ConstructSurfaceInfo(napi_value * value,std::shared_ptr<NWebNativeMediaPlayerSurfaceInfo> surfaceInfo)378 void NWebCreateNativeMediaPlayerCallbackImpl::ConstructSurfaceInfo(
379 napi_value* value, std::shared_ptr<NWebNativeMediaPlayerSurfaceInfo> surfaceInfo)
380 {
381 NAPI_CALL_RETURN_VOID(env_, napi_create_object(env_, value));
382
383 if (!surfaceInfo) {
384 return;
385 }
386
387 napi_value surfaceId = nullptr;
388 std::string id = surfaceInfo->GetId();
389 NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(env_, id.c_str(), id.length(), &surfaceId));
390 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "id", surfaceId));
391
392 napi_value rect = nullptr;
393 ConstructRect(&rect, surfaceInfo);
394 NAPI_CALL_RETURN_VOID(env_, napi_set_named_property(env_, *value, "rect", rect));
395 }
396
397 } // namespace OHOS::NWeb
398