1# Accessing and Managing Moving Photos 2 3A moving photo is a photo form that combines an image and a video, empowering a static image with dynamic video effect. It helps users capture dynamic moments and improves the fault tolerance rate of photographing. 4 5The media library provides the capabilities of accessing and managing moving photo assets, including: 6 7- [Saving Moving Photo Assets](#saving-moving-photo-assets) 8- [Obtaining a Moving Photo Object](#obtaining-a-moving-photo-object) 9- [Playing Moving Photos with MovingPhotoView](movingphotoview-guidelines.md) 10- [Reading Moving Photo Assets](#reading-moving-photo-assets) 11 12Camera Kit provides the capability of taking moving photos. For details, see [Moving Photos](../camera/camera-moving-photo.md). 13 14## Saving Moving Photo Assets 15 16Use the **SaveButton** security component to save the assets (image and video) of a moving photo. 17 18With the **SaveButton** security component, the application does not need the ohos.permission.WRITE_IMAGEVIDEO permission. When the user taps the button embedded with the **SaveButton** security component, the application obtains the temporary permission to save the assets to the specified media library directory. 19 20For details, see [SaveButton](../../reference/apis-arkui/arkui-ts/ts-security-components-savebutton.md). 21 22**How to Develop** 23 241. Set the properties of the **SaveButton** security component. 252. Create a button with **SaveButton**. 263. Call [MediaAssetChangeRequest.createAssetRequest](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetChangeRequest.md#createassetrequest11) to create an asset change request with **PhotoSubtype** set to **MOVING_PHOTO**. 274. Call [MediaAssetChangeRequest.addResource](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetChangeRequest.md#addresource11) to set the image and video of the moving photo. The video duration of the moving photo cannot exceed 10s. 28 29 In the following example, the image and video of the moving photo are specified by **fileUri** of the [application file](../../file-management/app-file-access.md) in the application sandbox. 30 31 You can also specify the assets in **ArrayBuffer**. For details, see [MediaAssetChangeRequest.addResource(type: ResourceType, data: ArrayBuffer)](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetChangeRequest.md#addresource11-1). 32 335. Call [PhotoAccessHelper.applyChanges](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-PhotoAccessHelper.md#applychanges11) to apply changes for the moving photo. 34 35```ts 36import { photoAccessHelper } from '@kit.MediaLibraryKit'; 37import { common } from '@kit.AbilityKit'; 38 39@Entry 40@Component 41struct Index { 42 @State message: string = 'Hello World' 43 @State saveButtonOptions: SaveButtonOptions = { 44 icon: SaveIconStyle.FULL_FILLED, 45 text: SaveDescription.SAVE_IMAGE, 46 buttonType: ButtonType.Capsule 47 } // Set properties of SaveButton. 48 49 build() { 50 Row() { 51 Column() { 52 Text(this.message) 53 .fontSize(50) 54 .fontWeight(FontWeight.Bold) 55 SaveButton(this.saveButtonOptions) // Create a button with SaveButton. 56 .onClick(async (event, result: SaveButtonOnClickResult) => { 57 if (result == SaveButtonOnClickResult.SUCCESS) { 58 try { 59 let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext; 60 let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context); 61 // Ensure that the assets specified by imageFileUri and videoFileUri exist. imageFileUri and videoFileUri specify the image and video of the moving photo to create. 62 let imageFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/create_moving_photo.jpg'; 63 let videoFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/create_moving_photo.mp4'; 64 let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createAssetRequest(context, photoAccessHelper.PhotoType.IMAGE, "jpg", { 65 title: "moving_photo", 66 subtype: photoAccessHelper.PhotoSubtype.MOVING_PHOTO 67 }); 68 assetChangeRequest.addResource(photoAccessHelper.ResourceType.IMAGE_RESOURCE, imageFileUri); 69 assetChangeRequest.addResource(photoAccessHelper.ResourceType.VIDEO_RESOURCE, videoFileUri); 70 await phAccessHelper.applyChanges(assetChangeRequest); 71 console.info('create moving photo successfully, uri: ' + assetChangeRequest.getAsset().uri); 72 } catch (err) { 73 console.error(`create moving photo failed with error: ${err.code}, ${err.message}`); 74 } 75 } else { 76 console.error('SaveButtonOnClickResult create moving photo failed'); 77 } 78 }) 79 } 80 .width('100%') 81 } 82 .height('100%') 83 } 84} 85``` 86 87## Obtaining a Moving Photo Object 88 89- Use **Picker** to obtain a moving photo object from the media library. 90 91- Create a local moving photo object of the application by passing **fileUri** of an [application file](../../file-management/app-file-access.md) in the application sandbox. 92 93After obtaining a moving photo object, you can use [MovingPhotoView](movingphotoview-guidelines.md) to play it. 94 95### Obtaining a Moving Photo Object from the Media Library 96 971. Select the [URI of a media file](../../file-management/user-file-uri-intro.md#media-file-uri) by using **Picker**. 982. Call [PhotoAccessHelper.getAssets](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-PhotoAccessHelper.md#getassets-1) and [FetchResult.getFirstObject](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-FetchResult.md#getfirstobject-1) to obtain the photo asset corresponding to the URI. 993. Call [MediaAssetManager.requestMovingPhoto](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetManager.md#requestmovingphoto12) to obtain the moving photo object. 100 101```ts 102import { photoAccessHelper } from '@kit.MediaLibraryKit'; 103import { dataSharePredicates } from '@kit.ArkData'; 104import { common } from '@kit.AbilityKit'; 105 106@Entry 107@Component 108struct Index { 109 build() { 110 Row() { 111 Button("example").onClick(async () => { 112 let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext; 113 let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context); 114 example(phAccessHelper, context); 115 }).width('100%') 116 } 117 .height('90%') 118 } 119} 120 121async function example(phAccessHelper: photoAccessHelper.PhotoAccessHelper, context: Context) { 122 try { 123 // Use Picker to select the URI of the moving photo. 124 let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); 125 photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.MOVING_PHOTO_IMAGE_TYPE; 126 photoSelectOptions.maxSelectNumber = 9; 127 let photoViewPicker = new photoAccessHelper.PhotoViewPicker(); 128 let photoSelectResult = await photoViewPicker.select(photoSelectOptions); 129 let uris = photoSelectResult.photoUris; 130 for (let i = 0; i < uris.length; i++) { 131 // Obtain the photo asset corresponding to the URI. 132 let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); 133 predicates.equalTo(photoAccessHelper.PhotoKeys.URI, uris[i]); 134 let fetchOption: photoAccessHelper.FetchOptions = { 135 fetchColumns: [], 136 predicates: predicates 137 }; 138 let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOption); 139 let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject(); 140 // Obtain the moving photo object corresponding to the photo asset. 141 await photoAccessHelper.MediaAssetManager.requestMovingPhoto(context, photoAsset, { 142 deliveryMode: photoAccessHelper.DeliveryMode.FAST_MODE 143 }, { 144 async onDataPrepared(movingPhoto: photoAccessHelper.MovingPhoto) { 145 if (movingPhoto !== undefined) { 146 // Customize the logic for processing the moving photo. 147 console.info('request moving photo successfully, uri: ' + movingPhoto.getUri()); 148 } 149 } 150 }) 151 } 152 } catch (err) { 153 console.error(`request moving photo failed with error: ${err.code}, ${err.message}`); 154 } 155} 156``` 157 158### Obtaining a Moving Photo object in an Application Sandbox Directory 159 160Call [MediaAssetManager.loadMovingPhoto](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetManager.md#loadmovingphoto12) to load the moving photo object in the application sandbox directory. 161 162```ts 163import { photoAccessHelper } from '@kit.MediaLibraryKit'; 164import { common } from '@kit.AbilityKit'; 165 166@Entry 167@Component 168struct Index { 169 @State outputText: string = 'Supported formats:\n'; 170 171 build() { 172 Row() { 173 Button("example").onClick(async () => { 174 let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext; 175 example(context); 176 }).width('100%') 177 } 178 .height('90%') 179 } 180} 181 182async function example(context: Context) { 183 try { 184 let imageFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/local_moving_photo.jpg'; 185 let videoFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/local_moving_photo.mp4'; 186 let movingPhoto = await photoAccessHelper.MediaAssetManager.loadMovingPhoto(context, imageFileUri, videoFileUri); 187 console.info('load moving photo successfully'); 188 } catch (err) { 189 console.error(`load moving photo failed with error: ${err.code}, ${err.message}`); 190 } 191} 192``` 193 194## Reading Moving Photo Assets 195 196Call [MovingPhoto.requestContent](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MovingPhoto.md#requestcontent12) to export the image and video of a moving photo to the application sandbox directory or read the image and video data from **ArrayBuffer**. 197 198```ts 199import { photoAccessHelper } from '@kit.MediaLibraryKit'; 200 201async function example(movingPhoto: photoAccessHelper.MovingPhoto) { 202 try { 203 let imageFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/request_moving_photo.jpg'; 204 let videoFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/request_moving_photo.mp4'; 205 await movingPhoto.requestContent(imageFileUri, videoFileUri); // Export the image and video of the moving photo to the application sandbox directory. 206 let imageData = await movingPhoto.requestContent(photoAccessHelper.ResourceType.IMAGE_RESOURCE); // Read ArrayBuffer to obtain the image data. 207 let videoData = await movingPhoto.requestContent(photoAccessHelper.ResourceType.VIDEO_RESOURCE); // Read ArrayBuffer to obtain the video data. 208 } catch (err) { 209 console.error(`request content of moving photo failed with error: ${err.code}, ${err.message}`); 210 } 211} 212``` 213