• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <climits>
17 #include "avrecorder_callback.h"
18 #include "media_dfx.h"
19 #include "media_log.h"
20 #include "media_errors.h"
21 #include "scope_guard.h"
22 #include "common_napi.h"
23 #include "surface_utils.h"
24 #include "string_ex.h"
25 #include "avcodec_info.h"
26 #include "av_common.h"
27 #ifdef SUPPORT_JSSTACK
28 #include "xpower_event_js.h"
29 #endif
30 #include "avrecorder_napi.h"
31 
32 namespace {
33     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVRecorderNapi"};
34 }
35 
36 namespace OHOS {
37 namespace Media {
38 thread_local napi_ref AVRecorderNapi::constructor_ = nullptr;
39 const std::string CLASS_NAME = "AVRecorder";
40 std::map<std::string, AVRecorderNapi::AvRecorderTaskqFunc> AVRecorderNapi::taskQFuncs_ = {
41     {AVRecordergOpt::GETINPUTSURFACE, &AVRecorderNapi::GetInputSurface},
42     {AVRecordergOpt::START, &AVRecorderNapi::Start},
43     {AVRecordergOpt::PAUSE, &AVRecorderNapi::Pause},
44     {AVRecordergOpt::RESUME, &AVRecorderNapi::Resume},
45     {AVRecordergOpt::STOP, &AVRecorderNapi::Stop},
46     {AVRecordergOpt::RESET, &AVRecorderNapi::Reset},
47     {AVRecordergOpt::RELEASE, &AVRecorderNapi::Release},
48 };
49 
AVRecorderNapi()50 AVRecorderNapi::AVRecorderNapi()
51 {
52     MEDIA_LOGI("0x%{public}06" PRIXPTR "Instances create", FAKE_POINTER(this));
53 }
54 
~AVRecorderNapi()55 AVRecorderNapi::~AVRecorderNapi()
56 {
57     MEDIA_LOGI("0x%{public}06" PRIXPTR "Instances destroy", FAKE_POINTER(this));
58 }
59 
Init(napi_env env,napi_value exports)60 napi_value AVRecorderNapi::Init(napi_env env, napi_value exports)
61 {
62     napi_property_descriptor staticProperty[] = {
63         DECLARE_NAPI_STATIC_FUNCTION("createAVRecorder", JsCreateAVRecorder),
64     };
65 
66     napi_property_descriptor properties[] = {
67         DECLARE_NAPI_FUNCTION("prepare", JsPrepare),
68         DECLARE_NAPI_FUNCTION("getInputSurface", JsGetInputSurface),
69         DECLARE_NAPI_FUNCTION("start", JsStart),
70         DECLARE_NAPI_FUNCTION("pause", JsPause),
71         DECLARE_NAPI_FUNCTION("resume", JsResume),
72         DECLARE_NAPI_FUNCTION("stop", JsStop),
73         DECLARE_NAPI_FUNCTION("reset", JsReset),
74         DECLARE_NAPI_FUNCTION("release", JsRelease),
75         DECLARE_NAPI_FUNCTION("on", JsSetEventCallback),
76         DECLARE_NAPI_FUNCTION("off", JsCancelEventCallback),
77         DECLARE_NAPI_FUNCTION("getAVRecorderProfile", JsGetAVRecorderProfile),
78         DECLARE_NAPI_FUNCTION("setAVRecorderConfig", JsSetAVRecorderConfig),
79 
80         DECLARE_NAPI_GETTER("state", JsGetState),
81     };
82 
83     napi_value constructor = nullptr;
84     napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr,
85                                            sizeof(properties) / sizeof(properties[0]), properties, &constructor);
86     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define AVRecorder class");
87 
88     status = napi_create_reference(env, constructor, 1, &constructor_);
89     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to create reference of constructor");
90 
91     status = napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor);
92     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to set constructor");
93 
94     status = napi_define_properties(env, exports, sizeof(staticProperty) / sizeof(staticProperty[0]), staticProperty);
95     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "Failed to define static function");
96 
97     MEDIA_LOGI("Init success");
98     return exports;
99 }
100 
Constructor(napi_env env,napi_callback_info info)101 napi_value AVRecorderNapi::Constructor(napi_env env, napi_callback_info info)
102 {
103     MediaTrace trace("AVRecorder::Constructor");
104     napi_value result = nullptr;
105     napi_get_undefined(env, &result);
106 
107     size_t argCount = 0;
108     napi_value jsThis = nullptr;
109     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
110     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "failed to napi_get_cb_info");
111 
112     AVRecorderNapi *jsRecorder = new(std::nothrow) AVRecorderNapi();
113     CHECK_AND_RETURN_RET_LOG(jsRecorder != nullptr, result, "failed to new AVRecorderNapi");
114 
115     jsRecorder->env_ = env;
116     jsRecorder->recorder_ = RecorderFactory::CreateRecorder();
117     CHECK_AND_RETURN_RET_LOG(jsRecorder->recorder_ != nullptr, result, "failed to CreateRecorder");
118 
119     jsRecorder->taskQue_ = std::make_unique<TaskQueue>("AVRecorderNapi");
120     (void)jsRecorder->taskQue_->Start();
121 
122     jsRecorder->recorderCb_ = std::make_shared<AVRecorderCallback>(env);
123     CHECK_AND_RETURN_RET_LOG(jsRecorder->recorderCb_ != nullptr, result, "failed to CreateRecorderCb");
124     (void)jsRecorder->recorder_->SetRecorderCallback(jsRecorder->recorderCb_);
125 
126     status = napi_wrap(env, jsThis, reinterpret_cast<void *>(jsRecorder),
127                        AVRecorderNapi::Destructor, nullptr, nullptr);
128     if (status != napi_ok) {
129         delete jsRecorder;
130         MEDIA_LOGE("Failed to wrap native instance");
131         return result;
132     }
133 
134     MEDIA_LOGI("Constructor success");
135     return jsThis;
136 }
137 
Destructor(napi_env env,void * nativeObject,void * finalize)138 void AVRecorderNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
139 {
140     MediaTrace trace("AVRecorder::Destructor");
141     (void)finalize;
142     if (nativeObject != nullptr) {
143         AVRecorderNapi *napi = reinterpret_cast<AVRecorderNapi *>(nativeObject);
144         if (napi->taskQue_ != nullptr) {
145             (void)napi->taskQue_->Stop();
146         }
147 
148         napi->RemoveSurface();
149         napi->recorderCb_ = nullptr;
150 
151         if (napi->recorder_) {
152             napi->recorder_->Release();
153             napi->recorder_ = nullptr;
154         }
155 
156         delete napi;
157     }
158     MEDIA_LOGI("Destructor success");
159 }
160 
JsCreateAVRecorder(napi_env env,napi_callback_info info)161 napi_value AVRecorderNapi::JsCreateAVRecorder(napi_env env, napi_callback_info info)
162 {
163     MediaTrace trace("AVRecorder::JsCreateAVRecorder");
164     napi_value result = nullptr;
165     napi_get_undefined(env, &result);
166 
167     // get args
168     napi_value jsThis = nullptr;
169     napi_value args[1] = { nullptr };
170     size_t argCount = 1;
171     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
172     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "failed to napi_get_cb_info");
173 
174     std::unique_ptr<AVRecorderAsyncContext> asyncCtx = std::make_unique<AVRecorderAsyncContext>(env);
175     CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get AsyncContext");
176 
177     asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[0]);
178     asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
179     asyncCtx->JsResult = std::make_unique<MediaJsResultInstance>(constructor_);
180     asyncCtx->ctorFlag = true;
181 
182     napi_value resource = nullptr;
183     napi_create_string_utf8(env, "JsCreateAVRecorder", NAPI_AUTO_LENGTH, &resource);
184     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {},
185               MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
186     NAPI_CALL(env, napi_queue_async_work(env, asyncCtx->work));
187     asyncCtx.release();
188 
189     MEDIA_LOGI("JsCreateAVRecorder success");
190     return result;
191 }
192 
GetRetInfo(int32_t errCode,const std::string & operate,const std::string & param,const std::string & add="")193 RetInfo GetRetInfo(int32_t errCode, const std::string &operate, const std::string &param, const std::string &add = "")
194 {
195     MEDIA_LOGE("failed to %{public}s, param %{public}s, errCode = %{public}d", operate.c_str(), param.c_str(), errCode);
196     MediaServiceExtErrCodeAPI9 err = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errCode));
197     if (errCode == MSERR_UNSUPPORT_VID_PARAMS) {
198         return RetInfo(err, "The video parameter is not supported. Please check the type and range.");
199     }
200 
201     if (errCode == MSERR_UNSUPPORT_AUD_PARAMS) {
202         return RetInfo(err, "The audio parameter is not supported. Please check the type and range.");
203     }
204 
205     std::string message;
206     if (err == MSERR_EXT_API9_INVALID_PARAMETER) {
207         message = MSExtErrorAPI9ToString(err, param, "") + add;
208     } else {
209         message = MSExtErrorAPI9ToString(err, operate, "") + add;
210     }
211 
212     MEDIA_LOGE("errCode: %{public}d, errMsg: %{public}s", err, message.c_str());
213     return RetInfo(err, message);
214 }
215 
JsPrepare(napi_env env,napi_callback_info info)216 napi_value AVRecorderNapi::JsPrepare(napi_env env, napi_callback_info info)
217 {
218     MediaTrace trace("AVRecorder::JsPrepare");
219     const std::string &opt = AVRecordergOpt::PREPARE;
220     MEDIA_LOGI("Js %{public}s Start", opt.c_str());
221 
222     const int32_t maxParam = 2; // config + callbackRef
223     size_t argCount = maxParam;
224     napi_value args[maxParam] = { nullptr };
225 
226     napi_value result = nullptr;
227     napi_get_undefined(env, &result);
228 
229     auto asyncCtx = std::make_unique<AVRecorderAsyncContext>(env);
230     CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get AsyncContext");
231     asyncCtx->napi = AVRecorderNapi::GetJsInstanceAndArgs(env, info, argCount, args);
232     CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
233     CHECK_AND_RETURN_RET_LOG(asyncCtx->napi->taskQue_ != nullptr, result, "taskQue is nullptr!");
234 
235     asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[1]);
236     asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
237 
238     if (asyncCtx->napi->CheckStateMachine(opt) == MSERR_OK) {
239         if (asyncCtx->napi->GetConfig(asyncCtx, env, args[0]) == MSERR_OK) {
240             asyncCtx->task_ = AVRecorderNapi::GetPrepareTask(asyncCtx);
241             (void)asyncCtx->napi->taskQue_->EnqueueTask(asyncCtx->task_);
242         }
243     } else {
244         asyncCtx->AVRecorderSignError(MSERR_INVALID_OPERATION, opt, "");
245     }
246 
247     napi_value resource = nullptr;
248     napi_create_string_utf8(env, opt.c_str(), NAPI_AUTO_LENGTH, &resource);
249     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
250         AVRecorderAsyncContext* asyncCtx = reinterpret_cast<AVRecorderAsyncContext *>(data);
251         CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
252 
253         if (asyncCtx->task_) {
254             auto result = asyncCtx->task_->GetResult();
255             if (result.Value().first != MSERR_EXT_API9_OK) {
256                 asyncCtx->SignError(result.Value().first, result.Value().second);
257             }
258         }
259         MEDIA_LOGI("The js thread of prepare finishes execution and returns");
260     }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
261     NAPI_CALL(env, napi_queue_async_work(env, asyncCtx->work));
262     asyncCtx.release();
263 
264     MEDIA_LOGI("Js %{public}s End", opt.c_str());
265     return result;
266 }
267 
GetPrepareTask(std::unique_ptr<AVRecorderAsyncContext> & asyncCtx)268 std::shared_ptr<TaskHandler<RetInfo>> AVRecorderNapi::GetPrepareTask(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx)
269 {
270     return std::make_shared<TaskHandler<RetInfo>>([napi = asyncCtx->napi, config = asyncCtx->config_]() {
271         const std::string &option = AVRecordergOpt::PREPARE;
272         MEDIA_LOGI("%{public}s Start", option.c_str());
273         CHECK_AND_RETURN_RET(napi != nullptr && napi->recorder_ != nullptr && config != nullptr,
274             GetRetInfo(MSERR_INVALID_OPERATION, option, ""));
275 
276         CHECK_AND_RETURN_RET(napi->CheckStateMachine(option) == MSERR_OK,
277             GetRetInfo(MSERR_INVALID_OPERATION, option, ""));
278 
279         RetInfo retinfo = napi->Configure(config);
280         CHECK_AND_RETURN_RET(retinfo.first == MSERR_OK, ((void)napi->recorder_->Reset(), retinfo));
281 
282         int32_t ret = napi->recorder_->Prepare();
283         CHECK_AND_RETURN_RET(ret == MSERR_OK, ((void)napi->recorder_->Reset(), GetRetInfo(ret, "Prepare", "")));
284 
285         napi->RemoveSurface();
286         napi->StateCallback(AVRecorderState::STATE_PREPARED);
287         napi->getVideoInputSurface_ = false;
288         napi->withVideo_ = config->withVideo;
289         MEDIA_LOGI("%{public}s End", option.c_str());
290         return RetInfo(MSERR_EXT_API9_OK, "");
291     });
292 }
293 
JsGetInputSurface(napi_env env,napi_callback_info info)294 napi_value AVRecorderNapi::JsGetInputSurface(napi_env env, napi_callback_info info)
295 {
296     MediaTrace trace("AVRecorder::JsGetInputSurface");
297     return ExecuteByPromise(env, info, AVRecordergOpt::GETINPUTSURFACE);
298 }
299 
JsStart(napi_env env,napi_callback_info info)300 napi_value AVRecorderNapi::JsStart(napi_env env, napi_callback_info info)
301 {
302     MediaTrace trace("AVRecorder::JsStart");
303 #ifdef SUPPORT_JSSTACK
304     HiviewDFX::ReportXPowerJsStackSysEvent(env, "STREAM_CHANGE", "SRC=Media");
305 #endif
306     return ExecuteByPromise(env, info, AVRecordergOpt::START);
307 }
308 
JsPause(napi_env env,napi_callback_info info)309 napi_value AVRecorderNapi::JsPause(napi_env env, napi_callback_info info)
310 {
311     MediaTrace trace("AVRecorder::JsPause");
312     return ExecuteByPromise(env, info, AVRecordergOpt::PAUSE);
313 }
314 
JsResume(napi_env env,napi_callback_info info)315 napi_value AVRecorderNapi::JsResume(napi_env env, napi_callback_info info)
316 {
317     MediaTrace trace("AVRecorder::JsResume");
318 #ifdef SUPPORT_JSSTACK
319     HiviewDFX::ReportXPowerJsStackSysEvent(env, "STREAM_CHANGE", "SRC=Media");
320 #endif
321     return ExecuteByPromise(env, info, AVRecordergOpt::RESUME);
322 }
323 
JsStop(napi_env env,napi_callback_info info)324 napi_value AVRecorderNapi::JsStop(napi_env env, napi_callback_info info)
325 {
326     MediaTrace trace("AVRecorder::JsStop");
327     return ExecuteByPromise(env, info, AVRecordergOpt::STOP);
328 }
329 
JsReset(napi_env env,napi_callback_info info)330 napi_value AVRecorderNapi::JsReset(napi_env env, napi_callback_info info)
331 {
332     MediaTrace trace("AVRecorder::JsReset");
333     return ExecuteByPromise(env, info, AVRecordergOpt::RESET);
334 }
335 
JsRelease(napi_env env,napi_callback_info info)336 napi_value AVRecorderNapi::JsRelease(napi_env env, napi_callback_info info)
337 {
338     MediaTrace trace("AVRecorder::JsRelease");
339     return ExecuteByPromise(env, info, AVRecordergOpt::RELEASE);
340 }
341 
JsGetAVRecorderProfile(napi_env env,napi_callback_info info)342 napi_value AVRecorderNapi::JsGetAVRecorderProfile(napi_env env, napi_callback_info info)
343 {
344     MediaTrace trace("AVRecorder::JsGetAVRecorderProfile");
345     MEDIA_LOGI("AVRecorder::JsGetAVRecorderProfile");
346     const std::string &opt = AVRecordergOpt::GET_AV_RECORDER_PROFILE;
347     MEDIA_LOGI("Js %{public}s Start", opt.c_str());
348 
349     const int32_t maxParam = 3; // config + callbackRef
350     const int32_t callbackParam = 2; // callback
351     size_t argCount = maxParam;
352     napi_value args[maxParam] = { nullptr };
353     napi_value result = nullptr;
354     napi_get_undefined(env, &result);
355 
356     auto asyncCtx = std::make_unique<AVRecorderAsyncContext>(env);
357     CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get AsyncContext");
358     asyncCtx->napi = AVRecorderNapi::GetJsInstanceAndArgs(env, info, argCount, args);
359     CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
360     CHECK_AND_RETURN_RET_LOG(asyncCtx->napi->taskQue_ != nullptr, result, "taskQue is nullptr!");
361 
362     asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[callbackParam]);
363     asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
364 
365     if (asyncCtx->napi->GetSourceIdAndQuality(asyncCtx, env, args[0], args[1], opt) == MSERR_OK) {
366         asyncCtx->task_ = AVRecorderNapi::GetAVRecorderProfileTask(asyncCtx);
367         (void)asyncCtx->napi->taskQue_->EnqueueTask(asyncCtx->task_);
368     }
369 
370     napi_value resource = nullptr;
371     napi_create_string_utf8(env, opt.c_str(), NAPI_AUTO_LENGTH, &resource);
372     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
373         AVRecorderAsyncContext* asyncCtx = reinterpret_cast<AVRecorderAsyncContext *>(data);
374         CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
375         if (asyncCtx->task_) {
376             auto result = asyncCtx->task_->GetResult();
377             if (result.Value().first != MSERR_EXT_API9_OK) {
378                 asyncCtx->SignError(result.Value().first, result.Value().second);
379             } else {
380                 asyncCtx->JsResult = std::make_unique<MediaJsAVRecorderProfile>(asyncCtx->profile_);
381             }
382         }
383         MEDIA_LOGI("The js thread of prepare finishes execution and returns");
384     }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
385     NAPI_CALL(env, napi_queue_async_work(env, asyncCtx->work));
386     asyncCtx.release();
387 
388     MEDIA_LOGI("Js %{public}s End", opt.c_str());
389     return result;
390 }
391 
GetAVRecorderProfileTask(const std::unique_ptr<AVRecorderAsyncContext> & asyncCtx)392 std::shared_ptr<TaskHandler<RetInfo>> AVRecorderNapi::GetAVRecorderProfileTask(
393     const std::unique_ptr<AVRecorderAsyncContext> &asyncCtx)
394 {
395     return std::make_shared<TaskHandler<RetInfo>>([napi = asyncCtx->napi, &profile = asyncCtx->profile_]() {
396         const std::string &option = AVRecordergOpt::GET_AV_RECORDER_PROFILE;
397         MEDIA_LOGI("%{public}s Start", option.c_str());
398         profile = std::make_shared<AVRecorderProfile>();
399 
400         CHECK_AND_RETURN_RET(napi != nullptr && profile != nullptr,
401             GetRetInfo(MSERR_INVALID_OPERATION, option, ""));
402 
403         CHECK_AND_RETURN_RET(napi->CheckStateMachine(option) == MSERR_OK,
404             GetRetInfo(MSERR_INVALID_OPERATION, option, ""));
405 
406         CHECK_AND_RETURN_RET_LOG(napi->sourceId_ >= 0 && ((napi->qualityLevel_ >= RECORDER_QUALITY_LOW &&
407             napi->qualityLevel_ <= RECORDER_QUALITY_2160P) ||
408             (napi->qualityLevel_ >= RECORDER_QUALITY_TIME_LAPSE_LOW &&
409             napi->qualityLevel_ <= RECORDER_QUALITY_TIME_LAPSE_2160P) ||
410             (napi->qualityLevel_ >= RECORDER_QUALITY_HIGH_SPEED_LOW &&
411             napi->qualityLevel_ <= RECORDER_QUALITY_HIGH_SPEED_1080P)),
412             GetRetInfo(MSERR_INVALID_VAL, "GetAVRecorderProfileTask", ""), "sourceId or qualityLevel is null");
413 
414         int32_t ret = AVRecorderNapi::GetAVRecorderProfile(profile, napi->sourceId_, napi->qualityLevel_);
415         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, GetRetInfo(MSERR_INVALID_VAL, "GetAVRecorderProfileTask", ""),
416             "get AVRecorderProfile failed");
417 
418         MEDIA_LOGI("%{public}s End", option.c_str());
419         return RetInfo(MSERR_EXT_API9_OK, "");
420     });
421 }
422 
SetAVRecorderConfigTask(std::unique_ptr<AVRecorderAsyncContext> & asyncCtx)423 std::shared_ptr<TaskHandler<RetInfo>> AVRecorderNapi::SetAVRecorderConfigTask(
424     std::unique_ptr<AVRecorderAsyncContext> &asyncCtx)
425 {
426     return std::make_shared<TaskHandler<RetInfo>>([napi = asyncCtx->napi, config = asyncCtx->config_]() {
427         const std::string &option = AVRecordergOpt::SET_AV_RECORDER_CONFIG;
428         MEDIA_LOGI("%{public}s Start", option.c_str());
429         CHECK_AND_RETURN_RET(napi != nullptr && napi->recorder_ != nullptr && config != nullptr,
430             GetRetInfo(MSERR_INVALID_OPERATION, option, ""));
431 
432         CHECK_AND_RETURN_RET(napi->CheckStateMachine(option) == MSERR_OK,
433             GetRetInfo(MSERR_INVALID_OPERATION, option, ""));
434 
435         RetInfo retinfo = napi->Configure(config);
436         CHECK_AND_RETURN_RET(retinfo.first == MSERR_OK, ((void)napi->recorder_->Reset(), retinfo));
437 
438         napi->withVideo_ = config->withVideo;
439         MEDIA_LOGI("%{public}s End", option.c_str());
440         return RetInfo(MSERR_EXT_API9_OK, "");
441     });
442 }
443 
JsSetAVRecorderConfig(napi_env env,napi_callback_info info)444 napi_value AVRecorderNapi::JsSetAVRecorderConfig(napi_env env, napi_callback_info info)
445 {
446     MediaTrace trace("AVRecorder::JsSetAVRecorderConfig");
447     const std::string &opt = AVRecordergOpt::SET_AV_RECORDER_CONFIG;
448     MEDIA_LOGI("Js %{public}s Start", opt.c_str());
449 
450     const int32_t maxParam = 2; // config + callbackRef
451     size_t argCount = maxParam;
452     napi_value args[maxParam] = { nullptr };
453     napi_value result = nullptr;
454     napi_get_undefined(env, &result);
455 
456     auto asyncCtx = std::make_unique<AVRecorderAsyncContext>(env);
457     CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get AsyncContext");
458     asyncCtx->napi = AVRecorderNapi::GetJsInstanceAndArgs(env, info, argCount, args);
459     CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
460     CHECK_AND_RETURN_RET_LOG(asyncCtx->napi->taskQue_ != nullptr, result, "taskQue is nullptr!");
461 
462     asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[1]);
463     asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
464 
465     if (asyncCtx->napi->CheckStateMachine(opt) == MSERR_OK) {
466         if (asyncCtx->napi->GetConfig(asyncCtx, env, args[0]) == MSERR_OK) {
467             asyncCtx->task_ = AVRecorderNapi::SetAVRecorderConfigTask(asyncCtx);
468             (void)asyncCtx->napi->taskQue_->EnqueueTask(asyncCtx->task_);
469         }
470     } else {
471         asyncCtx->AVRecorderSignError(MSERR_INVALID_OPERATION, opt, "");
472     }
473 
474     napi_value resource = nullptr;
475     napi_create_string_utf8(env, opt.c_str(), NAPI_AUTO_LENGTH, &resource);
476     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
477         AVRecorderAsyncContext* asyncCtx = reinterpret_cast<AVRecorderAsyncContext *>(data);
478         CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
479         if (asyncCtx->task_) {
480             auto result = asyncCtx->task_->GetResult();
481             if (result.Value().first != MSERR_EXT_API9_OK) {
482                 asyncCtx->SignError(result.Value().first, result.Value().second);
483             }
484         }
485         MEDIA_LOGI("The js thread of prepare finishes execution and returns");
486     }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
487     NAPI_CALL(env, napi_queue_async_work(env, asyncCtx->work));
488     asyncCtx.release();
489 
490     MEDIA_LOGI("Js %{public}s End", opt.c_str());
491     return result;
492 }
493 
JsSetEventCallback(napi_env env,napi_callback_info info)494 napi_value AVRecorderNapi::JsSetEventCallback(napi_env env, napi_callback_info info)
495 {
496     MediaTrace trace("AVRecorder::JsSetEventCallback");
497     MEDIA_LOGI("JsSetEventCallback Start");
498     napi_value result = nullptr;
499     napi_get_undefined(env, &result);
500 
501     size_t argCount = 2;
502     napi_value args[2] = { nullptr, nullptr };
503     AVRecorderNapi *recorderNapi = AVRecorderNapi::GetJsInstanceAndArgs(env, info, argCount, args);
504     CHECK_AND_RETURN_RET_LOG(recorderNapi != nullptr, result, "Failed to retrieve instance");
505 
506     napi_valuetype valueType0 = napi_undefined;
507     napi_valuetype valueType1 = napi_undefined;
508     if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string ||
509         napi_typeof(env, args[1], &valueType1) != napi_ok || valueType1 != napi_function) {
510         recorderNapi->ErrorCallback(MSERR_INVALID_VAL, "SetEventCallback");
511         return result;
512     }
513 
514     std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
515     if (callbackName != AVRecorderEvent::EVENT_ERROR && callbackName != AVRecorderEvent::EVENT_STATE_CHANGE) {
516         recorderNapi->ErrorCallback(MSERR_INVALID_VAL, "SetEventCallback");
517         return result;
518     }
519 
520     napi_ref ref = nullptr;
521     napi_status status = napi_create_reference(env, args[1], 1, &ref);
522     CHECK_AND_RETURN_RET_LOG(status == napi_ok && ref != nullptr, result, "failed to create reference!");
523 
524     std::shared_ptr<AutoRef> autoRef = std::make_shared<AutoRef>(env, ref);
525     recorderNapi->SetCallbackReference(callbackName, autoRef);
526 
527     MEDIA_LOGI("JsSetEventCallback End");
528     return result;
529 }
530 
JsCancelEventCallback(napi_env env,napi_callback_info info)531 napi_value AVRecorderNapi::JsCancelEventCallback(napi_env env, napi_callback_info info)
532 {
533     MediaTrace trace("AVRecorder::JsCancelEventCallback");
534     MEDIA_LOGI("JsCancelEventCallback Start");
535     napi_value result = nullptr;
536     napi_get_undefined(env, &result);
537 
538     size_t argCount = 1;
539     napi_value args[1] = { nullptr };
540     AVRecorderNapi *recorderNapi = AVRecorderNapi::GetJsInstanceAndArgs(env, info, argCount, args);
541     CHECK_AND_RETURN_RET_LOG(recorderNapi != nullptr, result, "Failed to retrieve instance");
542 
543     napi_valuetype valueType0 = napi_undefined;
544     if (napi_typeof(env, args[0], &valueType0) != napi_ok || valueType0 != napi_string) {
545         recorderNapi->ErrorCallback(MSERR_INVALID_VAL, "CancelEventCallback");
546         return result;
547     }
548 
549     std::string callbackName = CommonNapi::GetStringArgument(env, args[0]);
550     if (callbackName != AVRecorderEvent::EVENT_ERROR && callbackName != AVRecorderEvent::EVENT_STATE_CHANGE) {
551         recorderNapi->ErrorCallback(MSERR_INVALID_VAL, "CancelEventCallback");
552         return result;
553     }
554 
555     recorderNapi->CancelCallbackReference(callbackName);
556 
557     MEDIA_LOGI("JsCancelEventCallback End");
558     return result;
559 }
560 
JsGetState(napi_env env,napi_callback_info info)561 napi_value AVRecorderNapi::JsGetState(napi_env env, napi_callback_info info)
562 {
563     MediaTrace trace("AVRecorder::JsGetState");
564     napi_value result = nullptr;
565     napi_get_undefined(env, &result);
566 
567     size_t argCount = 0;
568     AVRecorderNapi *recorderNapi = AVRecorderNapi::GetJsInstanceAndArgs(env, info, argCount, nullptr);
569     CHECK_AND_RETURN_RET_LOG(recorderNapi != nullptr, result, "failed to GetJsInstance");
570 
571     auto napiCb = std::static_pointer_cast<AVRecorderCallback>(recorderNapi->recorderCb_);
572     CHECK_AND_RETURN_RET_LOG(napiCb != nullptr, result, "napiCb is nullptr!");
573     std::string curState = napiCb->GetState();
574     MEDIA_LOGI("GetState success, State: %{public}s", curState.c_str());
575 
576     napi_value jsResult = nullptr;
577     napi_status status = napi_create_string_utf8(env, curState.c_str(), NAPI_AUTO_LENGTH, &jsResult);
578     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_string_utf8 error");
579     return jsResult;
580 }
581 
GetJsInstanceAndArgs(napi_env env,napi_callback_info info,size_t & argCount,napi_value * args)582 AVRecorderNapi* AVRecorderNapi::GetJsInstanceAndArgs(napi_env env, napi_callback_info info,
583     size_t &argCount, napi_value *args)
584 {
585     napi_value jsThis = nullptr;
586     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
587     CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr, "failed to napi_get_cb_info");
588     MEDIA_LOGI("argCount:%{public}zu", argCount);
589 
590     AVRecorderNapi *recorderNapi = nullptr;
591     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&recorderNapi));
592     CHECK_AND_RETURN_RET_LOG(status == napi_ok && recorderNapi != nullptr, nullptr, "failed to retrieve instance");
593 
594     return recorderNapi;
595 }
596 
GetPromiseTask(AVRecorderNapi * avnapi,const std::string & opt)597 std::shared_ptr<TaskHandler<RetInfo>> AVRecorderNapi::GetPromiseTask(AVRecorderNapi *avnapi, const std::string &opt)
598 {
599     return std::make_shared<TaskHandler<RetInfo>>([napi = avnapi, option = opt]() {
600         MEDIA_LOGI("%{public}s Start", option.c_str());
601         CHECK_AND_RETURN_RET(napi != nullptr && napi->recorder_ != nullptr,
602             GetRetInfo(MSERR_INVALID_OPERATION, option, ""));
603 
604         CHECK_AND_RETURN_RET(napi->CheckStateMachine(option) == MSERR_OK,
605             GetRetInfo(MSERR_INVALID_OPERATION, option, ""));
606 
607         CHECK_AND_RETURN_RET(napi->CheckRepeatOperation(option) == MSERR_OK,
608             RetInfo(MSERR_EXT_API9_OK, ""));
609 
610         RetInfo ret(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "");
611         auto itFunc = taskQFuncs_.find(option);
612         CHECK_AND_RETURN_RET_LOG(itFunc != taskQFuncs_.end(), ret, "%{public}s not found in map!", option.c_str());
613         auto memberFunc = itFunc->second;
614         CHECK_AND_RETURN_RET_LOG(memberFunc != nullptr, ret, "memberFunc is nullptr!");
615         ret = (napi->*memberFunc)();
616 
617         MEDIA_LOGI("%{public}s End", option.c_str());
618         return ret;
619     });
620 }
621 
ExecuteByPromise(napi_env env,napi_callback_info info,const std::string & opt)622 napi_value AVRecorderNapi::ExecuteByPromise(napi_env env, napi_callback_info info, const std::string &opt)
623 {
624     MEDIA_LOGI("Js %{public}s Start", opt.c_str());
625     napi_value result = nullptr;
626     napi_get_undefined(env, &result);
627     size_t argCount = 1; // Only callbackRef parameter
628     napi_value args[1] = { nullptr }; // Only callbackRef parameter
629 
630     auto asyncCtx = std::make_unique<AVRecorderAsyncContext>(env);
631     CHECK_AND_RETURN_RET_LOG(asyncCtx != nullptr, result, "failed to get AsyncContext");
632     asyncCtx->napi = AVRecorderNapi::GetJsInstanceAndArgs(env, info, argCount, args);
633     CHECK_AND_RETURN_RET_LOG(asyncCtx->napi != nullptr, result, "failed to GetJsInstanceAndArgs");
634     CHECK_AND_RETURN_RET_LOG(asyncCtx->napi->taskQue_ != nullptr, result, "taskQue is nullptr!");
635 
636     asyncCtx->callbackRef = CommonNapi::CreateReference(env, args[0]);
637     asyncCtx->deferred = CommonNapi::CreatePromise(env, asyncCtx->callbackRef, result);
638 
639     if (asyncCtx->napi->CheckStateMachine(opt) == MSERR_OK) {
640         asyncCtx->task_ = AVRecorderNapi::GetPromiseTask(asyncCtx->napi, opt);
641         (void)asyncCtx->napi->taskQue_->EnqueueTask(asyncCtx->task_);
642         asyncCtx->opt_ = opt;
643     } else {
644         asyncCtx->AVRecorderSignError(MSERR_INVALID_OPERATION, opt, "");
645     }
646 
647     napi_value resource = nullptr;
648     napi_create_string_utf8(env, opt.c_str(), NAPI_AUTO_LENGTH, &resource);
649     NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) {
650         AVRecorderAsyncContext* asyncCtx = reinterpret_cast<AVRecorderAsyncContext *>(data);
651         CHECK_AND_RETURN_LOG(asyncCtx != nullptr, "asyncCtx is nullptr!");
652 
653         if (asyncCtx->task_) {
654             auto result = asyncCtx->task_->GetResult();
655             if (result.Value().first != MSERR_EXT_API9_OK) {
656                 asyncCtx->SignError(result.Value().first, result.Value().second);
657             }
658 
659             if ((result.Value().first == MSERR_EXT_API9_OK) && (asyncCtx->opt_ == AVRecordergOpt::GETINPUTSURFACE)) {
660                 asyncCtx->JsResult = std::make_unique<MediaJsResultString>(result.Value().second);
661             }
662         }
663         MEDIA_LOGI("The js thread of %{public}s finishes execution and returns", asyncCtx->opt_.c_str());
664     }, MediaAsyncContext::CompleteCallback, static_cast<void *>(asyncCtx.get()), &asyncCtx->work));
665     NAPI_CALL(env, napi_queue_async_work(env, asyncCtx->work));
666     asyncCtx.release();
667 
668     MEDIA_LOGI("Js %{public}s End", opt.c_str());
669     return result;
670 }
671 
GetInputSurface()672 RetInfo AVRecorderNapi::GetInputSurface()
673 {
674     CHECK_AND_RETURN_RET_LOG(withVideo_, GetRetInfo(MSERR_INVALID_OPERATION, "GetInputSurface", "",
675         "The VideoSourceType is not configured. Please do not call getInputSurface"), "No video recording");
676 
677     if (surface_ == nullptr) {
678         surface_ = recorder_->GetSurface(videoSourceID_);
679         CHECK_AND_RETURN_RET_LOG(surface_ != nullptr,
680             GetRetInfo(MSERR_INVALID_OPERATION, "GetInputSurface", ""), "failed to GetSurface");
681 
682         SurfaceError error = SurfaceUtils::GetInstance()->Add(surface_->GetUniqueId(), surface_);
683         CHECK_AND_RETURN_RET_LOG(error == SURFACE_ERROR_OK,
684             GetRetInfo(MSERR_INVALID_OPERATION, "GetInputSurface", ""), "failed to AddSurface");
685     }
686 
687     auto surfaceId = std::to_string(surface_->GetUniqueId());
688     getVideoInputSurface_ = true;
689     return RetInfo(MSERR_EXT_API9_OK, surfaceId);
690 }
691 
Start()692 RetInfo AVRecorderNapi::Start()
693 {
694     if (withVideo_ && !getVideoInputSurface_) {
695         return GetRetInfo(MSERR_INVALID_OPERATION, "Start", "",
696             " Please get the video input surface through GetInputSurface first!");
697     }
698 
699     int32_t ret = recorder_->Start();
700     CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "Start", ""));
701     StateCallback(AVRecorderState::STATE_STARTED);
702     return RetInfo(MSERR_EXT_API9_OK, "");
703 }
704 
Pause()705 RetInfo AVRecorderNapi::Pause()
706 {
707     int32_t ret = recorder_->Pause();
708     CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "Pause", ""));
709     StateCallback(AVRecorderState::STATE_PAUSED);
710     return RetInfo(MSERR_EXT_API9_OK, "");
711 }
712 
Resume()713 RetInfo AVRecorderNapi::Resume()
714 {
715     int32_t ret = recorder_->Resume();
716     CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "Resume", ""));
717     StateCallback(AVRecorderState::STATE_STARTED);
718     return RetInfo(MSERR_EXT_API9_OK, "");
719 }
720 
Stop()721 RetInfo AVRecorderNapi::Stop()
722 {
723     int32_t ret = recorder_->Stop(false);
724     CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "Stop", ""));
725     StateCallback(AVRecorderState::STATE_STOPPED);
726     hasConfiged_ = false;
727     return RetInfo(MSERR_EXT_API9_OK, "");
728 }
729 
Reset()730 RetInfo AVRecorderNapi::Reset()
731 {
732     RemoveSurface();
733     int32_t ret = recorder_->Reset();
734     CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "Reset", ""));
735 
736     StateCallback(AVRecorderState::STATE_IDLE);
737     hasConfiged_ = false;
738     return RetInfo(MSERR_EXT_API9_OK, "");
739 }
740 
Release()741 RetInfo AVRecorderNapi::Release()
742 {
743     RemoveSurface();
744     int32_t ret = recorder_->Release();
745     CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "Release", ""));
746 
747     StateCallback(AVRecorderState::STATE_RELEASED);
748     CancelCallback();
749     hasConfiged_ = false;
750     return RetInfo(MSERR_EXT_API9_OK, "");
751 }
752 
CheckStateMachine(const std::string & opt)753 int32_t AVRecorderNapi::CheckStateMachine(const std::string &opt)
754 {
755     auto napiCb = std::static_pointer_cast<AVRecorderCallback>(recorderCb_);
756     CHECK_AND_RETURN_RET_LOG(napiCb != nullptr, MSERR_INVALID_OPERATION, "napiCb is nullptr!");
757 
758     std::string curState = napiCb->GetState();
759     std::vector<std::string> allowedOpt = stateCtrlList.at(curState);
760     if (find(allowedOpt.begin(), allowedOpt.end(), opt) == allowedOpt.end()) {
761         MEDIA_LOGE("The %{public}s operation is not allowed in the %{public}s state!", opt.c_str(), curState.c_str());
762         return MSERR_INVALID_OPERATION;
763     }
764 
765     return MSERR_OK;
766 }
767 
CheckRepeatOperation(const std::string & opt)768 int32_t AVRecorderNapi::CheckRepeatOperation(const std::string &opt)
769 {
770     const std::map<std::string, std::vector<std::string>> stateCtrl = {
771         {AVRecorderState::STATE_IDLE, {
772             AVRecordergOpt::RESET,
773             AVRecordergOpt::GET_AV_RECORDER_PROFILE,
774             AVRecordergOpt::SET_AV_RECORDER_CONFIG,
775         }},
776         {AVRecorderState::STATE_PREPARED, {}},
777         {AVRecorderState::STATE_STARTED, {
778             AVRecordergOpt::START,
779             AVRecordergOpt::RESUME
780         }},
781         {AVRecorderState::STATE_PAUSED, {
782             AVRecordergOpt::PAUSE
783         }},
784         {AVRecorderState::STATE_STOPPED, {
785             AVRecordergOpt::STOP
786         }},
787         {AVRecorderState::STATE_RELEASED, {
788             AVRecordergOpt::RELEASE
789         }},
790         {AVRecorderState::STATE_ERROR, {}},
791     };
792 
793     auto napiCb = std::static_pointer_cast<AVRecorderCallback>(recorderCb_);
794     CHECK_AND_RETURN_RET_LOG(napiCb != nullptr, MSERR_INVALID_OPERATION, "napiCb is nullptr!");
795 
796     std::string curState = napiCb->GetState();
797     std::vector<std::string> repeatOpt = stateCtrl.at(curState);
798     if (find(repeatOpt.begin(), repeatOpt.end(), opt) != repeatOpt.end()) {
799         MEDIA_LOGI("Current state is %{public}s. Please do not call %{public}s again!", curState.c_str(), opt.c_str());
800         return MSERR_INVALID_OPERATION;
801     }
802 
803     return MSERR_OK;
804 }
805 
GetAudioCodecFormat(const std::string & mime,AudioCodecFormat & codecFormat)806 int32_t AVRecorderNapi::GetAudioCodecFormat(const std::string &mime, AudioCodecFormat &codecFormat)
807 {
808     MEDIA_LOGI("mime %{public}s", mime.c_str());
809     const std::map<std::string_view, AudioCodecFormat> mimeStrToCodecFormat = {
810         { CodecMimeType::AUDIO_AAC, AudioCodecFormat::AAC_LC },
811         { "", AudioCodecFormat::AUDIO_DEFAULT },
812     };
813 
814     auto iter = mimeStrToCodecFormat.find(mime);
815     if (iter != mimeStrToCodecFormat.end()) {
816         codecFormat = iter->second;
817         return MSERR_OK;
818     }
819     return MSERR_INVALID_VAL;
820 }
821 
GetVideoCodecFormat(const std::string & mime,VideoCodecFormat & codecFormat)822 int32_t AVRecorderNapi::GetVideoCodecFormat(const std::string &mime, VideoCodecFormat &codecFormat)
823 {
824     MEDIA_LOGI("mime %{public}s", mime.c_str());
825     const std::map<std::string_view, VideoCodecFormat> mimeStrToCodecFormat = {
826         { CodecMimeType::VIDEO_AVC, VideoCodecFormat::H264 },
827         { CodecMimeType::VIDEO_MPEG4, VideoCodecFormat::MPEG4 },
828         { "", VideoCodecFormat::VIDEO_DEFAULT },
829     };
830 
831     auto iter = mimeStrToCodecFormat.find(mime);
832     if (iter != mimeStrToCodecFormat.end()) {
833         codecFormat = iter->second;
834         return MSERR_OK;
835     }
836     return MSERR_INVALID_VAL;
837 }
838 
GetOutputFormat(const std::string & extension,OutputFormatType & type)839 int32_t AVRecorderNapi::GetOutputFormat(const std::string &extension, OutputFormatType &type)
840 {
841     MEDIA_LOGI("mime %{public}s", extension.c_str());
842     const std::map<std::string, OutputFormatType> extensionToOutputFormat = {
843         { "mp4", OutputFormatType::FORMAT_MPEG_4 },
844         { "m4a", OutputFormatType::FORMAT_M4A },
845         { "", OutputFormatType::FORMAT_DEFAULT },
846     };
847 
848     auto iter = extensionToOutputFormat.find(extension);
849     if (iter != extensionToOutputFormat.end()) {
850         type = iter->second;
851         return MSERR_OK;
852     }
853     return MSERR_INVALID_VAL;
854 }
855 
GetSourceType(std::unique_ptr<AVRecorderAsyncContext> & asyncCtx,napi_env env,napi_value args)856 int32_t AVRecorderNapi::GetSourceType(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx, napi_env env, napi_value args)
857 {
858     std::shared_ptr<AVRecorderConfig> config = asyncCtx->config_;
859     int32_t audioSource = AUDIO_SOURCE_INVALID;
860     int32_t videoSource = VIDEO_SOURCE_BUTT;
861 
862     bool getValue = false;
863     int32_t ret = AVRecorderNapi::GetPropertyInt32(env, args, "audioSourceType", audioSource, getValue);
864     CHECK_AND_RETURN_RET(ret == MSERR_OK,
865         (asyncCtx->AVRecorderSignError(ret, "getaudioSourceType", "audioSourceType"), ret));
866     if (getValue) {
867         config->audioSourceType = static_cast<AudioSourceType>(audioSource);
868         config->withAudio = true;
869         MEDIA_LOGI("audioSource Type %{public}d!", audioSource);
870     }
871 
872     ret = AVRecorderNapi::GetPropertyInt32(env, args, "videoSourceType", videoSource, getValue);
873     CHECK_AND_RETURN_RET(ret == MSERR_OK,
874         (asyncCtx->AVRecorderSignError(ret, "getvideoSourceType", "videoSourceType"), ret));
875     if (getValue) {
876         config->videoSourceType = static_cast<VideoSourceType>(videoSource);
877         config->withVideo = true;
878         MEDIA_LOGI("videoSource Type %{public}d!", videoSource);
879     }
880 
881     CHECK_AND_RETURN_RET(config->withAudio || config->withVideo,
882         (asyncCtx->AVRecorderSignError(MSERR_INVALID_VAL, "getsourcetype", "SourceType"), MSERR_INVALID_VAL));
883 
884     return MSERR_OK;
885 }
886 
GetProfile(std::unique_ptr<AVRecorderAsyncContext> & asyncCtx,napi_env env,napi_value args)887 int32_t AVRecorderNapi::GetProfile(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx, napi_env env, napi_value args)
888 {
889     napi_value item = nullptr;
890     napi_get_named_property(env, args, "profile", &item);
891     CHECK_AND_RETURN_RET_LOG(item != nullptr, MSERR_INVALID_VAL, "get profile error");
892 
893     AVRecorderProfile &profile = asyncCtx->config_->profile;
894 
895     int32_t ret = MSERR_OK;
896     if (asyncCtx->config_->withAudio) {
897         std::string audioCodec = CommonNapi::GetPropertyString(env, item, "audioCodec");
898         ret = AVRecorderNapi::GetAudioCodecFormat(audioCodec, profile.audioCodecFormat);
899         CHECK_AND_RETURN_RET(ret == MSERR_OK,
900             (asyncCtx->AVRecorderSignError(ret, "GetAudioCodecFormat", "audioCodecFormat"), ret));
901 
902         ret = MSERR_INVALID_VAL;
903         CHECK_AND_RETURN_RET(CommonNapi::GetPropertyInt32(env, item, "audioBitrate", profile.audioBitrate),
904             (asyncCtx->AVRecorderSignError(ret, "GetaudioBitrate", "audioBitrate"), ret));
905         CHECK_AND_RETURN_RET(CommonNapi::GetPropertyInt32(env, item, "audioChannels", profile.audioChannels),
906             (asyncCtx->AVRecorderSignError(ret, "GetaudioChannels", "audioChannels"), ret));
907         CHECK_AND_RETURN_RET(CommonNapi::GetPropertyInt32(env, item, "audioSampleRate", profile.auidoSampleRate),
908             (asyncCtx->AVRecorderSignError(ret, "GetauidoSampleRate", "auidoSampleRate"), ret));
909 
910         MEDIA_LOGI("audioBitrate %{public}d, audioChannels %{public}d, audioCodecFormat %{public}d,"
911                    " audioSampleRate %{public}d!", profile.audioBitrate, profile.audioChannels,
912                    profile.audioCodecFormat, profile.auidoSampleRate);
913     }
914 
915     if (asyncCtx->config_->withVideo) {
916         std::string videoCodec = CommonNapi::GetPropertyString(env, item, "videoCodec");
917         ret = AVRecorderNapi::GetVideoCodecFormat(videoCodec, profile.videoCodecFormat);
918         CHECK_AND_RETURN_RET(ret == MSERR_OK,
919             (asyncCtx->AVRecorderSignError(ret, "GetVideoCodecFormat", "videoCodecFormat"), ret));
920 
921         ret = MSERR_INVALID_VAL;
922         CHECK_AND_RETURN_RET(CommonNapi::GetPropertyInt32(env, item, "videoBitrate", profile.videoBitrate),
923             (asyncCtx->AVRecorderSignError(ret, "GetvideoBitrate", "videoBitrate"), ret));
924         CHECK_AND_RETURN_RET(CommonNapi::GetPropertyInt32(env, item, "videoFrameWidth", profile.videoFrameWidth),
925             (asyncCtx->AVRecorderSignError(ret, "GetvideoFrameWidth", "videoFrameWidth"), ret));
926         CHECK_AND_RETURN_RET(CommonNapi::GetPropertyInt32(env, item, "videoFrameHeight", profile.videoFrameHeight),
927             (asyncCtx->AVRecorderSignError(ret, "GetvideoFrameHeight", "videoFrameHeight"), ret));
928         CHECK_AND_RETURN_RET(CommonNapi::GetPropertyInt32(env, item, "videoFrameRate", profile.videoFrameRate),
929             (asyncCtx->AVRecorderSignError(ret, "GetvideoFrameRate", "videoFrameRate"), ret));
930 
931         MEDIA_LOGI("videoBitrate %{public}d, videoCodecFormat %{public}d, videoFrameWidth %{public}d,"
932                    " videoFrameHeight %{public}d, videoFrameRate %{public}d",
933                    profile.videoBitrate, profile.videoCodecFormat, profile.videoFrameWidth,
934                    profile.videoFrameHeight, profile.videoFrameRate);
935     }
936 
937     std::string outputFile = CommonNapi::GetPropertyString(env, item, "fileFormat");
938     ret = AVRecorderNapi::GetOutputFormat(outputFile, profile.fileFormat);
939     CHECK_AND_RETURN_RET(ret == MSERR_OK,
940         (asyncCtx->AVRecorderSignError(ret, "GetOutputFormat", "fileFormat"), ret));
941     MEDIA_LOGI("fileFormat %{public}d", profile.fileFormat);
942 
943     return MSERR_OK;
944 }
945 
GetConfig(std::unique_ptr<AVRecorderAsyncContext> & asyncCtx,napi_env env,napi_value args)946 int32_t AVRecorderNapi::GetConfig(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx, napi_env env, napi_value args)
947 {
948     napi_valuetype valueType = napi_undefined;
949     if (args == nullptr || napi_typeof(env, args, &valueType) != napi_ok || valueType != napi_object) {
950         asyncCtx->AVRecorderSignError(MSERR_INVALID_VAL, "GetConfig", "AVRecorderConfig");
951         return MSERR_INVALID_VAL;
952     }
953 
954     asyncCtx->config_ = std::make_shared<AVRecorderConfig>();
955     CHECK_AND_RETURN_RET(asyncCtx->config_,
956         (asyncCtx->AVRecorderSignError(MSERR_NO_MEMORY, "AVRecorderConfig", "AVRecorderConfig"), MSERR_NO_MEMORY));
957 
958     std::shared_ptr<AVRecorderConfig> config = asyncCtx->config_;
959 
960     int32_t ret = GetSourceType(asyncCtx, env, args);
961     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "failed to GetSourceType");
962 
963     ret = GetProfile(asyncCtx, env, args);
964     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "failed to GetProfile");
965 
966     config->url = CommonNapi::GetPropertyString(env, args, "url");
967     MEDIA_LOGI("url %{public}s!", config->url.c_str());
968     CHECK_AND_RETURN_RET(config->url != "",
969         (asyncCtx->AVRecorderSignError(MSERR_INVALID_VAL, "geturl", "url"), MSERR_INVALID_VAL));
970 
971     bool getValue = false;
972     ret = AVRecorderNapi::GetPropertyInt32(env, args, "rotation", config->rotation, getValue);
973     CHECK_AND_RETURN_RET(ret == MSERR_OK,
974         (asyncCtx->AVRecorderSignError(ret, "getrotation", "rotation"), ret));
975     MEDIA_LOGI("rotation %{public}d!", config->rotation);
976     CHECK_AND_RETURN_RET((config->rotation == VIDEO_ROTATION_0 || config->rotation == VIDEO_ROTATION_90 ||
977         config->rotation == VIDEO_ROTATION_180 || config->rotation == VIDEO_ROTATION_270),
978         (asyncCtx->AVRecorderSignError(MSERR_INVALID_VAL, "getrotation", "rotation"), MSERR_INVALID_VAL));
979 
980     napi_value geoLocation = nullptr;
981     napi_get_named_property(env, args, "location", &geoLocation);
982     double tempLatitude = 0;
983     double tempLongitude = 0;
984     (void)CommonNapi::GetPropertyDouble(env, geoLocation, "latitude", tempLatitude);
985     (void)CommonNapi::GetPropertyDouble(env, geoLocation, "longitude", tempLongitude);
986     config->location.latitude = static_cast<float>(tempLatitude);
987     config->location.longitude = static_cast<float>(tempLongitude);
988 
989     return MSERR_OK;
990 }
991 
SetProfile(std::shared_ptr<AVRecorderConfig> config)992 RetInfo AVRecorderNapi::SetProfile(std::shared_ptr<AVRecorderConfig> config)
993 {
994     int32_t ret;
995     AVRecorderProfile &profile = config->profile;
996 
997     ret = recorder_->SetOutputFormat(profile.fileFormat);
998     CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetOutputFormat", "fileFormat"));
999 
1000     if (config->withAudio) {
1001         ret = recorder_->SetAudioEncoder(audioSourceID_, profile.audioCodecFormat);
1002         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetAudioEncoder", "audioCodecFormat"));
1003 
1004         ret = recorder_->SetAudioSampleRate(audioSourceID_, profile.auidoSampleRate);
1005         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetAudioSampleRate", "auidoSampleRate"));
1006 
1007         ret = recorder_->SetAudioChannels(audioSourceID_, profile.audioChannels);
1008         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetAudioChannels", "audioChannels"));
1009 
1010         ret = recorder_->SetAudioEncodingBitRate(audioSourceID_, profile.audioBitrate);
1011         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetAudioEncodingBitRate", "audioBitrate"));
1012     }
1013 
1014     if (config->withVideo) {
1015         ret = recorder_->SetVideoEncoder(videoSourceID_, profile.videoCodecFormat);
1016         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetVideoEncoder", "videoCodecFormat"));
1017 
1018         ret = recorder_->SetVideoSize(videoSourceID_, profile.videoFrameWidth, profile.videoFrameHeight);
1019         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetVideoSize", "VideoSize"));
1020 
1021         ret = recorder_->SetVideoFrameRate(videoSourceID_, profile.videoFrameRate);
1022         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetVideoFrameRate", "videoFrameRate"));
1023 
1024         ret = recorder_->SetVideoEncodingBitRate(videoSourceID_, profile.videoBitrate);
1025         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetVideoEncodingBitRate", "videoBitrate"));
1026     }
1027 
1028     return RetInfo(MSERR_EXT_API9_OK, "");
1029 }
1030 
Configure(std::shared_ptr<AVRecorderConfig> config)1031 RetInfo AVRecorderNapi::Configure(std::shared_ptr<AVRecorderConfig> config)
1032 {
1033     CHECK_AND_RETURN_RET(recorder_ != nullptr, GetRetInfo(MSERR_INVALID_OPERATION, "Configure", ""));
1034     CHECK_AND_RETURN_RET(config != nullptr, GetRetInfo(MSERR_INVALID_VAL, "Configure", "config"));
1035 
1036     if (hasConfiged_) {
1037         MEDIA_LOGE("AVRecorderConfig has been configured and will not be configured again");
1038         return RetInfo(MSERR_EXT_API9_OK, "");
1039     }
1040 
1041     int32_t ret;
1042     if (config->withAudio) {
1043         ret = recorder_->SetAudioSource(config->audioSourceType, audioSourceID_);
1044         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetAudioSource", "audioSourceType"));
1045     }
1046 
1047     if (config->withVideo) {
1048         ret = recorder_->SetVideoSource(config->videoSourceType, videoSourceID_);
1049         CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetVideoSource", "videoSourceType"));
1050     }
1051 
1052     RetInfo retInfo = SetProfile(config);
1053     CHECK_AND_RETURN_RET_LOG(retInfo.first == MSERR_OK, retInfo, "Fail to set videoBitrate");
1054 
1055     recorder_->SetLocation(config->location.latitude, config->location.longitude);
1056 
1057     if (config->withVideo) {
1058         recorder_->SetOrientationHint(config->rotation);
1059     }
1060 
1061     ret = MSERR_INVALID_VAL;
1062     const std::string fdHead = "fd://";
1063     CHECK_AND_RETURN_RET(config->url.find(fdHead) != std::string::npos, GetRetInfo(ret, "Getfd", "uri"));
1064     int32_t fd = -1;
1065     std::string inputFd = config->url.substr(fdHead.size());
1066     CHECK_AND_RETURN_RET(StrToInt(inputFd, fd) == true && fd >= 0, GetRetInfo(ret, "Getfd", "uri"));
1067 
1068     ret = recorder_->SetOutputFile(fd);
1069     CHECK_AND_RETURN_RET(ret == MSERR_OK, GetRetInfo(ret, "SetOutputFile", "uri"));
1070     hasConfiged_ = true;
1071 
1072     return RetInfo(MSERR_EXT_API9_OK, "");
1073 }
1074 
GetSourceIdAndQuality(std::unique_ptr<AVRecorderAsyncContext> & asyncCtx,napi_env env,napi_value sourceIdArgs,napi_value qualityArgs,const std::string & opt)1075 int32_t AVRecorderNapi::GetSourceIdAndQuality(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx,
1076     napi_env env, napi_value sourceIdArgs, napi_value qualityArgs, const std::string &opt)
1077 {
1078     if (asyncCtx->napi->CheckStateMachine(opt) == MSERR_OK) {
1079         napi_status ret = napi_get_value_int32(env, sourceIdArgs, &asyncCtx->napi->sourceId_);
1080         if (ret != napi_ok) {
1081             asyncCtx->AVRecorderSignError(MSERR_INVALID_VAL, "failed to get sourceId", "");
1082             return MSERR_INVALID_VAL;
1083         }
1084         ret = napi_get_value_int32(env, qualityArgs, &asyncCtx->napi->qualityLevel_);
1085         if (ret != napi_ok) {
1086             asyncCtx->AVRecorderSignError(MSERR_INVALID_VAL, "failed to get qualityLevel", "");
1087             return MSERR_INVALID_VAL;
1088         }
1089     } else {
1090         asyncCtx->AVRecorderSignError(MSERR_INVALID_OPERATION, opt, "");
1091         return MSERR_INVALID_OPERATION;
1092     }
1093     return MSERR_OK;
1094 }
1095 
GetAVRecorderProfile(std::shared_ptr<AVRecorderProfile> & profile,const int32_t sourceId,const int32_t qualityLevel)1096 int32_t AVRecorderNapi::GetAVRecorderProfile(std::shared_ptr<AVRecorderProfile> &profile,
1097     const int32_t sourceId, const int32_t qualityLevel)
1098 {
1099     MediaTrace trace("AVRecorder::GetAVRecorderProfile");
1100     std::shared_ptr<VideoRecorderProfile> videoRecorderProfile =
1101         OHOS::Media::RecorderProfilesFactory::CreateRecorderProfiles().GetVideoRecorderProfile(sourceId, qualityLevel);
1102     CHECK_AND_RETURN_RET_LOG(videoRecorderProfile != nullptr, MSERR_INVALID_VAL, "failed to get videoRecorderProfile");
1103 
1104     int32_t ret = MSERR_OK;
1105     ret = AVRecorderNapi::GetOutputFormat(videoRecorderProfile->containerFormatType, profile ->fileFormat);
1106     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL, "get outputFormat error");
1107 
1108     ret = AVRecorderNapi::GetAudioCodecFormat(videoRecorderProfile->audioCodec, profile ->audioCodecFormat);
1109     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL, "get audioCodec error");
1110 
1111     ret = AVRecorderNapi::GetVideoCodecFormat(videoRecorderProfile->videoCodec, profile ->videoCodecFormat);
1112     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL, "get videoCodec error");
1113 
1114     profile->audioBitrate = videoRecorderProfile->audioBitrate;
1115     profile->audioChannels = videoRecorderProfile->audioChannels;
1116     profile->auidoSampleRate = videoRecorderProfile->audioSampleRate;
1117     profile->videoBitrate = videoRecorderProfile->videoBitrate;
1118     profile->videoFrameWidth = videoRecorderProfile->videoFrameWidth;
1119     profile->videoFrameHeight = videoRecorderProfile->videoFrameHeight;
1120     profile->videoFrameRate = videoRecorderProfile->videoFrameRate;
1121 
1122     return MSERR_OK;
1123 }
1124 
ErrorCallback(int32_t errCode,const std::string & operate,const std::string & add)1125 void AVRecorderNapi::ErrorCallback(int32_t errCode, const std::string &operate, const std::string &add)
1126 {
1127     MEDIA_LOGE("failed to %{public}s, errCode = %{public}d", operate.c_str(), errCode);
1128     CHECK_AND_RETURN_LOG(recorderCb_ != nullptr, "recorderCb_ is nullptr!");
1129     auto napiCb = std::static_pointer_cast<AVRecorderCallback>(recorderCb_);
1130 
1131     MediaServiceExtErrCodeAPI9 err = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errCode));
1132     std::string msg = MSExtErrorAPI9ToString(err, operate, "") + add;
1133     napiCb->SendErrorCallback(errCode, msg);
1134 }
1135 
StateCallback(const std::string & state)1136 void AVRecorderNapi::StateCallback(const std::string &state)
1137 {
1138     MEDIA_LOGI("Change state to %{public}s", state.c_str());
1139     CHECK_AND_RETURN_LOG(recorderCb_ != nullptr, "recorderCb_ is nullptr!");
1140     auto napiCb = std::static_pointer_cast<AVRecorderCallback>(recorderCb_);
1141     napiCb->SendStateCallback(state, StateChangeReason::USER);
1142 }
1143 
SetCallbackReference(const std::string & callbackName,std::shared_ptr<AutoRef> ref)1144 void AVRecorderNapi::SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref)
1145 {
1146     eventCbMap_[callbackName] = ref;
1147     CHECK_AND_RETURN_LOG(recorderCb_ != nullptr, "recorderCb_ is nullptr!");
1148     auto napiCb = std::static_pointer_cast<AVRecorderCallback>(recorderCb_);
1149     napiCb->SaveCallbackReference(callbackName, ref);
1150 }
1151 
CancelCallbackReference(const std::string & callbackName)1152 void AVRecorderNapi::CancelCallbackReference(const std::string &callbackName)
1153 {
1154     CHECK_AND_RETURN_LOG(recorderCb_ != nullptr, "recorderCb_ is nullptr!");
1155     auto napiCb = std::static_pointer_cast<AVRecorderCallback>(recorderCb_);
1156     napiCb->CancelCallbackReference(callbackName);
1157     eventCbMap_[callbackName] = nullptr;
1158 }
1159 
CancelCallback()1160 void AVRecorderNapi::CancelCallback()
1161 {
1162     CHECK_AND_RETURN_LOG(recorderCb_ != nullptr, "recorderCb_ is nullptr!");
1163     auto napiCb = std::static_pointer_cast<AVRecorderCallback>(recorderCb_);
1164     napiCb->ClearCallbackReference();
1165 }
1166 
RemoveSurface()1167 void AVRecorderNapi::RemoveSurface()
1168 {
1169     if (surface_ != nullptr) {
1170         auto id = surface_->GetUniqueId();
1171         auto surface = SurfaceUtils::GetInstance()->GetSurface(id);
1172         if (surface) {
1173             (void)SurfaceUtils::GetInstance()->Remove(id);
1174         }
1175         surface_ = nullptr;
1176     }
1177 }
1178 
GetPropertyInt32(napi_env env,napi_value configObj,const std::string & type,int32_t & result,bool & getValue)1179 int32_t AVRecorderNapi::GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result,
1180     bool &getValue)
1181 {
1182     napi_value item = nullptr;
1183     bool exist = false;
1184     getValue = false;
1185     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
1186     if (status != napi_ok || !exist) {
1187         MEDIA_LOGI("can not find %{public}s property", type.c_str());
1188         return MSERR_OK;
1189     }
1190 
1191     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
1192         MEDIA_LOGI("get %{public}s property fail", type.c_str());
1193         return MSERR_UNKNOWN;
1194     }
1195 
1196     if (napi_get_value_int32(env, item, &result) != napi_ok) {
1197         std::string string = CommonNapi::GetStringArgument(env, item);
1198         if (string == "") {
1199             // This attribute has not been assigned
1200             return MSERR_OK;
1201         } else {
1202             MEDIA_LOGE("get %{public}s property value fail", type.c_str());
1203             return MSERR_INVALID_VAL;
1204         }
1205     }
1206 
1207     MEDIA_LOGI("get %{public}s : %{public}d!", type.c_str(), result);
1208     getValue = true;
1209     return MSERR_OK;
1210 }
1211 
GetJsResult(napi_env env,napi_value & result)1212 napi_status MediaJsAVRecorderProfile::GetJsResult(napi_env env, napi_value &result)
1213 {
1214     napi_status ret = napi_ok;
1215     bool setRet = true;
1216     int32_t setState = MSERR_OK;
1217     CHECK_AND_RETURN_RET(value_ != nullptr, napi_generic_failure);
1218     CHECK_AND_RETURN_RET((ret = napi_create_object(env, &result)) == napi_ok, ret);
1219 
1220     setRet = CommonNapi::SetPropertyInt32(env, result, "audioBitrate", value_->audioBitrate);
1221     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1222     setRet = CommonNapi::SetPropertyInt32(env, result, "audioChannels", value_->audioChannels);
1223     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1224 
1225     std::string audioCodec;
1226     setState = SetAudioCodecFormat(value_->audioCodecFormat, audioCodec);
1227     CHECK_AND_RETURN_RET(setState == MSERR_OK, napi_generic_failure);
1228     setRet = CommonNapi::SetPropertyString(env, result, "audioCodec", audioCodec);
1229     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1230 
1231     setRet = CommonNapi::SetPropertyInt32(env, result, "audioSampleRate", value_->auidoSampleRate);
1232     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1233 
1234     std::string fileFormat;
1235     setState = SetFileFormat(value_->fileFormat, fileFormat);
1236     CHECK_AND_RETURN_RET(setState == MSERR_OK, napi_generic_failure);
1237     setRet = CommonNapi::SetPropertyString(env, result, "fileFormat", fileFormat);
1238     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1239 
1240     setRet = CommonNapi::SetPropertyInt32(env, result, "videoBitrate", value_->videoBitrate);
1241     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1242 
1243     std::string videoCodec;
1244     setState = SetVideoCodecFormat(value_->videoCodecFormat, videoCodec);
1245     CHECK_AND_RETURN_RET(setState == MSERR_OK, napi_generic_failure);
1246     setRet = CommonNapi::SetPropertyString(env, result, "videoCodec", videoCodec);
1247     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1248 
1249     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1250     setRet = CommonNapi::SetPropertyInt32(env, result, "videoFrameWidth", value_->videoFrameWidth);
1251     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1252     setRet = CommonNapi::SetPropertyInt32(env, result, "videoFrameHeight", value_->videoFrameHeight);
1253     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1254     setRet = CommonNapi::SetPropertyInt32(env, result, "videoFrameRate", value_->videoFrameRate);
1255     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
1256 
1257     return ret;
1258 }
1259 
SetAudioCodecFormat(AudioCodecFormat & codecFormat,std::string & mime)1260 int32_t MediaJsAVRecorderProfile::SetAudioCodecFormat(AudioCodecFormat &codecFormat, std::string &mime)
1261 {
1262     MEDIA_LOGI("audioCodecFormat %{public}d", codecFormat);
1263     const std::map<AudioCodecFormat, std::string_view> codecFormatToMimeStr = {
1264         { AudioCodecFormat::AAC_LC, CodecMimeType::AUDIO_AAC },
1265         { AudioCodecFormat::AUDIO_DEFAULT, "" },
1266     };
1267 
1268     auto iter = codecFormatToMimeStr.find(codecFormat);
1269     if (iter != codecFormatToMimeStr.end()) {
1270         mime = iter->second;
1271         return MSERR_OK;
1272     }
1273     return MSERR_INVALID_VAL;
1274 }
1275 
SetVideoCodecFormat(VideoCodecFormat & codecFormat,std::string & mime)1276 int32_t MediaJsAVRecorderProfile::SetVideoCodecFormat(VideoCodecFormat &codecFormat, std::string &mime)
1277 {
1278     MEDIA_LOGI("VideoCodecFormat %{public}d", codecFormat);
1279     const std::map<VideoCodecFormat, std::string_view> codecFormatTomimeStr = {
1280         { VideoCodecFormat::H264, CodecMimeType::VIDEO_AVC },
1281         { VideoCodecFormat::MPEG4, CodecMimeType::VIDEO_MPEG4 },
1282         { VideoCodecFormat::VIDEO_DEFAULT, ""},
1283     };
1284 
1285     auto iter = codecFormatTomimeStr.find(codecFormat);
1286     if (iter != codecFormatTomimeStr.end()) {
1287         mime = iter->second;
1288         return MSERR_OK;
1289     }
1290     return MSERR_INVALID_VAL;
1291 }
1292 
SetFileFormat(OutputFormatType & type,std::string & extension)1293 int32_t MediaJsAVRecorderProfile::SetFileFormat(OutputFormatType &type, std::string &extension)
1294 {
1295     MEDIA_LOGI("OutputFormatType %{public}d", type);
1296     const std::map<OutputFormatType, std::string> outputFormatToextension = {
1297         { OutputFormatType::FORMAT_MPEG_4, "mp4" },
1298         { OutputFormatType::FORMAT_M4A, "m4a" },
1299         { OutputFormatType::FORMAT_DEFAULT, "" },
1300     };
1301 
1302     auto iter = outputFormatToextension.find(type);
1303     if (iter != outputFormatToextension.end()) {
1304         extension = iter->second;
1305         return MSERR_OK;
1306     }
1307     return MSERR_INVALID_VAL;
1308 }
1309 
AVRecorderSignError(int32_t errCode,const std::string & operate,const std::string & param,const std::string & add)1310 void AVRecorderAsyncContext::AVRecorderSignError(int32_t errCode, const std::string &operate,
1311     const std::string &param, const std::string &add)
1312 {
1313     RetInfo retInfo = GetRetInfo(errCode, operate, param, add);
1314     SignError(retInfo.first, retInfo.second);
1315 }
1316 } // namespace Media
1317 } // namespace OHOS