• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Video Recording (ArkTS)
2<!--Kit: Camera Kit-->
3<!--Subsystem: Multimedia-->
4<!--Owner: @qano-->
5<!--SE: @leo_ysl-->
6<!--TSE: @xchaosioda-->
7
8As another important function of the camera application, video recording is the process of cyclic frame capture. To smooth video recording, you can follow step 4 in [Photo Capture](camera-shooting.md) to set the resolution, flash, focal length, photo quality, and rotation angle.
9
10## How to Develop
11
12Read [Module Description](../../reference/apis-camera-kit/arkts-apis-camera.md) for the API reference.
13
141. Import the media module.
15
16   The [APIs](../../reference/apis-media-kit/arkts-apis-media.md) provided by this module are used to obtain the surface ID and create a video output stream.
17
18   ```ts
19   import { BusinessError } from '@kit.BasicServicesKit';
20   import { camera } from '@kit.CameraKit';
21   import { media } from '@kit.MediaKit';
22   ```
23
242. Create a surface.
25
26   Call **createAVRecorder()** of the media module to create an AVRecorder instance, and call [getInputSurface](../../reference/apis-media-kit/arkts-apis-media-AVRecorder.md#getinputsurface9) of the instance to obtain the surface ID, which is associated with the video output stream to process the stream data.
27
28   ```ts
29   async function getVideoSurfaceId(aVRecorderConfig: media.AVRecorderConfig): Promise<string | undefined> {  // For details about aVRecorderConfig, see the next section.
30     let avRecorder: media.AVRecorder | undefined = undefined;
31     try {
32       avRecorder = await media.createAVRecorder();
33     } catch (error) {
34       let err = error as BusinessError;
35       console.error(`createAVRecorder call failed. error code: ${err.code}`);
36     }
37     if (avRecorder === undefined) {
38       return undefined;
39     }
40     avRecorder.prepare(aVRecorderConfig, (err: BusinessError) => {
41       if (err == null) {
42         console.info('prepare success');
43       } else {
44         console.error('prepare failed and error is ' + err.message);
45       }
46     });
47     let videoSurfaceId = await avRecorder.getInputSurface();
48     return videoSurfaceId;
49   }
50   ```
51
523. Create a video output stream.
53
54   Obtain the video output streams supported by the current device from **videoProfiles** in the [CameraOutputCapability](../../reference/apis-camera-kit/arkts-apis-camera-i.md#cameraoutputcapability) class. Then, define video recording parameters and use [createVideoOutput](../../reference/apis-camera-kit/arkts-apis-camera-CameraManager.md#createvideooutput) to create a video output stream.
55
56   > **NOTE**
57   >
58   > 1. The preview stream and video output stream must have the same aspect ratio of the resolution. For example, the aspect ratio in the code snippet below is 640:480 (which is equal to 4:3), then the aspect ratio of the resolution of the preview stream must also be 4:3. This means that the resolution can be 640:480, 960:720, 1440:1080, or the like.
59   >
60   > 2. Before setting the resolution width and height of the preview output stream, call [AVRecorderProfile](../../reference/apis-media-kit/arkts-apis-media-i.md#avrecorderprofile9) to obtain the configurable width and height range for video frames.
61   >
62   > 3. To obtain the video rotation angle (specified by **rotation**), call [getVideoRotation](../../reference/apis-camera-kit/arkts-apis-camera-VideoOutput.md#getvideorotation12) in the [VideoOutput](../../reference/apis-camera-kit/arkts-apis-camera-VideoOutput.md) class.
63   >
64   > 4. To configure the frame rate for a video output stream, select a suitable **videoProfile** from **videoProfiles** of the [CameraOutputCapability](../../reference/apis-camera-kit/arkts-apis-camera-i.md#cameraoutputcapability) class. Ensure that [frameRateRange](../../reference/apis-camera-kit/arkts-apis-camera-i.md#frameraterange) of the selected profile meets your service requirements.
65
66   ```ts
67   async function getVideoOutput(cameraManager: camera.CameraManager, videoSurfaceId: string, cameraOutputCapability: camera.CameraOutputCapability): Promise<camera.VideoOutput | undefined> {
68     let videoProfilesArray: Array<camera.VideoProfile> = cameraOutputCapability.videoProfiles;
69     if (!videoProfilesArray) {
70       console.error("createOutput videoProfilesArray == null || undefined");
71       return undefined;
72     }
73     // AVRecorderProfile.
74     let aVRecorderProfile: media.AVRecorderProfile = {
75       fileFormat: media.ContainerFormatType.CFT_MPEG_4, // Video file container format. Only MP4 is supported.
76       videoBitrate: 100000, // Video bit rate.
77       videoCodec: media.CodecMimeType.VIDEO_AVC, // Video file encoding format. AVC is supported.
78       videoFrameWidth: 640, // Video frame width.
79       videoFrameHeight: 480, // Video frame height.
80       videoFrameRate: 30 // Video frame rate.
81     };
82     // Define video recording parameters. The ratio of the resolution width (videoFrameWidth) to the resolution height (videoFrameHeight) of the video output stream must be the same as that of the preview stream.
83     let aVRecorderConfig: media.AVRecorderConfig = {
84       videoSourceType: media.VideoSourceType.VIDEO_SOURCE_TYPE_SURFACE_YUV,
85       profile: aVRecorderProfile,
86       url: 'fd://35',
87       rotation: 90 // The value of rotation is 90, which is obtained through getPhotoRotation.
88     };
89     // Create an AVRecorder instance.
90     let avRecorder: media.AVRecorder | undefined = undefined;
91     try {
92       avRecorder = await media.createAVRecorder();
93     } catch (error) {
94       let err = error as BusinessError;
95       console.error(`createAVRecorder call failed. error code: ${err.code}`);
96     }
97     if (avRecorder === undefined) {
98       return undefined;
99     }
100     // Set video recording parameters.
101     avRecorder.prepare(aVRecorderConfig);
102     // Create a VideoOutput instance.
103     let videoOutput: camera.VideoOutput | undefined = undefined;
104     // The width and height of the videoProfile object passed in by createVideoOutput must be the same as those of aVRecorderProfile.
105     let videoProfile: undefined | camera.VideoProfile = videoProfilesArray.find((profile: camera.VideoProfile) => {
106       return profile.size.width === aVRecorderProfile.videoFrameWidth && profile.size.height === aVRecorderProfile.videoFrameHeight;
107     });
108     if (!videoProfile) {
109       console.error('videoProfile is not found');
110       return;
111     }
112     try {
113       videoOutput = cameraManager.createVideoOutput(videoProfile, videoSurfaceId);
114     } catch (error) {
115       let err = error as BusinessError;
116       console.error('Failed to create the videoOutput instance. errorCode = ' + err.code);
117     }
118     return videoOutput;
119   }
120   ```
121
1224. Start video recording.
123
124   Call [start](../../reference/apis-camera-kit/arkts-apis-camera-VideoOutput.md#start-1) of the VideoOutput instance to start the video output stream, and then call [start](../../reference/apis-media-kit/arkts-apis-media-AVRecorder.md#start9) of the AVRecorder instance to start recording.
125
126   ```ts
127   async function startVideo(videoOutput: camera.VideoOutput, avRecorder: media.AVRecorder): Promise<void> {
128     videoOutput.start(async (err: BusinessError) => {
129       if (err) {
130         console.error(`Failed to start the video output ${err.message}`);
131         return;
132       }
133       console.info('Callback invoked to indicate the video output start success.');
134     });
135     try {
136       await avRecorder.start();
137     } catch (error) {
138       let err = error as BusinessError;
139       console.error(`avRecorder start error: ${err}`);
140     }
141   }
142   ```
143
1445. Stop video recording.
145
146   Call [stop](../../reference/apis-media-kit/arkts-apis-media-AVRecorder.md#stop9-1) of the AVRecorder instance to stop recording, and then call [stop](../../reference/apis-camera-kit/arkts-apis-camera-VideoOutput.md#stop-1) of the VideoOutput instance to stop the video output stream.
147
148   ```ts
149   async function stopVideo(videoOutput: camera.VideoOutput, avRecorder: media.AVRecorder): Promise<void> {
150     try {
151       await avRecorder.stop();
152     } catch (error) {
153       let err = error as BusinessError;
154       console.error(`avRecorder stop error: ${err}`);
155     }
156     videoOutput.stop((err: BusinessError) => {
157       if (err) {
158         console.error(`Failed to stop the video output ${err.message}`);
159         return;
160       }
161       console.info('Callback invoked to indicate the video output stop success.');
162     });
163   }
164   ```
165
166
167## Status Listening
168
169During camera application development, you can listen for the status of the video output stream, including recording start, recording end, and video output errors.
170
171- Register the **'frameStart'** event to listen for recording start events. This event can be registered when a VideoOutput instance is created and is triggered when the bottom layer starts exposure for recording for the first time. Video recording starts as long as a result is returned.
172
173  ```ts
174  function onVideoOutputFrameStart(videoOutput: camera.VideoOutput): void {
175    videoOutput.on('frameStart', (err: BusinessError) => {
176      if (err !== undefined && err.code !== 0) {
177        return;
178      }
179      console.info('Video frame started');
180    });
181  }
182  ```
183
184- Register the **'frameEnd'** event to listen for recording end events. This event can be registered when a VideoOutput instance is created and is triggered when the last frame of recording ends. Video recording ends as long as a result is returned.
185
186  ```ts
187  function onVideoOutputFrameEnd(videoOutput: camera.VideoOutput): void {
188    videoOutput.on('frameEnd', (err: BusinessError) => {
189      if (err !== undefined && err.code !== 0) {
190        return;
191      }
192      console.info('Video frame ended');
193    });
194  }
195  ```
196
197- Register the **'error'** event to listen for video output errors. The callback function returns an error code when an API is incorrectly used. For details about the error code types, see [CameraErrorCode](../../reference/apis-camera-kit/arkts-apis-camera-e.md#cameraerrorcode).
198
199  ```ts
200  function onVideoOutputError(videoOutput: camera.VideoOutput): void {
201    videoOutput.on('error', (error: BusinessError) => {
202      console.error(`Video output error code: ${error.code}`);
203    });
204  }
205  ```
206
207<!--RP1-->
208<!--RP1End-->
209