• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# @ohos.multimedia.movingphotoview (MovingPhotoView)
2
3The **MovingPhotoView** component is used to play moving photos and control the playback status.
4
5> **NOTE**
6>
7> - This component is supported since API version 12. Updates will be marked with a superscript to indicate their earliest API version.
8> - Currently, the **MovingPhotoView** component cannot be used in Previewer.
9
10## Modules to Import
11
12```
13import { MovingPhotoView, MovingPhotoViewController, MovingPhotoViewAttribute } from '@kit.MediaLibraryKit';
14```
15
16## MovingPhotoView
17
18> **NOTE**
19>
20> - Currently, live attributes cannot be set.
21> - Currently, **expandSafeArea** in the ArkUI common attribute **ComponentOptions** cannot be set.
22> - When this component is long pressed to trigger playback, the component area is zoomed in to 1.1 times.
23> - This component uses [AVPlayer](../apis-media-kit/_a_v_player.md#avplayer) to play moving photos. A maximum of three [AVPlayers](../apis-media-kit/_a_v_player.md#avplayer) can be used at the same time. Otherwise, frame freezing may occur during the playback.
24
25MovingPhotoView(options: MovingPhotoViewOptions)
26
27**Parameters**
28
29
30| Name | Type                                                 | Mandatory| Description      |
31| ------- | --------------------------------------------------------- | ---- | -------------- |
32| options | [MovingPhotoViewOptions](#movingphotoviewoptions) | Yes  | Moving photo information.|
33
34## MovingPhotoViewOptions
35
36
37| Name     | Type                                                                                        | Mandatory| Description                                                                                                                                       |
38| ----------- | ------------------------------------------------------------------------------------------------ | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
39| movingPhoto | [MovingPhoto](js-apis-photoAccessHelper.md#movingphoto12) | Yes  | **MovingPhoto** instance. For details, see [MovingPhoto](js-apis-photoAccessHelper.md#movingphoto12).<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
40| controller  | [MovingPhotoViewController](#movingphotoviewcontroller)                                          | No  | Controller used to control the playback status of the moving photo.<br>**Atomic service API**: This API can be used in atomic services since API version 12.                     |
41
42## Properties
43
44In addition to the [universal properties](../apis-arkui/arkui-ts/ts-component-general-attributes.md), the following properties are supported.
45
46### muted
47
48muted(isMuted: boolean)
49
50Sets whether to mute the player.
51
52**Atomic service API**: This API can be used in atomic services since API version 12.
53
54**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
55
56**Parameters**
57
58
59| Name | Type   | Mandatory| Description                        |
60| ------- | ------- | ---- | ---------------------------- |
61| isMuted | boolean | Yes  | Whether to mute the player.<br>Default value: **false**<br>The value **true** means to mute the player; the value **false** means the opposite.|
62
63### objectFit
64
65objectFit(value: ImageFit)
66
67Sets the display mode of the moving photo.
68
69**Atomic service API**: This API can be used in atomic services since API version 12.
70
71**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
72
73**Parameters**
74
75
76| Name| Type                                                                         | Mandatory| Description                            |
77| ------ | ----------------------------------------------------------------------------- | ---- | -------------------------------- |
78| value  | [ImageFit](../apis-arkui/arkui-ts/ts-appendix-enums.md#imagefit) | Yes  | Image scale type.<br>Default value: **Cover**|
79
80### autoPlayPeriod<sup>13+</sup>
81
82autoPlayPeriod(startTime: number, endTime: number)
83
84Sets the autoplay period, which is a configuration item of **autoPlay**.
85
86Before this API is called, [autoPlay](#autoplay13) must be set to **true**. Otherwise, the specified video play period (**startTime**, **endTime**) does not take effect.
87
88**Atomic service API**: This API can be used in atomic services since API version 13.
89
90**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
91
92**Parameters**
93
94
95| Name | Type   | Mandatory| Description                        |
96| ------- | ------- | ---- | ---------------------------- |
97| startTime| number| Yes  | Start playback time, in ms.<br>Value range: [0,3000]|
98| endTime| number| Yes  | End playback time, in ms.<br>Value range: [0,3000]|
99
100### autoPlay<sup>13+</sup>
101
102autoPlay(isAutoPlay: boolean)
103
104Sets autoplay. After the moving photo is played once, a static image is displayed.
105
106**Atomic service API**: This API can be used in atomic services since API version 13.
107
108**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
109
110**Parameters**
111
112
113| Name | Type   | Mandatory| Description                        |
114| ------- | ------- | ---- | ---------------------------- |
115| isAutoPlay| boolean| Yes  | Whether to enable autoplay.<br>The value **true** means to enable autoplay; the value **false** means the opposite.<br>Default value: **false**|
116
117### repeatPlay<sup>13+</sup>
118
119repeatPlay(isRepeatPlay: boolean)
120
121Sets repeat play. **repeatPlay** is mutually exclusive with **autoPlay** and **Long Press**, and takes precedence over them.
122
123**Atomic service API**: This API can be used in atomic services since API version 13.
124
125**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
126
127**Parameters**
128
129
130| Name | Type   | Mandatory| Description                        |
131| ------- | ------- | ---- | ---------------------------- |
132| isRepeatPlay| boolean| Yes  | Whether to enable repeat play.<br>The value **true** means to enable repeat play; the value **false** means the opposite.<br>Default value: **false**|
133
134## Events
135
136In addition to [universal events](../apis-arkui/arkui-ts/ts-component-general-events.md), the following events are supported.
137
138### onComplete<sup>13+</sup>
139
140onComplete(callback: MovingPhotoViewEventCallback)
141
142Called when the image of a moving photo is loaded.
143
144**Atomic service API**: This API can be used in atomic services since API version 13.
145
146**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
147
148**Parameters**
149
150
151| Name  | Type                                                         | Mandatory| Description                          |
152| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
153| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | Yes  | Callback to be invoked when the image of a moving photo is loaded.|
154
155### onStart
156
157onStart(callback: MovingPhotoViewEventCallback)
158
159Called when a moving photo starts playing.
160
161**Atomic service API**: This API can be used in atomic services since API version 12.
162
163**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
164
165**Parameters**
166
167
168| Name  | Type                                                         | Mandatory| Description                          |
169| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
170| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | Yes  | Callback to be invoked when a moving photo starts playing.|
171
172### onPause
173
174onPause(callback: MovingPhotoViewEventCallback)
175
176Called when the playback is paused.
177
178**Atomic service API**: This API can be used in atomic services since API version 12.
179
180**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
181
182**Parameters**
183
184
185| Name  | Type                                                         | Mandatory| Description                          |
186| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
187| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | Yes  | Callback to be invoked when the playback of a moving photo is paused.|
188
189### onFinish
190
191onFinish(callback: MovingPhotoViewEventCallback)
192
193Called when the playback is finished.
194
195**Atomic service API**: This API can be used in atomic services since API version 12.
196
197**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
198
199**Parameters**
200
201
202| Name  | Type                                                         | Mandatory| Description                          |
203| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
204| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | Yes  | Callback to be invoked when the playback of a moving photo ends.|
205
206### onError
207
208onError(callback: MovingPhotoViewEventCallback)
209
210Called when the playback fails.
211
212**Atomic service API**: This API can be used in atomic services since API version 12.
213
214**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
215
216**Parameters**
217
218
219| Name  | Type                                                         | Mandatory| Description                          |
220| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
221| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | Yes  | Callback to be invoked when the playback of a moving photo fails.|
222
223### onStop
224
225onStop(callback: MovingPhotoViewEventCallback)
226
227Called when the playback is stopped by **stop()**.
228
229**Atomic service API**: This API can be used in atomic services since API version 12.
230
231**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
232
233**Parameters**
234
235
236| Name  | Type                                                         | Mandatory| Description                          |
237| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
238| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | Yes  | Callback to be invoked when the playback of a moving photo is stopped.|
239
240## MovingPhotoViewEventCallback
241
242declare type MovingPhotoViewEventCallback = () => void
243
244Defines a callback to be invoked when the playback status of a moving photo changes.
245
246## MovingPhotoViewController
247
248A **MovingPhotoViewController** object can be used to control a **MovingPhotoView** component. For details, see [@ohos.multimedia.media](../apis-media-kit/js-apis-media.md).
249
250### startPlayback
251
252startPlayback(): void
253
254Starts playback.
255
256**Atomic service API**: This API can be used in atomic services since API version 12.
257
258**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
259
260### stopPlayback
261
262stopPlayback(): void
263
264Stops playback. Once started again, the playback starts from the beginning.
265
266**Atomic service API**: This API can be used in atomic services since API version 12.
267
268**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
269
270## Example 1: Play a moving photo in multiple modes.
271
272```ts
273// xxx.ets
274import { photoAccessHelper } from '@kit.MediaLibraryKit';
275import { emitter } from '@kit.BasicServicesKit';
276import { dataSharePredicates } from '@kit.ArkData';
277import { MovingPhotoView, MovingPhotoViewController, MovingPhotoViewAttribute } from '@kit.MediaLibraryKit';
278
279const PHOTO_SELECT_EVENT_ID: number = 80001
280
281@Entry
282@Component
283struct MovingPhotoViewDemo {
284  @State src: photoAccessHelper.MovingPhoto | undefined = undefined
285  @State isMuted: boolean = false
286  controller: MovingPhotoViewController = new MovingPhotoViewController()
287
288  aboutToAppear(): void {
289    emitter.on({
290      eventId: PHOTO_SELECT_EVENT_ID,
291      priority: emitter.EventPriority.IMMEDIATE,
292    }, (eventData: emitter.EventData) => {
293      this.src = AppStorage.get<photoAccessHelper.MovingPhoto>('mv_data') as photoAccessHelper.MovingPhoto
294    })
295  }
296
297  aboutToDisappear(): void {
298    emitter.off(PHOTO_SELECT_EVENT_ID)
299  }
300
301  build() {
302    Column() {
303      Row() {
304        Button('PICK')
305          .margin(5)
306          .onClick(async () => {
307            let context = getContext(this)
308            try {
309              let uris: Array<string> = []
310              const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions()
311              photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE
312              photoSelectOptions.maxSelectNumber = 2
313              const photoViewPicker = new photoAccessHelper.PhotoViewPicker()
314              let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions)
315              uris = photoSelectResult.photoUris
316              if (uris[0]) {
317                this.handlePickerResult(context, uris[0], new MediaDataHandlerMovingPhoto())
318              }
319            } catch (e) {
320              console.error(`pick file failed`)
321            }
322          })
323      }
324      .alignItems(VerticalAlign.Center)
325      .justifyContent(FlexAlign.Center)
326      .height('15%')
327
328      Row() {
329        Column() {
330          MovingPhotoView({
331            movingPhoto: this.src,
332            controller: this.controller
333          })
334            .width('100%')
335            .height('100%')
336            .muted(this.isMuted)
337            .autoPlay(true)
338            .repeatPlay(false)
339            .autoPlayPeriod(0, 600)
340            .objectFit(ImageFit.Cover)
341            .onComplete(() => {
342              console.log('Completed');
343            })
344            .onStart(() => {
345              console.log('onStart')
346            })
347            .onFinish(() => {
348              console.log('onFinish')
349            })
350            .onStop(() => {
351              console.log('onStop')
352            })
353            .onError(() => {
354              console.log('onError')
355            })
356        }
357      }
358      .height('70%')
359
360      Row() {
361        Button('start')
362          .onClick(() => {
363            this.controller.startPlayback()
364          })
365          .margin(5)
366        Button('stop')
367          .onClick(() => {
368            this.controller.stopPlayback()
369          })
370          .margin(5)
371        Button('mute')
372          .onClick(() => {
373            this.isMuted = !this.isMuted
374          })
375          .margin(5)
376      }
377      .alignItems(VerticalAlign.Center)
378      .justifyContent(FlexAlign.Center)
379      .height('15%')
380    }
381  }
382
383  async handlePickerResult(context: Context, uri: string, handler: photoAccessHelper.MediaAssetDataHandler<photoAccessHelper.MovingPhoto>): Promise<void> {
384    let uriPredicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
385    uriPredicates.equalTo('uri', uri)
386    let fetchOptions: photoAccessHelper.FetchOptions = {
387      fetchColumns: [],
388      predicates: uriPredicates
389    };
390    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context)
391    let assetResult = await phAccessHelper.getAssets(fetchOptions)
392    let asset = await assetResult.getFirstObject()
393    let requestOptions: photoAccessHelper.RequestOptions = {
394      deliveryMode: photoAccessHelper.DeliveryMode.FAST_MODE,
395    }
396    try {
397      photoAccessHelper.MediaAssetManager.requestMovingPhoto(context, asset, requestOptions, handler)
398    } catch (err) {
399      console.error("request error: ", err)
400    }
401  }
402}
403
404class MediaDataHandlerMovingPhoto implements photoAccessHelper.MediaAssetDataHandler<photoAccessHelper.MovingPhoto> {
405  async onDataPrepared(movingPhoto: photoAccessHelper.MovingPhoto) {
406    AppStorage.setOrCreate('mv_data', movingPhoto)
407    emitter.emit({
408      eventId: PHOTO_SELECT_EVENT_ID,
409      priority: emitter.EventPriority.IMMEDIATE,
410    }, {
411    })
412  }
413}
414```
415
416## Example 2: Use moving photos in an atomic service.
417
418```ts
419// xxx.ets
420import { photoAccessHelper, MovingPhotoView, MovingPhotoViewController, MovingPhotoViewAttribute } from '@kit.MediaLibraryKit';
421
422let context = getContext(this)
423let data: photoAccessHelper.MovingPhoto
424async function loading() {
425  try {
426    // Ensure that the media assets corresponding to imageFileUri and videoFileUri exist in the application sandbox directory.
427    let imageFileUri = 'file://{bundleName}/data/storage/el2/base/haps/entry/files/xxx.jpg';
428    let videoFileUri = 'file://{bundleName}/data/storage/el2/base/haps/entry/files/xxx.mp4';
429    data = await photoAccessHelper.MediaAssetManager.loadMovingPhoto(context, imageFileUri, videoFileUri);
430    console.info('load moving photo successfully');
431  } catch (err) {
432    console.error(`load moving photo failed with error: ${err.code}, ${err.message}`);
433  }
434}
435@Entry
436@Component
437struct Index {
438  controller: MovingPhotoViewController = new MovingPhotoViewController()
439  @State ImageFit: ImageFit | undefined | null = ImageFit.Contain;
440  @State flag: boolean = true;
441  @State autoPlayFlag: boolean = true;
442  @State repeatPlayFlag: boolean = false;
443  @State autoPlayPeriodStart: number = 0;
444  @State autoPlayPeriodEnd: number = 500;
445  aboutToAppear(): void {
446    loading()
447  }
448
449  build() {
450    NavDestination() {
451      Column() {
452        Stack({ alignContent: Alignment.BottomStart }) {
453          MovingPhotoView({
454            movingPhoto: data,
455            controller: this.controller
456          })
457            .width(300)
458            .height(400)
459            .muted(this.flag)
460            .objectFit(this.ImageFit)
461            .autoPlay(this.autoPlayFlag)
462            .autoPlayPeriod(this.autoPlayPeriodStart, this.autoPlayPeriodEnd)
463            .repeatPlay(this.repeatPlayFlag)
464            .onComplete(() => {
465              console.info('onComplete')
466            })
467            .onStart(() => {
468              console.info('onStart')
469            })
470            .onStop(() => {
471              console.info('onStop')
472            })
473            .onPause(() => {
474              console.info('onPause')
475            })
476            .onFinish(() => {
477              console.info('onFinish')
478            })
479            .onError(() => {
480              console.info('onError')
481            })
482        }
483
484        Row() {
485          Button('Play')
486            .onClick(() => {
487              this.controller.startPlayback()
488            })
489          Button('StopPlay')
490            .onClick(() => {
491              this.controller.stopPlayback()
492            })
493          Button('mute').id('MovingPhotoView_true')
494            .onClick(() => {
495              this.flag = false
496            })
497        }
498      }
499    }
500  }
501}
502```
503
504 <!--no_check-->