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 #ifndef AV_RECORDER_NAPI_H 17 #define AV_RECORDER_NAPI_H 18 19 #include "recorder.h" 20 #include "av_common.h" 21 #include "media_errors.h" 22 #include "napi/native_api.h" 23 #include "napi/native_node_api.h" 24 #include "common_napi.h" 25 #include "task_queue.h" 26 27 namespace OHOS { 28 namespace Media { 29 /* type AVRecorderState = 'idle' | 'prepared' | 'started' | 'paused' | 'stopped' | 'released' | 'error'; */ 30 namespace AVRecorderState { 31 const std::string STATE_IDLE = "idle"; 32 const std::string STATE_PREPARED = "prepared"; 33 const std::string STATE_STARTED = "started"; 34 const std::string STATE_PAUSED = "paused"; 35 const std::string STATE_STOPPED = "stopped"; 36 const std::string STATE_RELEASED = "released"; 37 const std::string STATE_ERROR = "error"; 38 } 39 40 namespace AVRecordergOpt { 41 const std::string PREPARE = "Prepare"; 42 const std::string GETINPUTSURFACE = "GetInputSurface"; 43 const std::string START = "Start"; 44 const std::string PAUSE = "Pause"; 45 const std::string RESUME = "Resume"; 46 const std::string STOP = "Stop"; 47 const std::string RESET = "Reset"; 48 const std::string RELEASE = "Release"; 49 } 50 51 constexpr int32_t AVRECORDER_DEFAULT_AUDIO_BIT_RATE = 48000; 52 constexpr int32_t AVRECORDER_DEFAULT_AUDIO_CHANNELS = 2; 53 constexpr int32_t AVRECORDER_DEFAULT_AUDIO_SAMPLE_RATE = 48000; 54 constexpr int32_t AVRECORDER_DEFAULT_VIDEO_BIT_RATE = 48000; 55 constexpr int32_t AVRECORDER_DEFAULT_FRAME_HEIGHT = -1; 56 constexpr int32_t AVRECORDER_DEFAULT_FRAME_WIDTH = -1; 57 constexpr int32_t AVRECORDER_DEFAULT_FRAME_RATE = 30; 58 59 /** 60 * on(type: 'stateChange', callback: (state: AVPlayerState, reason: StateChangeReason) => void): void 61 * on(type: 'error', callback: ErrorCallback): void 62 */ 63 namespace AVRecorderEvent { 64 const std::string EVENT_STATE_CHANGE = "stateChange"; 65 const std::string EVENT_ERROR = "error"; 66 } 67 68 struct AVRecorderAsyncContext; 69 struct AVRecorderProfile { 70 int32_t audioBitrate = AVRECORDER_DEFAULT_AUDIO_BIT_RATE; 71 int32_t audioChannels = AVRECORDER_DEFAULT_AUDIO_CHANNELS; 72 int32_t auidoSampleRate = AVRECORDER_DEFAULT_AUDIO_SAMPLE_RATE; 73 AudioCodecFormat audioCodecFormat = AudioCodecFormat::AUDIO_DEFAULT; 74 75 int32_t videoBitrate = AVRECORDER_DEFAULT_VIDEO_BIT_RATE; 76 int32_t videoFrameWidth = AVRECORDER_DEFAULT_FRAME_HEIGHT; 77 int32_t videoFrameHeight = AVRECORDER_DEFAULT_FRAME_WIDTH; 78 int32_t videoFrameRate = AVRECORDER_DEFAULT_FRAME_RATE; 79 VideoCodecFormat videoCodecFormat = VideoCodecFormat::VIDEO_DEFAULT; 80 81 OutputFormatType fileFormat = OutputFormatType::FORMAT_DEFAULT; 82 }; 83 84 struct AVRecorderConfig { 85 AudioSourceType audioSourceType; // source type; 86 VideoSourceType videoSourceType; 87 AVRecorderProfile profile; 88 std::string url; 89 int32_t rotation = 0; // Optional 90 Location location; // Optional 91 bool withVideo = false; 92 bool withAudio = false; 93 }; 94 95 using RetInfo = std::pair<int32_t, std::string>; 96 97 class AVRecorderNapi { 98 public: 99 __attribute__((visibility("default"))) static napi_value Init(napi_env env, napi_value exports); 100 101 using AvRecorderTaskqFunc = RetInfo (AVRecorderNapi::*)(); 102 103 private: 104 static napi_value Constructor(napi_env env, napi_callback_info info); 105 static void Destructor(napi_env env, void *nativeObject, void *finalize); 106 /** 107 * createAVRecorder(callback: AsyncCallback<VideoPlayer>): void 108 * createAVRecorder(): Promise<VideoPlayer> 109 */ 110 static napi_value JsCreateAVRecorder(napi_env env, napi_callback_info info); 111 /** 112 * prepare(config: AVRecorderConfig, callback: AsyncCallback<void>): void; 113 * prepare(config: AVRecorderConfig): Promise<void>; 114 */ 115 static napi_value JsPrepare(napi_env env, napi_callback_info info); 116 /** 117 * getInputSurface(callback: AsyncCallback<string>): void 118 * getInputSurface(): Promise<string> 119 */ 120 static napi_value JsGetInputSurface(napi_env env, napi_callback_info info); 121 /** 122 * start(callback: AsyncCallback<void>): void; 123 * start(): Promise<void>; 124 */ 125 static napi_value JsStart(napi_env env, napi_callback_info info); 126 /** 127 * pause(callback: AsyncCallback<void>): void; 128 * pause(): Promise<void>; 129 */ 130 static napi_value JsPause(napi_env env, napi_callback_info info); 131 /** 132 * resume(callback: AsyncCallback<void>): void; 133 * resume(): Promise<void>; 134 */ 135 static napi_value JsResume(napi_env env, napi_callback_info info); 136 /** 137 * stop(callback: AsyncCallback<void>): void; 138 * stop(): Promise<void>; 139 */ 140 static napi_value JsStop(napi_env env, napi_callback_info info); 141 /** 142 * reset(callback: AsyncCallback<void>): void 143 * reset(): Promise<void> 144 */ 145 static napi_value JsReset(napi_env env, napi_callback_info info); 146 /** 147 * release(callback: AsyncCallback<void>): void 148 * release(): Promise<void> 149 */ 150 static napi_value JsRelease(napi_env env, napi_callback_info info); 151 /** 152 * on(type: 'stateChange', callback: (state: AVPlayerState, reason: StateChangeReason) => void): void 153 * on(type: 'error', callback: ErrorCallback): void 154 */ 155 static napi_value JsSetEventCallback(napi_env env, napi_callback_info info); 156 /** 157 * off(type: 'stateChange'): void; 158 * off(type: 'error'): void; 159 */ 160 static napi_value JsCancelEventCallback(napi_env env, napi_callback_info info); 161 /** 162 * readonly state: AVRecorderState; 163 */ 164 static napi_value JsGetState(napi_env env, napi_callback_info info); 165 166 static AVRecorderNapi* GetJsInstanceAndArgs(napi_env env, napi_callback_info info, 167 size_t &argCount, napi_value *args); 168 static std::shared_ptr<TaskHandler<RetInfo>> GetPrepareTask(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx); 169 static std::shared_ptr<TaskHandler<RetInfo>> GetPromiseTask(AVRecorderNapi *avnapi, const std::string &opt); 170 static napi_value ExecuteByPromise(napi_env env, napi_callback_info info, const std::string &opt); 171 172 static int32_t GetAudioCodecFormat(const std::string &mime, AudioCodecFormat &codecFormat); 173 static int32_t GetVideoCodecFormat(const std::string &mime, VideoCodecFormat &codecFormat); 174 static int32_t GetOutputFormat(const std::string &extension, OutputFormatType &type); 175 176 static int32_t GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result, 177 bool &getValue); 178 179 AVRecorderNapi(); 180 ~AVRecorderNapi(); 181 182 RetInfo GetInputSurface(); 183 RetInfo Start(); 184 RetInfo Pause(); 185 RetInfo Resume(); 186 RetInfo Stop(); 187 RetInfo Reset(); 188 RetInfo Release(); 189 190 void ErrorCallback(int32_t errCode, const std::string &operate, const std::string &add = ""); 191 void StateCallback(const std::string &state); 192 void SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref); 193 void CancelCallbackReference(const std::string &callbackName); 194 void CancelCallback(); 195 void RemoveSurface(); 196 197 int32_t CheckStateMachine(const std::string &opt); 198 int32_t CheckRepeatOperation(const std::string &opt); 199 int32_t GetSourceType(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx, napi_env env, napi_value args); 200 int32_t GetProfile(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx, napi_env env, napi_value args); 201 int32_t GetConfig(std::unique_ptr<AVRecorderAsyncContext> &asyncCtx, napi_env env, napi_value args); 202 RetInfo SetProfile(std::shared_ptr<AVRecorderConfig> config); 203 RetInfo Configure(std::shared_ptr<AVRecorderConfig> config); 204 205 static thread_local napi_ref constructor_; 206 napi_env env_ = nullptr; 207 std::shared_ptr<Recorder> recorder_ = nullptr; 208 std::shared_ptr<RecorderCallback> recorderCb_ = nullptr; 209 std::map<std::string, std::shared_ptr<AutoRef>> eventCbMap_; 210 std::unique_ptr<TaskQueue> taskQue_; 211 static std::map<std::string, AvRecorderTaskqFunc> taskQFuncs_; 212 sptr<Surface> surface_ = nullptr; 213 int32_t videoSourceID_ = -1; 214 int32_t audioSourceID_ = -1; 215 bool withVideo_ = false; 216 bool getVideoInputSurface_ = false; 217 }; 218 219 struct AVRecorderAsyncContext : public MediaAsyncContext { AVRecorderAsyncContextAVRecorderAsyncContext220 explicit AVRecorderAsyncContext(napi_env env) : MediaAsyncContext(env) {} 221 ~AVRecorderAsyncContext() = default; 222 223 void AVRecorderSignError(int32_t errCode, const std::string &operate, 224 const std::string ¶m, const std::string &add = ""); 225 226 AVRecorderNapi *napi = nullptr; 227 std::shared_ptr<AVRecorderConfig> config_ = nullptr; 228 std::string opt_ = ""; 229 std::shared_ptr<TaskHandler<RetInfo>> task_ = nullptr; 230 }; 231 } // namespace Media 232 } // namespace OHOS 233 #endif // AV_RECORDER_NAPI_H