• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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![Recording Development Process](figures/recording-development-process.png)
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