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