• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Camera Development
2
3## When to Use
4
5With the APIs provided by the **Camera** module, you can access and operate camera devices and develop new functions. Common operations include preview, photographing, and video recording. You can also implement flash control, exposure time control, focus mode control, zoom control, and much more.
6
7Before calling camera APIs, be familiar with the following concepts:
8
9- **Static camera capabilities**: A series of parameters used to describe inherent capabilities of a camera, such as orientation and supported resolution.
10- **Physical camera**: An independent camera device. The physical camera ID is a string that uniquely identifies a physical camera.
11- **Asynchronous operation**: A non-blocking operation that allows other operations to execute before it completes. To prevent the UI thread from being blocked, some **Camera** calls are asynchronous. Each asynchronous API provides the callback and promise functions.
12
13## How to Develop
14
15### Available APIs
16
17For details about the APIs, see [Camera Management](../reference/apis/js-apis-camera.md).
18
19### Full-Process Scenario
20
21The full process includes applying for permissions, creating an instance, setting parameters, managing sessions, taking photos, recording videos, and releasing resources.
22
23#### Applying for Permissions
24
25You must apply for the permissions for your application to access the camera device and other functions. The following table lists camera-related permissions.
26
27| Permission| Attribute Value                    |
28| -------- | ------------------------------ |
29| Camera| ohos.permission.CAMERA         |
30| Call recording| ohos.permission.MICROPHONE     |
31| Storage| ohos.permission.WRITE_MEDIA    |
32| Read| ohos.permission.READ_MEDIA     |
33| Location| ohos.permission.MEDIA_LOCATION |
34
35The code snippet is as follows:
36
37```typescript
38const PERMISSIONS: Array<string> = [
39    'ohos.permission.CAMERA',
40    'ohos.permission.MICROPHONE',
41    'ohos.permission.MEDIA_LOCATION',
42    'ohos.permission.READ_MEDIA',
43    'ohos.permission.WRITE_MEDIA'
44]
45
46function applyPermission() {
47        console.info('[permission] get permission');
48        globalThis.abilityContext.requestPermissionFromUser(PERMISSIONS)
49    }
50```
51
52#### Creating an Instance
53
54You must create an independent **CameraManager** instance before performing camera operations. If this operation fails, the camera may be occupied or unusable. If the camera is occupied, wait until it is released. You can call **getSupportedCameras()** to obtain the list of cameras supported by the current device. The list stores all camera IDs of the current device. Each of these IDs can be used to create an independent **CameraManager** instance. If the list is empty, no camera is available for the current device and subsequent operations cannot be performed. The camera has preview, shooting, video recording, and metadata output streams. You can use **getSupportedOutputCapability()** to obtain the output stream capabilities of the camera and configure them in the **profile** field in **CameraOutputCapability**. The procedure for creating a **CameraManager** instance is as follows:
55
56```typescript
57import camera from '@ohos.multimedia.camera'
58import image from '@ohos.multimedia.image'
59import media from '@ohos.multimedia.media'
60
61// Create a CameraManager instance.
62context: any = getContext(this)
63let cameraManager = camera.getCameraManager(this.context)
64if (!cameraManager) {
65    console.error("camera.getCameraManager error")
66    return;
67}
68// Listen for camera state changes.
69cameraManager.on('cameraStatus', (cameraStatusInfo) => {
70    console.log(`camera : ${cameraStatusInfo.camera.cameraId}`);
71    console.log(`status: ${cameraStatusInfo.status}`);
72})
73
74// Obtain the camera list.
75let cameraArray = cameraManager.getSupportedCameras();
76if (cameraArray.length <= 0) {
77    console.error("cameraManager.getSupportedCameras error")
78    return;
79}
80
81for (let index = 0; index < cameraArray.length; index++) {
82    console.log('cameraId : ' + cameraArray[index].cameraId);                        // Obtain the camera ID.
83    console.log('cameraPosition : ' + cameraArray[index].cameraPosition);              // Obtain the camera position.
84    console.log('cameraType : ' + cameraArray[index].cameraType);                      // Obtain the camera type.
85    console.log('connectionType : ' + cameraArray[index].connectionType);              // Obtain the camera connection type.
86}
87
88// Create a camera input stream.
89let cameraInput
90try {
91    cameraInput = cameraManager.createCameraInput(cameraArray[0]);
92} catch () {
93   console.error('Failed to createCameraInput errorCode = ' + error.code);
94}
95
96// Listen for CameraInput errors.
97let cameraDevice = cameraArray[0];
98cameraInput.on('error', cameraDevice, (error) => {
99    console.log(`Camera input error code: ${error.code}`);
100})
101
102// Open the camera.
103await cameraInput.open();
104
105// Obtain the output stream capabilities supported by the camera.
106let cameraOutputCap = cameraManager.getSupportedOutputCapability(cameraArray[0]);
107if (!cameraOutputCap) {
108    console.error("cameraManager.getSupportedOutputCapability error")
109    return;
110}
111console.info("outputCapability: " + JSON.stringify(cameraOutputCap));
112
113let previewProfilesArray = cameraOutputCap.previewProfiles;
114if (!previewProfilesArray) {
115    console.error("createOutput previewProfilesArray == null || undefined")
116}
117
118let photoProfilesArray = cameraOutputCap.photoProfiles;
119if (!photoProfilesArray) {
120    console.error("createOutput photoProfilesArray == null || undefined")
121}
122
123let videoProfilesArray = cameraOutputCap.videoProfiles;
124if (!videoProfilesArray) {
125    console.error("createOutput videoProfilesArray == null || undefined")
126}
127
128let metadataObjectTypesArray = cameraOutputCap.supportedMetadataObjectTypes;
129if (!metadataObjectTypesArray) {
130    console.error("createOutput metadataObjectTypesArray == null || undefined")
131}
132
133// Create a preview stream. For details about the surfaceId parameter, see the XComponent section. The preview stream is the surface provided by the XComponent.
134let previewOutput
135try {
136    previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId)
137} catch (error) {
138    console.error("Failed to create the PreviewOutput instance.")
139}
140
141// Listen for PreviewOutput errors.
142previewOutput.on('error', (error) => {
143    console.log(`Preview output error code: ${error.code}`);
144})
145
146// Create an ImageReceiver instance and set photo parameters. Wherein, the resolution must be one of the photographing resolutions supported by the current device, which are obtained by photoProfilesArray.
147let imageReceiver = await image.createImageReceiver(1920, 1080, 4, 8)
148// Obtain the surface ID for displaying the photos.
149let photoSurfaceId = await imageReceiver.getReceivingSurfaceId()
150// Create a photographing output stream.
151let photoOutput
152try {
153    photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId)
154} catch (error) {
155   console.error('Failed to createPhotoOutput errorCode = ' + error.code);
156}
157
158// Define video recording parameters.
159let videoConfig = {
160    audioSourceType: 1,
161    videoSourceType: 1,
162    profile: {
163        audioBitrate: 48000,
164        audioChannels: 2,
165        audioCodec: 'audio/mp4v-es',
166        audioSampleRate: 48000,
167        durationTime: 1000,
168        fileFormat: 'mp4',
169        videoBitrate: 48000,
170        videoCodec: 'video/mp4v-es',
171        videoFrameWidth: 640,
172        videoFrameHeight: 480,
173        videoFrameRate: 30
174    },
175    url: 'file:///data/media/01.mp4',
176    orientationHint: 0,
177    maxSize: 100,
178    maxDuration: 500,
179    rotation: 0
180}
181
182// Create a video recording output stream.
183let videoRecorder
184media.createVideoRecorder().then((recorder) => {
185    console.log('createVideoRecorder called')
186    videoRecorder = recorder
187})
188// Set video recording parameters.
189videoRecorder.prepare(videoConfig)
190// Obtain the surface ID for video recording.
191let videoSurfaceId
192videoRecorder.getInputSurface().then((id) => {
193    console.log('getInputSurface called')
194    videoSurfaceId = id
195})
196
197// Create a VideoOutput instance.
198let videoOutput
199try {
200    videoOutput = cameraManager.createVideoOutput(videoProfilesArray[0], videoSurfaceId)
201} catch (error) {
202    console.error('Failed to create the videoOutput instance. errorCode = ' + error.code);
203}
204
205// Listen for VideoOutput errors.
206videoOutput.on('error', (error) => {
207    console.log(`Preview output error code: ${error.code}`);
208})
209```
210Surfaces must be created in advance for the preview, shooting, and video recording stream. The preview stream is the surface provided by the **XComponent**, the shooting stream is the surface provided by **ImageReceiver**, and the video recording stream is the surface provided by **VideoRecorder**.
211
212**XComponent**
213
214```typescript
215mXComponentController: XComponentController = new XComponentController                   // Create an XComponentController.
216
217build() {
218    Flex() {
219        XComponent({                                                                     // Create an XComponent.
220            id: '',
221            type: 'surface',
222            libraryname: '',
223            controller: this.mXComponentController
224        })
225        .onload(() => {                                                                  // Set the onload callback.
226            // Set the surface width and height (1920 x 1080). For details about how to set the preview size, see the preview resolutions supported by the current device, which are obtained by previewProfilesArray.
227            this.mXComponentController.setXComponentSurfaceSize({surfaceWidth:1920,surfaceHeight:1080})
228            // Obtain the surface ID.
229            globalThis.surfaceId = mXComponentController.getXComponentSurfaceId()
230        })
231        .width('1920px')                                                                 // Set the width of the XComponent.
232        .height('1080px')                                                                // Set the height of the XComponent.
233    }
234}
235```
236
237**ImageReceiver**
238
239```typescript
240function getImageReceiverSurfaceId() {
241    let receiver = image.createImageReceiver(640, 480, 4, 8)
242    console.log(TAG + 'before ImageReceiver check')
243    if (receiver !== undefined) {
244      console.log('ImageReceiver is ok')
245      surfaceId1 = receiver.getReceivingSurfaceId()
246      console.log('ImageReceived id: ' + JSON.stringify(surfaceId1))
247    } else {
248      console.log('ImageReceiver is not ok')
249    }
250  }
251```
252
253**VideoRecorder**
254
255```typescript
256function getVideoRecorderSurface() {
257        await getFd('CameraManager.mp4');
258        mVideoConfig.url = mFdPath;
259        media.createVideoRecorder((err, recorder) => {
260            console.info('Entering create video receiver')
261            mVideoRecorder = recorder
262            console.info('videoRecorder is :' + JSON.stringify(mVideoRecorder))
263            console.info('videoRecorder.prepare called.')
264            mVideoRecorder.prepare(mVideoConfig, (err) => {
265                console.info('videoRecorder.prepare success.')
266                mVideoRecorder.getInputSurface((err, id) => {
267                    console.info('getInputSurface called')
268                    mVideoSurface = id
269                    console.info('getInputSurface surfaceId: ' + JSON.stringify(mVideoSurface))
270                })
271            })
272        })
273    }
274```
275
276#### Managing Sessions
277
278##### Creating a Session
279
280```typescript
281// Create a session.
282let captureSession
283try {
284    captureSession = cameraManager.createCaptureSession()
285} catch (error) {
286    console.error('Failed to create the CaptureSession instance. errorCode = ' + error.code);
287}
288
289// Listen for session errors.
290captureSession.on('error', (error) => {
291    console.log(`Capture session error code: ${error.code}`);
292})
293
294// Start configuration for the session.
295try {
296    captureSession.beginConfig()
297} catch (error) {
298    console.error('Failed to beginConfig. errorCode = ' + error.code);
299}
300
301// Add the camera input stream to the session.
302try {
303    captureSession.addInput(cameraInput)
304} catch (error) {
305    console.error('Failed to addInput. errorCode = ' + error.code);
306}
307
308// Add the preview input stream to the session.
309try {
310    captureSession.addOutput(previewOutput)
311} catch (error) {
312    console.error('Failed to addOutput(previewOutput). errorCode = ' + error.code);
313}
314
315// Add the photographing output stream to the session.
316try {
317    captureSession.addOutput(photoOutput)
318} catch (error) {
319    console.error('Failed to addOutput(photoOutput). errorCode = ' + error.code);
320}
321
322// Commit the session configuration.
323await captureSession.commitConfig()
324
325// Start the session.
326await captureSession.start().then(() => {
327    console.log('Promise returned to indicate the session start success.');
328})
329```
330
331##### Switching a Session
332
333```typescript
334// Stop the session.
335await captureSession.stop()
336
337// Start configuration for the session.
338try {
339    captureSession.beginConfig()
340} catch (error) {
341    console.error('Failed to beginConfig. errorCode = ' + error.code);
342}
343
344// Remove the photographing output stream from the session.
345try {
346    captureSession.removeOutput(photoOutput)
347} catch (error) {
348    console.error('Failed to removeOutput(photoOutput). errorCode = ' + error.code);
349}
350
351// Add a video recording output stream to the session.
352try {
353    captureSession.addOutput(videoOutput)
354} catch (error) {
355    console.error('Failed to addOutput(videoOutput). errorCode = ' + error.code);
356}
357
358// Commit the session configuration.
359await captureSession.commitConfig()
360
361// Start the session.
362await captureSession.start().then(() => {
363    console.log('Promise returned to indicate the session start success.');
364})
365```
366
367#### Setting Parameters
368
369```typescript
370// Check whether the camera has flash.
371let flashStatus
372try {
373    flashStatus = captureSession.hasFlash()
374} catch (error) {
375    console.error('Failed to hasFlash. errorCode = ' + error.code);
376}
377console.log('Promise returned with the flash light support status:' + flashStatus);
378
379if (flashStatus) {
380    // Check whether the auto flash mode is supported.
381    let flashModeStatus
382    try {
383        let status = captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO)
384        flashModeStatus = status
385    } catch (error) {
386        console.error('Failed to check whether the flash mode is supported. errorCode = ' + error.code);
387    }
388    if(flashModeStatus) {
389        // Set the flash mode to auto.
390        try {
391            captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO)
392        } catch (error) {
393            console.error('Failed to set the flash mode. errorCode = ' + error.code);
394        }
395    }
396}
397
398// Check whether the continuous auto focus is supported.
399let focusModeStatus
400try {
401    let status = captureSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO)
402    focusModeStatus = status
403} catch (error) {
404    console.error('Failed to check whether the focus mode is supported. errorCode = ' + error.code);
405}
406
407if (focusModeStatus) {
408    // Set the focus mode to continuous auto focus.
409    try {
410        captureSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO)
411    } catch (error) {
412        console.error('Failed to set the focus mode. errorCode = ' + error.code);
413    }
414}
415
416// Obtain the zoom ratio range supported by the camera.
417let zoomRatioRange
418try {
419    zoomRatioRange = captureSession.getZoomRatioRange()
420} catch (error) {
421    console.error('Failed to get the zoom ratio range. errorCode = ' + error.code);
422}
423
424// Set a zoom ratio.
425try {
426    captureSession.setZoomRatio(zoomRatioRange[0])
427} catch (error) {
428    console.error('Failed to set the zoom ratio value. errorCode = ' + error.code);
429}
430```
431
432#### Taking Photos
433
434```typescript
435let settings = {
436    quality: camera.QualityLevel.QUALITY_LEVEL_HIGH,                                     // Set the image quality to high.
437    rotation: camera.ImageRotation.ROTATION_0                                            // Set the image rotation angle to 0.
438}
439// Use the current photographing settings to take photos.
440photoOutput.capture(settings, async (err) => {
441    if (err) {
442        console.error('Failed to capture the photo ${err.message}');
443        return;
444    }
445    console.log('Callback invoked to indicate the photo capture request success.');
446});
447```
448
449#### Recording Videos
450
451```typescript
452// Start the video recording output stream.
453videoOutput.start(async (err) => {
454    if (err) {
455        console.error('Failed to start the video output ${err.message}');
456        return;
457    }
458    console.log('Callback invoked to indicate the video output start success.');
459});
460
461// Start video recording.
462videoRecorder.start().then(() => {
463    console.info('videoRecorder start success');
464}
465
466// Stop video recording.
467videoRecorder.stop().then(() => {
468    console.info('stop success');
469}
470
471// Stop the video recording output stream.
472videoOutput.stop((err) => {
473    if (err) {
474        console.error('Failed to stop the video output ${err.message}');
475        return;
476    }
477    console.log('Callback invoked to indicate the video output stop success.');
478});
479```
480
481For details about the APIs used for saving photos, see [Image Processing](image.md#using-imagereceiver).
482
483#### Releasing Resources
484
485```typescript
486// Stop the session.
487captureSession.stop()
488
489// Release the camera input stream.
490cameraInput.close()
491
492// Release the preview output stream.
493previewOutput.release()
494
495// Release the photographing output stream.
496photoOutput.release()
497
498// Release the video recording output stream.
499videoOutput.release()
500
501// Release the session.
502captureSession.release()
503
504// Set the session to null.
505captureSession = null
506```
507
508## Process Flowchart
509
510The following figure shows the process of using the camera.
511![camera_framework process](figures/camera_framework_process.png)
512