1# 动态照片(ArkTS)
2
3相机框架提供动态照片拍摄能力,业务应用可以类似拍摄普通照片一样,一键式拍摄得到动态照片。
4
5应用开发动态照片主要分为以下步骤:
6
7- 查询当前设备的当前模式是否支持拍摄动态照片。
8- 如果支持动态照片,可以调用相机框架提供的使能接口**使能**动态照片能力。
9- 监听照片回调,将照片存入媒体库。可参考[MediaLibrary Kit-访问和管理动态照片资源](../medialibrary/photoAccessHelper-movingphoto.md)。
10
11## 开发步骤
12
13详细的API说明请参考[Camera API参考](../../reference/apis-camera-kit/js-apis-camera.md)。
14
15> **说明:**
16>
17> - 使能动态照片前需要使能[分段式拍照](camera-deferred-capture.md)能力。
18> - 拍摄动态照片需要麦克风权限ohos.permission.MICROPHONE,权限申请和校验的方式请参考[开发准备](camera-preparation.md)。否则拍摄的照片没有声音。
19
201. 导入依赖,需要导入相机框架、媒体库、图片相关领域依赖。
21
22   ```ts
23   import { camera } from '@kit.CameraKit';
24   import { photoAccessHelper } from '@kit.MediaLibraryKit';
25   import { BusinessError } from '@kit.BasicServicesKit';
26   ```
27
282. 确定拍照输出流。
29
30   通过[CameraOutputCapability](../../reference/apis-camera-kit/js-apis-camera.md#cameraoutputcapability)类中的photoProfiles属性,可获取当前设备支持的拍照输出流,通过[createPhotoOutput](../../reference/apis-camera-kit/js-apis-camera.md#createphotooutput11)方法创建拍照输出流。
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. 查询当前设备当前模式是否支持动态照片能力。
51
52    > **说明:**
53    > 查询是否支持动态照片前需要先完成相机会话配置、提交和启动会话,详细开发步骤请参考[会话管理](camera-session-management.md)。
54
55    ```ts
56    function isMovingPhotoSupported(photoOutput: camera.PhotoOutput): boolean {
57      let isSupported: boolean = false;
58      try {
59        isSupported = photoOutput.isMovingPhotoSupported();
60      } catch (error) {
61        // 失败返回错误码error.code并处理
62        let err = error as BusinessError;
63        console.error(`The isMovingPhotoSupported call failed. error code: ${err.code}`);
64      }
65      return isSupported;
66    }
67    ```
68
694. 使能动态照片拍照能力。
70
71   ```ts
72   function enableMovingPhoto(photoOutput: camera.PhotoOutput): void {
73     try {
74       photoOutput.enableMovingPhoto(true);
75     } catch (error) {
76       // 失败返回错误码error.code并处理
77       let err = error as BusinessError;
78       console.error(`The enableMovingPhoto call failed. error code: ${err.code}`);
79     }
80   }
81   ```
82
835. 触发拍照,与普通拍照方式相同,请参考[拍照](camera-shooting.md)。
84
85## 状态监听
86
87在相机应用开发过程中,可以随时监听动态照片拍照输出流状态。通过注册photoAsset的回调函数获取监听结果,photoOutput创建成功时即可监听。
88
89   ```ts
90   let context = getContext(this);
91   let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
92
93   async function mediaLibSavePhoto(photoAsset: photoAccessHelper.PhotoAsset): Promise<void> {
94     try {
95       let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = new photoAccessHelper.MediaAssetChangeRequest(photoAsset);
96       assetChangeRequest.saveCameraPhoto();
97       await phAccessHelper.applyChanges(assetChangeRequest);
98       console.info('apply saveCameraPhoto successfully');
99     } catch (err) {
100       console.error(`apply saveCameraPhoto failed with error: ${err.code}, ${err.message}`);
101     }
102   }
103
104   function onPhotoOutputPhotoAssetAvailable(photoOutput: camera.PhotoOutput): void {
105     photoOutput.on('photoAssetAvailable', (err: BusinessError, photoAsset: photoAccessHelper.PhotoAsset): void => {
106       if (err) {
107         console.info(`photoAssetAvailable error: ${JSON.stringify(err)}.`);
108         return;
109       }
110       console.info('photoOutPutCallBack photoAssetAvailable');
111       // 调用媒体库落盘接口保存一阶段图和动态照片视频
112       mediaLibSavePhoto(photoAsset);
113     });
114   }
115   ```
116