1# Camera Recording Sample (ArkTS) 2 3This topic provides sample code that covers the complete recording process to help you understand the complete API calling sequence. 4 5Before referring to the sample code, you are advised to read [Device Input Management](camera-device-input.md), [Camera Session Management](camera-session-management.md), [Camera Recording](camera-recording.md), and other related topics in [Camera Development (ArkTS)](camera-preparation.md). 6 7## Development Process 8 9After obtaining the output stream capabilities supported by the camera, create a video stream. The development process is as follows: 10 11 12 13 14## Sample Code 15For details about how to obtain the context, see [Obtaining the Context of UIAbility](../application-models/uiability-usage.md#obtaining-the-context-of-uiability). 16 17```ts 18import camera from '@ohos.multimedia.camera'; 19import { BusinessError } from '@ohos.base'; 20import media from '@ohos.multimedia.media'; 21import common from '@ohos.app.ability.common'; 22import PhotoAccessHelper from '@ohos.file.photoAccessHelper'; 23import fs from '@ohos.file.fs'; 24 25async function videoRecording(context: common.Context, surfaceId: string): Promise<void> { 26 // Create a CameraManager instance. 27 let cameraManager: camera.CameraManager = camera.getCameraManager(context); 28 if (!cameraManager) { 29 console.error("camera.getCameraManager error"); 30 return; 31 } 32 33 // Listen for camera status changes. 34 cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { 35 console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); 36 console.info(`status: ${cameraStatusInfo.status}`); 37 }); 38 39 // Obtain the camera list. 40 let cameraArray: Array<camera.CameraDevice> = []; 41 try { 42 cameraArray = cameraManager.getSupportedCameras(); 43 } catch (error) { 44 let err = error as BusinessError; 45 console.error(`getSupportedCameras call failed. error code: ${err.code}`); 46 } 47 48 if (cameraArray.length <= 0) { 49 console.error("cameraManager.getSupportedCameras error"); 50 return; 51 } 52 53 // Obtain the supported modes. 54 let sceneModes: Array<camera.SceneMode> = cameraManager.getSupportedSceneModes(cameraArray[0]); 55 let isSupportVideoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_VIDEO) >= 0; 56 if (!isSupportVideoMode) { 57 console.error('video mode not support'); 58 return; 59 } 60 61 // Obtain the output stream capabilities supported by the camera. 62 let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0], camera.SceneMode.NORMAL_VIDEO); 63 if (!cameraOutputCap) { 64 console.error("cameraManager.getSupportedOutputCapability error") 65 return; 66 } 67 console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); 68 69 let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles; 70 if (!previewProfilesArray) { 71 console.error("createOutput previewProfilesArray == null || undefined"); 72 } 73 74 let photoProfilesArray: Array<camera.Profile> = cameraOutputCap.photoProfiles; 75 if (!photoProfilesArray) { 76 console.error("createOutput photoProfilesArray == null || undefined"); 77 } 78 79 let videoProfilesArray: Array<camera.VideoProfile> = cameraOutputCap.videoProfiles; 80 if (!videoProfilesArray) { 81 console.error("createOutput videoProfilesArray == null || undefined"); 82 } 83 // The width and height of videoProfile must be the same as those of AVRecorderProfile. 84 let videoSize: camera.Size = { 85 width: 640, 86 height: 480 87 } 88 let videoProfile: undefined | camera.VideoProfile = videoProfilesArray.find((profile: camera.VideoProfile) => { 89 return profile.size.width === videoSize.width && profile.size.height === videoSize.height; 90 }); 91 if (!videoProfile) { 92 console.error('videoProfile is not found'); 93 return; 94 } 95 // Configure the parameters based on those supported by the hardware device. 96 let aVRecorderProfile: media.AVRecorderProfile = { 97 audioBitrate: 48000, 98 audioChannels: 2, 99 audioCodec: media.CodecMimeType.AUDIO_AAC, 100 audioSampleRate: 48000, 101 fileFormat: media.ContainerFormatType.CFT_MPEG_4, 102 videoBitrate: 2000000, 103 videoCodec: media.CodecMimeType.VIDEO_AVC, 104 videoFrameWidth: videoSize.width, 105 videoFrameHeight: videoSize.height, 106 videoFrameRate: 30 107 }; 108 let options: PhotoAccessHelper.CreateOptions = { 109 title: Date.now().toString() 110 }; 111 let photoAccessHelper: PhotoAccessHelper.PhotoAccessHelper = PhotoAccessHelper.getPhotoAccessHelper(context); 112 let videoUri: string = await photoAccessHelper.createAsset(PhotoAccessHelper.PhotoType.VIDEO, 'mp4', options); 113 let file: fs.File = fs.openSync(videoUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 114 let aVRecorderConfig: media.AVRecorderConfig = { 115 audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, 116 videoSourceType: media.VideoSourceType.VIDEO_SOURCE_TYPE_SURFACE_YUV, 117 profile: aVRecorderProfile, 118 url: `fd://${file.fd.toString()}`, // Before passing in a file descriptor to this parameter, the file must be created by the caller and granted with the read and write permissions. Example value: fd://45--file:///data/media/01.mp4. 119 rotation: 0, // The value can be 0, 90, 180, or 270. If any other value is used, prepare() reports an error. 120 location: { latitude: 30, longitude: 130 } 121 }; 122 123 let avRecorder: media.AVRecorder | undefined = undefined; 124 try { 125 avRecorder = await media.createAVRecorder(); 126 } catch (error) { 127 let err = error as BusinessError; 128 console.error(`createAVRecorder call failed. error code: ${err.code}`); 129 } 130 131 if (avRecorder === undefined) { 132 return; 133 } 134 135 try { 136 await avRecorder.prepare(aVRecorderConfig); 137 } catch (error) { 138 let err = error as BusinessError; 139 console.error(`prepare call failed. error code: ${err.code}`); 140 } 141 142 let videoSurfaceId: string | undefined = undefined; // The surfaceID is passed in to the camera API to create a VideoOutput instance. 143 try { 144 videoSurfaceId = await avRecorder.getInputSurface(); 145 } catch (error) { 146 let err = error as BusinessError; 147 console.error(`getInputSurface call failed. error code: ${err.code}`); 148 } 149 if (videoSurfaceId === undefined) { 150 return; 151 } 152 // Create a VideoOutput instance. 153 let videoOutput: camera.VideoOutput | undefined = undefined; 154 try { 155 videoOutput = cameraManager.createVideoOutput(videoProfile, videoSurfaceId); 156 } catch (error) { 157 let err = error as BusinessError; 158 console.error(`Failed to create the videoOutput instance. error: ${JSON.stringify(err)}`); 159 } 160 if (videoOutput === undefined) { 161 return; 162 } 163 // Listen for video output errors. 164 videoOutput.on('error', (error: BusinessError) => { 165 console.error(`Preview output error code: ${error.code}`); 166 }); 167 168 // Create a session. 169 let videoSession: camera.CaptureSession | undefined = undefined; 170 try { 171 videoSession = cameraManager.createSession(camera.SceneMode.NORMAL_VIDEO) as camera.VideoSession; 172 } catch (error) { 173 let err = error as BusinessError; 174 console.error(`Failed to create the session instance. error: ${JSON.stringify(err)}`); 175 } 176 if (videoSession === undefined) { 177 return; 178 } 179 // Listen for session errors. 180 videoSession.on('error', (error: BusinessError) => { 181 console.error(`Video session error code: ${error.code}`); 182 }); 183 184 // Start configuration for the session. 185 try { 186 videoSession.beginConfig(); 187 } catch (error) { 188 let err = error as BusinessError; 189 console.error(`Failed to beginConfig. error: ${JSON.stringify(err)}`); 190 } 191 192 // Create a camera input stream. 193 let cameraInput: camera.CameraInput | undefined = undefined; 194 try { 195 cameraInput = cameraManager.createCameraInput(cameraArray[0]); 196 } catch (error) { 197 let err = error as BusinessError; 198 console.error(`Failed to createCameraInput. error: ${JSON.stringify(err)}`); 199 } 200 if (cameraInput === undefined) { 201 return; 202 } 203 // Listen for camera input errors. 204 let cameraDevice: camera.CameraDevice = cameraArray[0]; 205 cameraInput.on('error', cameraDevice, (error: BusinessError) => { 206 console.error(`Camera input error code: ${error.code}`); 207 }); 208 209 // Open the camera. 210 try { 211 await cameraInput.open(); 212 } catch (error) { 213 let err = error as BusinessError; 214 console.error(`Failed to open cameraInput. error: ${JSON.stringify(err)}`); 215 } 216 217 // Add the camera input stream to the session. 218 try { 219 videoSession.addInput(cameraInput); 220 } catch (error) { 221 let err = error as BusinessError; 222 console.error(`Failed to add cameraInput. error: ${JSON.stringify(err)}`); 223 } 224 225 // Create a preview output stream. For details about the surfaceId parameter, see the <XComponent>. The preview stream is the surface provided by the <XComponent>. 226 let previewOutput: camera.PreviewOutput | undefined = undefined; 227 try { 228 previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); 229 } catch (error) { 230 let err = error as BusinessError; 231 console.error(`Failed to create the PreviewOutput instance. error: ${JSON.stringify(err)}`); 232 } 233 234 if (previewOutput === undefined) { 235 return; 236 } 237 // Add the preview output stream to the session. 238 try { 239 videoSession.addOutput(previewOutput); 240 } catch (error) { 241 let err = error as BusinessError; 242 console.error(`Failed to add previewOutput. error: ${JSON.stringify(err)}`); 243 } 244 245 // Add a video output stream to the session. 246 try { 247 videoSession.addOutput(videoOutput); 248 } catch (error) { 249 let err = error as BusinessError; 250 console.error(`Failed to add videoOutput. error: ${JSON.stringify(err)}`); 251 } 252 253 // Commit the session configuration. 254 try { 255 await videoSession.commitConfig(); 256 } catch (error) { 257 let err = error as BusinessError; 258 console.error(`videoSession commitConfig error: ${JSON.stringify(err)}`); 259 } 260 261 // Start the session. 262 try { 263 await videoSession.start(); 264 } catch (error) { 265 let err = error as BusinessError; 266 console.error(`videoSession start error: ${JSON.stringify(err)}`); 267 } 268 269 // Start the video output stream. 270 videoOutput.start((err: BusinessError) => { 271 if (err) { 272 console.error(`Failed to start the video output. error: ${JSON.stringify(err)}`); 273 return; 274 } 275 console.info('Callback invoked to indicate the video output start success.'); 276 }); 277 278 // Start video recording. 279 try { 280 await avRecorder.start(); 281 } catch (error) { 282 let err = error as BusinessError; 283 console.error(`avRecorder start error: ${JSON.stringify(err)}`); 284 } 285 286 // Stop the video output stream. 287 videoOutput.stop((err: BusinessError) => { 288 if (err) { 289 console.error(`Failed to stop the video output. error: ${JSON.stringify(err)}`); 290 return; 291 } 292 console.info('Callback invoked to indicate the video output stop success.'); 293 }); 294 295 // Stop video recording. 296 try { 297 await avRecorder.stop(); 298 } catch (error) { 299 let err = error as BusinessError; 300 console.error(`avRecorder stop error: ${JSON.stringify(err)}`); 301 } 302 303 // Stop the session. 304 videoSession.stop(); 305 306 // Close the files. 307 fs.closeSync(file); 308 309 // Release the camera input stream. 310 cameraInput.close(); 311 312 // Release the preview output stream. 313 previewOutput.release(); 314 315 // Release the video output stream. 316 videoOutput.release(); 317 318 // Release the session. 319 videoSession.release(); 320 321 // Set the session to null. 322 videoSession = undefined; 323} 324``` 325