1e41f4b71Sopenharmony_ci# Moving Photos (ArkTS)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciThe 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.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciTo develop the moving photo feature, perform the following steps:
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci- Check whether the device supports taking moving photos.
8e41f4b71Sopenharmony_ci- Enable the capability of taking moving photos (if supported).
9e41f4b71Sopenharmony_ci- 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).
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci## How to Develop
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ciRead [Camera](../../reference/apis-camera-kit/js-apis-camera.md) for the API reference.
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci> **NOTE**
16e41f4b71Sopenharmony_ci>
17e41f4b71Sopenharmony_ci> - Before enabling the capability of taking moving photos, you must enable [deferred photo delivery](camera-deferred-capture.md).
18e41f4b71Sopenharmony_ci> - 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.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci1. Import dependencies. Specifically, import the camera, image, and mediaLibrary modules.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci   ```ts
23e41f4b71Sopenharmony_ci   import { camera } from '@kit.CameraKit';
24e41f4b71Sopenharmony_ci   import { photoAccessHelper } from '@kit.MediaLibraryKit';
25e41f4b71Sopenharmony_ci   import { BusinessError } from '@kit.BasicServicesKit';
26e41f4b71Sopenharmony_ci   ```
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci2. Determine the photo output stream.
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci   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.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci   ```ts
33e41f4b71Sopenharmony_ci   function getPhotoOutput(cameraManager: camera.CameraManager, 
34e41f4b71Sopenharmony_ci                           cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined {
35e41f4b71Sopenharmony_ci     let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles;
36e41f4b71Sopenharmony_ci     if (!photoProfilesArray) {
37e41f4b71Sopenharmony_ci       console.error("createOutput photoProfilesArray == null || undefined");
38e41f4b71Sopenharmony_ci     }
39e41f4b71Sopenharmony_ci     let photoOutput: camera.PhotoOutput | undefined = undefined;
40e41f4b71Sopenharmony_ci     try {
41e41f4b71Sopenharmony_ci       photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]);
42e41f4b71Sopenharmony_ci     } catch (error) {
43e41f4b71Sopenharmony_ci       let err = error as BusinessError;
44e41f4b71Sopenharmony_ci       console.error(`Failed to createPhotoOutput. error: ${JSON.stringify(err)}`);
45e41f4b71Sopenharmony_ci     }
46e41f4b71Sopenharmony_ci     return photoOutput;
47e41f4b71Sopenharmony_ci   }
48e41f4b71Sopenharmony_ci   ```
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci3. Check whether the device supports taking moving photos.
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci   ```ts
53e41f4b71Sopenharmony_ci   function isMovingPhotoSupported(photoOutput: camera.PhotoOutput): boolean {
54e41f4b71Sopenharmony_ci     let isSupported: boolean = false;
55e41f4b71Sopenharmony_ci     try {
56e41f4b71Sopenharmony_ci       isSupported = photoOutput.isMovingPhotoSupported();
57e41f4b71Sopenharmony_ci     } catch (error) {
58e41f4b71Sopenharmony_ci       // If the operation fails, error.code is returned and processed.
59e41f4b71Sopenharmony_ci       let err = error as BusinessError;
60e41f4b71Sopenharmony_ci       console.error(`The isMovingPhotoSupported call failed. error code: ${err.code}`);
61e41f4b71Sopenharmony_ci     }
62e41f4b71Sopenharmony_ci     return isSupported;
63e41f4b71Sopenharmony_ci   }
64e41f4b71Sopenharmony_ci   ```
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci4. Enable the capability of taking moving photos.
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci   ```ts
69e41f4b71Sopenharmony_ci   function enableMovingPhoto(photoOutput: camera.PhotoOutput): void {
70e41f4b71Sopenharmony_ci     try {
71e41f4b71Sopenharmony_ci       photoOutput.enableMovingPhoto(true);
72e41f4b71Sopenharmony_ci     } catch (error) {
73e41f4b71Sopenharmony_ci       // If the operation fails, error.code is returned and processed.
74e41f4b71Sopenharmony_ci       let err = error as BusinessError;
75e41f4b71Sopenharmony_ci       console.error(`The enableMovingPhoto call failed. error code: ${err.code}`);
76e41f4b71Sopenharmony_ci     }
77e41f4b71Sopenharmony_ci   }
78e41f4b71Sopenharmony_ci   ```
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci5. Trigger photographing. This procedure is the same as that in the common photographing mode. For details, see [Camera Photographing](camera-shooting.md).
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ci## Status Listening
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ciRegister a callback function to listen for **'photoAssetAvailable'** events.
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci   ```ts
89e41f4b71Sopenharmony_ci   let context = getContext(this);
90e41f4b71Sopenharmony_ci   let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci   async function mediaLibSavePhoto(photoAsset: photoAccessHelper.PhotoAsset): Promise<void> {
93e41f4b71Sopenharmony_ci     try {
94e41f4b71Sopenharmony_ci       let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = new photoAccessHelper.MediaAssetChangeRequest(photoAsset);
95e41f4b71Sopenharmony_ci       assetChangeRequest.saveCameraPhoto();
96e41f4b71Sopenharmony_ci       await phAccessHelper.applyChanges(assetChangeRequest);
97e41f4b71Sopenharmony_ci       console.info('apply saveCameraPhoto successfully');
98e41f4b71Sopenharmony_ci     } catch (err) {
99e41f4b71Sopenharmony_ci       console.error(`apply saveCameraPhoto failed with error: ${err.code}, ${err.message}`);
100e41f4b71Sopenharmony_ci     }
101e41f4b71Sopenharmony_ci   }
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci   function onPhotoOutputPhotoAssetAvailable(photoOutput: camera.PhotoOutput): void {
104e41f4b71Sopenharmony_ci     photoOutput.on('photoAssetAvailable', (err: BusinessError, photoAsset: photoAccessHelper.PhotoAsset): void => {
105e41f4b71Sopenharmony_ci       if (err) {
106e41f4b71Sopenharmony_ci         console.info(`photoAssetAvailable error: ${JSON.stringify(err)}.`);
107e41f4b71Sopenharmony_ci         return;
108e41f4b71Sopenharmony_ci       }
109e41f4b71Sopenharmony_ci       console.info('photoOutPutCallBack photoAssetAvailable');
110e41f4b71Sopenharmony_ci       // Call the mediaLibrary flush API to save the first-phase images and moving photos.
111e41f4b71Sopenharmony_ci       mediaLibSavePhoto(photoAsset);
112e41f4b71Sopenharmony_ci     });
113e41f4b71Sopenharmony_ci   }
114e41f4b71Sopenharmony_ci   ```
115e41f4b71Sopenharmony_ci
116e41f4b71Sopenharmony_ci <!--no_check-->