• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "movingphoto_napi.h"
17 
18 #include "ext_napi_utils.h"
19 #include "movingphoto_model_ng.h"
20 
21 extern const char _binary_multimedia_movingphotoview_js_start[];
22 extern const char _binary_multimedia_movingphotoview_abc_start[];
23 #if !defined(IOS_PLATFORM)
24 extern const char _binary_multimedia_movingphotoview_js_end[];
25 extern const char _binary_multimedia_movingphotoview_abc_end[];
26 #else
27 extern const char* _binary_multimedia_movingphotoview_js_end;
28 extern const char* _binary_multimedia_movingphotoview_abc_end;
29 #endif
30 
31 namespace OHOS::Ace {
32 namespace {
33 static constexpr size_t MAX_ARG_NUM = 10;
34 static constexpr int32_t ARG_NUM_ONE = 1;
35 static constexpr int32_t ARG_NUM_TWO = 2;
36 static constexpr int32_t PARAM_INDEX_ZERO = 0;
37 static constexpr int32_t PARAM_INDEX_ONE = 1;
38 } // namespace
39 
40 std::unique_ptr<NG::MovingPhotoModelNG> NG::MovingPhotoModelNG::instance_ = nullptr;
41 std::mutex NG::MovingPhotoModelNG::mutex_;
42 
GetInstance()43 NG::MovingPhotoModelNG* NG::MovingPhotoModelNG::GetInstance()
44 {
45     if (!instance_) {
46         std::lock_guard<std::mutex> lock(mutex_);
47         if (!instance_) {
48             instance_.reset(new NG::MovingPhotoModelNG());
49         }
50     }
51     return instance_.get();
52 }
53 
JsCreate(napi_env env,napi_callback_info info)54 napi_value JsCreate(napi_env env, napi_callback_info info)
55 {
56     size_t argc = MAX_ARG_NUM;
57     napi_value argv[MAX_ARG_NUM] = { nullptr };
58     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
59     NAPI_ASSERT(env, argc >= ARG_NUM_ONE, "Wrong number of arguments");
60 
61     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_object)) {
62         return ExtNapiUtils::CreateNull(env);
63     }
64 
65     napi_value jsController = nullptr;
66     NG::MovingPhotoController* controller = nullptr;
67     napi_get_named_property(env, argv[0], "controller", &jsController);
68     if (ExtNapiUtils::CheckTypeForNapiValue(env, jsController, napi_object)) {
69         napi_unwrap(env, jsController, (void**)&controller);
70     }
71     NG::MovingPhotoModelNG::GetInstance()->Create(Referenced::Claim(controller));
72 
73     napi_value jsData = nullptr;
74     napi_get_named_property(env, argv[0], "movingPhoto", &jsData);
75     if (!ExtNapiUtils::CheckTypeForNapiValue(env, jsData, napi_object)) {
76         return ExtNapiUtils::CreateNull(env);
77     }
78 
79     napi_value jsImageAIOptions = nullptr;
80     napi_get_named_property(env, argv[0], "imageAIOptions", &jsImageAIOptions);
81     NG::MovingPhotoModelNG::GetInstance()->SetImageAIOptions(jsImageAIOptions);
82 
83     napi_value jsMovingPhotoFormat = nullptr;
84     napi_get_named_property(env, argv[0], "movingPhotoFormat", &jsMovingPhotoFormat);
85     auto format = MovingPhotoFormat::UNKNOWN;
86     if (ExtNapiUtils::CheckTypeForNapiValue(env, jsMovingPhotoFormat, napi_number)) {
87         format = static_cast<MovingPhotoFormat>(ExtNapiUtils::GetCInt32(env, jsMovingPhotoFormat));
88         NG::MovingPhotoModelNG::GetInstance()->SetMovingPhotoFormat(format);
89     }
90 
91     napi_value jsDynamicRangeMode = nullptr;
92     napi_get_named_property(env, argv[0], "dynamicRangeMode", &jsDynamicRangeMode);
93     auto rangeMode = DynamicRangeMode::HIGH;
94     if (ExtNapiUtils::CheckTypeForNapiValue(env, jsDynamicRangeMode, napi_number)) {
95         rangeMode = static_cast<DynamicRangeMode>(ExtNapiUtils::GetCInt32(env, jsDynamicRangeMode));
96         NG::MovingPhotoModelNG::GetInstance()->SetDynamicRangeMode(rangeMode);
97     }
98 
99     napi_value getUri = nullptr;
100     napi_get_named_property(env, jsData, "getUri", &getUri);
101     if (!ExtNapiUtils::CheckTypeForNapiValue(env, getUri, napi_function)) {
102         return ExtNapiUtils::CreateNull(env);
103     }
104     napi_value imageUri;
105     napi_call_function(env, jsData, getUri, 0, nullptr, &imageUri);
106     std::string imageUriStr = ExtNapiUtils::GetStringFromValueUtf8(env, imageUri);
107     NG::MovingPhotoModelNG::GetInstance()->SetImageSrc(imageUriStr);
108 
109     return ExtNapiUtils::CreateNull(env);
110 }
111 
JsMuted(napi_env env,napi_callback_info info)112 napi_value JsMuted(napi_env env, napi_callback_info info)
113 {
114     size_t argc = MAX_ARG_NUM;
115     napi_value argv[MAX_ARG_NUM] = { nullptr };
116     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
117     NAPI_ASSERT(env, argc >= ARG_NUM_ONE, "Wrong number of arguments");
118 
119     bool muted = false;
120     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_boolean)) {
121         muted = ExtNapiUtils::GetBool(env, argv[0]);
122     }
123     NG::MovingPhotoModelNG::GetInstance()->SetMuted(muted);
124 
125     return ExtNapiUtils::CreateNull(env);
126 }
127 
JsObjectFit(napi_env env,napi_callback_info info)128 napi_value JsObjectFit(napi_env env, napi_callback_info info)
129 {
130     size_t argc = MAX_ARG_NUM;
131     napi_value argv[MAX_ARG_NUM] = { nullptr };
132     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
133     NAPI_ASSERT(env, argc >= ARG_NUM_ONE, "Wrong number of arguments");
134 
135     auto objectFit = ImageFit::COVER;
136     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_number)) {
137         objectFit = static_cast<ImageFit>(ExtNapiUtils::GetCInt32(env, argv[0]));
138     }
139     NG::MovingPhotoModelNG::GetInstance()->SetObjectFit(objectFit);
140 
141     return ExtNapiUtils::CreateNull(env);
142 }
143 
JsOnComplete(napi_env env,napi_callback_info info)144 napi_value JsOnComplete(napi_env env, napi_callback_info info)
145 {
146     size_t argc = MAX_ARG_NUM;
147     napi_value thisVal = nullptr;
148     napi_value argv[MAX_ARG_NUM] = { nullptr };
149     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
150     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
151     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
152         return ExtNapiUtils::CreateNull(env);
153     }
154     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
155     auto onComplete = [asyncEvent]() {
156         asyncEvent->Call(0, nullptr);
157     };
158     NG::MovingPhotoModelNG::GetInstance()->SetOnComplete(std::move(onComplete));
159     return ExtNapiUtils::CreateNull(env);
160 }
161 
JsOnStart(napi_env env,napi_callback_info info)162 napi_value JsOnStart(napi_env env, napi_callback_info info)
163 {
164     size_t argc = MAX_ARG_NUM;
165     napi_value thisVal = nullptr;
166     napi_value argv[MAX_ARG_NUM] = { nullptr };
167     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
168     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
169     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
170         return ExtNapiUtils::CreateNull(env);
171     }
172     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
173     auto onStart = [asyncEvent]() {
174         asyncEvent->Call(0, nullptr);
175     };
176     NG::MovingPhotoModelNG::GetInstance()->SetOnStart(std::move(onStart));
177     return ExtNapiUtils::CreateNull(env);
178 }
179 
JsOnStop(napi_env env,napi_callback_info info)180 napi_value JsOnStop(napi_env env, napi_callback_info info)
181 {
182     size_t argc = MAX_ARG_NUM;
183     napi_value thisVal = nullptr;
184     napi_value argv[MAX_ARG_NUM] = { nullptr };
185     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
186     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
187     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
188         return ExtNapiUtils::CreateNull(env);
189     }
190     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
191     auto onStop = [asyncEvent]() {
192         asyncEvent->Call(0, nullptr);
193     };
194     NG::MovingPhotoModelNG::GetInstance()->SetOnStop(std::move(onStop));
195     return ExtNapiUtils::CreateNull(env);
196 }
197 
JsOnPause(napi_env env,napi_callback_info info)198 napi_value JsOnPause(napi_env env, napi_callback_info info)
199 {
200     size_t argc = MAX_ARG_NUM;
201     napi_value thisVal = nullptr;
202     napi_value argv[MAX_ARG_NUM] = { nullptr };
203     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
204     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
205     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
206         return ExtNapiUtils::CreateNull(env);
207     }
208     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
209     auto onPause = [asyncEvent]() {
210         asyncEvent->Call(0, nullptr);
211     };
212     NG::MovingPhotoModelNG::GetInstance()->SetOnPause(std::move(onPause));
213     return ExtNapiUtils::CreateNull(env);
214 }
215 
JsOnFinish(napi_env env,napi_callback_info info)216 napi_value JsOnFinish(napi_env env, napi_callback_info info)
217 {
218     size_t argc = MAX_ARG_NUM;
219     napi_value thisVal = nullptr;
220     napi_value argv[MAX_ARG_NUM] = { nullptr };
221     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
222     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
223     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
224         return ExtNapiUtils::CreateNull(env);
225     }
226     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
227     auto onFinish = [asyncEvent]() {
228         asyncEvent->Call(0, nullptr);
229     };
230     NG::MovingPhotoModelNG::GetInstance()->SetOnFinish(std::move(onFinish));
231     return ExtNapiUtils::CreateNull(env);
232 }
233 
JsOnError(napi_env env,napi_callback_info info)234 napi_value JsOnError(napi_env env, napi_callback_info info)
235 {
236     size_t argc = MAX_ARG_NUM;
237     napi_value thisVal = nullptr;
238     napi_value argv[MAX_ARG_NUM] = { nullptr };
239     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
240     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
241     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
242         return ExtNapiUtils::CreateNull(env);
243     }
244     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
245     auto onError = [asyncEvent]() {
246         asyncEvent->Call(0, nullptr);
247     };
248     NG::MovingPhotoModelNG::GetInstance()->SetOnError(std::move(onError));
249     return ExtNapiUtils::CreateNull(env);
250 }
251 
InitView(napi_env env,napi_value exports)252 napi_value InitView(napi_env env, napi_value exports)
253 {
254     static napi_property_descriptor desc[] = {
255         DECLARE_NAPI_FUNCTION("create", JsCreate),
256         DECLARE_NAPI_FUNCTION("muted", JsMuted),
257         DECLARE_NAPI_FUNCTION("objectFit", JsObjectFit),
258         DECLARE_NAPI_FUNCTION("onComplete", JsOnComplete),
259         DECLARE_NAPI_FUNCTION("onStart", JsOnStart),
260         DECLARE_NAPI_FUNCTION("onStop", JsOnStop),
261         DECLARE_NAPI_FUNCTION("onPause", JsOnPause),
262         DECLARE_NAPI_FUNCTION("onFinish", JsOnFinish),
263         DECLARE_NAPI_FUNCTION("onError", JsOnError),
264         DECLARE_NAPI_FUNCTION("autoPlayPeriod", JsAutoPlayPeriod),
265         DECLARE_NAPI_FUNCTION("autoPlay", JsAutoPlay),
266         DECLARE_NAPI_FUNCTION("repeatPlay", JsRepeatPlay),
267         DECLARE_NAPI_FUNCTION("enableAnalyzer", JsEnableAnalyzer),
268     };
269     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
270     return exports;
271 }
272 
StartPlayback(napi_env env,napi_callback_info info)273 napi_value StartPlayback(napi_env env, napi_callback_info info)
274 {
275     napi_value thisVar = nullptr;
276     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL));
277     NG::MovingPhotoController* controller = nullptr;
278     napi_unwrap(env, thisVar, (void**)&controller);
279     if (controller == nullptr) {
280         return ExtNapiUtils::CreateNull(env);
281     }
282     controller->StartPlayback();
283     return ExtNapiUtils::CreateNull(env);
284 }
285 
StopPlayback(napi_env env,napi_callback_info info)286 napi_value StopPlayback(napi_env env, napi_callback_info info)
287 {
288     napi_value thisVar = nullptr;
289     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL));
290     NG::MovingPhotoController* controller = nullptr;
291     napi_unwrap(env, thisVar, (void**)&controller);
292     if (controller == nullptr) {
293         return ExtNapiUtils::CreateNull(env);
294     }
295     controller->StopPlayback();
296     return ExtNapiUtils::CreateNull(env);
297 }
298 
RefreshMovingPhoto(napi_env env,napi_callback_info info)299 napi_value RefreshMovingPhoto(napi_env env, napi_callback_info info)
300 {
301     napi_value thisVar = nullptr;
302     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL));
303     NG::MovingPhotoController* controller = nullptr;
304     napi_unwrap(env, thisVar, (void**)&controller);
305     if (controller == nullptr) {
306         return ExtNapiUtils::CreateNull(env);
307     }
308     controller->RefreshMovingPhoto();
309     return ExtNapiUtils::CreateNull(env);
310 }
311 
MovingPhotoControllerConstructor(napi_env env,napi_callback_info info)312 napi_value MovingPhotoControllerConstructor(napi_env env, napi_callback_info info)
313 {
314     napi_value thisVar = nullptr;
315     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
316     auto controller = AceType::MakeRefPtr<NG::MovingPhotoController>();
317     if (controller == nullptr) {
318         return ExtNapiUtils::CreateNull(env);
319     }
320     controller->IncRefCount();
321     napi_wrap(
322         env, thisVar, AceType::RawPtr(controller),
323         [](napi_env env, void* data, void* hint) {
324             auto* controller = reinterpret_cast<NG::MovingPhotoController*>(data);
325             controller->DecRefCount();
326         },
327         nullptr, nullptr);
328     return thisVar;
329 }
330 
InitController(napi_env env,napi_value exports)331 napi_value InitController(napi_env env, napi_value exports)
332 {
333     napi_value movingphotoControllerClass = nullptr;
334     napi_property_descriptor properties[] = {
335         DECLARE_NAPI_FUNCTION("startPlayback", StartPlayback),
336         DECLARE_NAPI_FUNCTION("stopPlayback", StopPlayback),
337         DECLARE_NAPI_FUNCTION("refreshMovingPhoto", RefreshMovingPhoto),
338     };
339     NAPI_CALL(env, napi_define_class(env, "MovingPhotoViewController", NAPI_AUTO_LENGTH,
340         MovingPhotoControllerConstructor, nullptr, sizeof(properties) / sizeof(*properties), properties,
341         &movingphotoControllerClass));
342     NAPI_CALL(env, napi_set_named_property(env, exports, "MovingPhotoViewController", movingphotoControllerClass));
343     return exports;
344 }
345 
ExportMovingPhoto(napi_env env,napi_value exports)346 napi_value ExportMovingPhoto(napi_env env, napi_value exports)
347 {
348     InitView(env, exports);
349     InitController(env, exports);
350     return exports;
351 }
352 
JsAutoPlayPeriod(napi_env env,napi_callback_info info)353 napi_value JsAutoPlayPeriod(napi_env env, napi_callback_info info)
354 {
355     size_t argc = MAX_ARG_NUM;
356     napi_value argv[MAX_ARG_NUM] = { nullptr };
357     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
358     NAPI_ASSERT(env, argc >= ARG_NUM_TWO, "Wrong number of arguments");
359 
360     int64_t startTime = 0;
361     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ZERO], napi_number)) {
362         startTime = ExtNapiUtils::GetCInt64(env, argv[PARAM_INDEX_ZERO]);
363     }
364     int64_t endTime = 0;
365     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ONE], napi_number)) {
366         endTime = ExtNapiUtils::GetCInt64(env, argv[PARAM_INDEX_ONE]);
367     }
368     NG::MovingPhotoModelNG::GetInstance()->AutoPlayPeriod(startTime, endTime);
369 
370     return ExtNapiUtils::CreateNull(env);
371 }
372 
JsAutoPlay(napi_env env,napi_callback_info info)373 napi_value JsAutoPlay(napi_env env, napi_callback_info info)
374 {
375     size_t argc = MAX_ARG_NUM;
376     napi_value argv[MAX_ARG_NUM] = { nullptr };
377     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
378     NAPI_ASSERT(env, argc >= ARG_NUM_ONE, "Wrong number of arguments");
379 
380     bool isAutoPlay = false;
381     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ZERO], napi_boolean)) {
382         isAutoPlay = ExtNapiUtils::GetBool(env, argv[PARAM_INDEX_ZERO]);
383     }
384     NG::MovingPhotoModelNG::GetInstance()->AutoPlay(isAutoPlay);
385 
386     return ExtNapiUtils::CreateNull(env);
387 }
388 
JsEnableAnalyzer(napi_env env,napi_callback_info info)389 napi_value JsEnableAnalyzer(napi_env env, napi_callback_info info)
390 {
391     size_t argc = MAX_ARG_NUM;
392     napi_value argv[MAX_ARG_NUM] = { nullptr };
393     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
394     NAPI_ASSERT(env, argc >= ARG_NUM_ONE, "Wrong number of arguments");
395 
396     bool enabled = false;
397     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ZERO], napi_boolean)) {
398         enabled = ExtNapiUtils::GetBool(env, argv[PARAM_INDEX_ZERO]);
399     }
400     NG::MovingPhotoModelNG::GetInstance()->EnableAnalyzer(enabled);
401 
402     return ExtNapiUtils::CreateNull(env);
403 }
404 
JsRepeatPlay(napi_env env,napi_callback_info info)405 napi_value JsRepeatPlay(napi_env env, napi_callback_info info)
406 {
407     size_t argc = MAX_ARG_NUM;
408     napi_value argv[MAX_ARG_NUM] = { nullptr };
409     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
410     NAPI_ASSERT(env, argc >= ARG_NUM_ONE, "Wrong number of arguments");
411 
412     bool isRepeatPlay = false;
413     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ZERO], napi_boolean)) {
414         isRepeatPlay = ExtNapiUtils::GetBool(env, argv[PARAM_INDEX_ZERO]);
415     }
416     NG::MovingPhotoModelNG::GetInstance()->RepeatPlay(isRepeatPlay);
417 
418     return ExtNapiUtils::CreateNull(env);
419 }
420 
421 } // namespace OHOS::Ace
422 
NAPI_multimedia_movingphotoview_GetJSCode(const char ** buf,int * bufLen)423 extern "C" __attribute__((visibility("default"))) void NAPI_multimedia_movingphotoview_GetJSCode(
424     const char** buf, int* bufLen)
425 {
426     if (buf != nullptr) {
427         *buf = _binary_multimedia_movingphotoview_js_start;
428     }
429 
430     if (bufLen != nullptr) {
431         *bufLen = _binary_multimedia_movingphotoview_js_end - _binary_multimedia_movingphotoview_js_start;
432     }
433 }
434 
435 // multimedia_movingphotoview JS register
NAPI_multimedia_movingphotoview_GetABCCode(const char ** buf,int * buflen)436 extern "C" __attribute__((visibility("default"))) void NAPI_multimedia_movingphotoview_GetABCCode(
437     const char** buf, int* buflen)
438 {
439     if (buf != nullptr) {
440         *buf = _binary_multimedia_movingphotoview_abc_start;
441     }
442     if (buflen != nullptr) {
443         *buflen = _binary_multimedia_movingphotoview_abc_end - _binary_multimedia_movingphotoview_abc_start;
444     }
445 }
446 
447 static napi_module movingphotoModule  = {
448     .nm_version = 1,
449     .nm_flags = 0,
450     .nm_filename = nullptr,
451     .nm_register_func = OHOS::Ace::ExportMovingPhoto,
452     .nm_modname = "multimedia.movingphotoview",
453     .nm_priv = ((void*)0),
454     .reserved = { 0 },
455 };
456 
RegisterModuleMovingPhoto()457 extern "C" __attribute__((constructor)) void RegisterModuleMovingPhoto()
458 {
459     napi_module_register(&movingphotoModule);
460 }
461