1# Moving Photos (ArkTS)
2
3The camera framework provides the capability of taking moving photos. With this capability, users can take a moving photo in one-click mode, in a way similar to taking an ordinary photo.
4
5To develop the moving photo feature, perform the following steps:
6
7- Check whether the device supports taking moving photos.
8- Enable the capability of taking moving photos (if supported).
9- Listen for the photo callback function and save the photo to the media library. For details, see [Accessing and Managing Moving Photos](../medialibrary/photoAccessHelper-movingphoto.md).
10
11## How to Develop
12
13Read [Camera](../../reference/apis-camera-kit/js-apis-camera.md) for the API reference.
14
15> **NOTE**
16>
17> - Before enabling the capability of taking moving photos, you must enable [deferred photo delivery](camera-deferred-capture.md).
18> - The permission **ohos.permission.MICROPHONE** is required for taking moving photos. For details about how to apply for and verify the permission, see [Camera Development Preparations](camera-preparation.md). Otherwise, there is no sound when a photo is being taken.
19
201. Import dependencies. Specifically, import the camera, image, and mediaLibrary modules.
21
22   ```ts
23   import { camera } from '@kit.CameraKit';
24   import { photoAccessHelper } from '@kit.MediaLibraryKit';
25   import { BusinessError } from '@kit.BasicServicesKit';
26   ```
27
282. Determine the photo output stream.
29
30   You can use the **photoProfiles** attribute of the [CameraOutputCapability](../../reference/apis-camera-kit/js-apis-camera.md#cameraoutputcapability) class to obtain the photo output streams supported by the device and use [createPhotoOutput](../../reference/apis-camera-kit/js-apis-camera.md#createphotooutput11) to create a photo output stream.
31
32   ```ts
33   function getPhotoOutput(cameraManager: camera.CameraManager,
34                           cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined {
35     let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles;
36     if (!photoProfilesArray) {
37       console.error("createOutput photoProfilesArray == null || undefined");
38     }
39     let photoOutput: camera.PhotoOutput | undefined = undefined;
40     try {
41       photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]);
42     } catch (error) {
43       let err = error as BusinessError;
44       console.error(`Failed to createPhotoOutput. error: ${JSON.stringify(err)}`);
45     }
46     return photoOutput;
47   }
48   ```
49
503. Check whether the device supports taking moving photos.
51
52    > **NOTE**
53    >
54    > Before the check, you must configure, commit, and start a session. For details, see [Camera Session Management](camera-session-management.md).
55
56    ```ts
57    function isMovingPhotoSupported(photoOutput: camera.PhotoOutput): boolean {
58      let isSupported: boolean = false;
59      try {
60        isSupported = photoOutput.isMovingPhotoSupported();
61      } catch (error) {
62        // If the operation fails, error.code is returned and processed.
63        let err = error as BusinessError;
64        console.error(`The isMovingPhotoSupported call failed. error code: ${err.code}`);
65      }
66      return isSupported;
67    }
68    ```
69
704. Enable the capability of taking moving photos.
71
72   ```ts
73   function enableMovingPhoto(photoOutput: camera.PhotoOutput): void {
74     try {
75       photoOutput.enableMovingPhoto(true);
76     } catch (error) {
77       // If the operation fails, error.code is returned and processed.
78       let err = error as BusinessError;
79       console.error(`The enableMovingPhoto call failed. error code: ${err.code}`);
80     }
81   }
82   ```
83
845. Trigger photo capture. This procedure is the same as that in the common photo capture mode. For details, see [Photo Capture](camera-shooting.md).
85
86## Status Listening
87
88During camera application development, you can listen for the output stream status of moving photos by registering the **'photoAsset'** event. This event can be registered when a **PhotoOutput** instance is created.
89
90   ```ts
91   let context = getContext(this);
92   let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
93
94   async function mediaLibSavePhoto(photoAsset: photoAccessHelper.PhotoAsset): Promise<void> {
95     try {
96       let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = new photoAccessHelper.MediaAssetChangeRequest(photoAsset);
97       assetChangeRequest.saveCameraPhoto();
98       await phAccessHelper.applyChanges(assetChangeRequest);
99       console.info('apply saveCameraPhoto successfully');
100     } catch (err) {
101       console.error(`apply saveCameraPhoto failed with error: ${err.code}, ${err.message}`);
102     }
103   }
104
105   function onPhotoOutputPhotoAssetAvailable(photoOutput: camera.PhotoOutput): void {
106     photoOutput.on('photoAssetAvailable', (err: BusinessError, photoAsset: photoAccessHelper.PhotoAsset): void => {
107       if (err) {
108         console.info(`photoAssetAvailable error: ${JSON.stringify(err)}.`);
109         return;
110       }
111       console.info('photoOutPutCallBack photoAssetAvailable');
112       // Call the mediaLibrary flush API to save the first-phase images and moving photos.
113       mediaLibSavePhoto(photoAsset);
114     });
115   }
116   ```
117