• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# @ohos.multimedia.movingphotoview (动态照片)
2<!--Kit: Media Library Kit-->
3<!--Subsystem: FileManagement-->
4<!--Owner: @tangye123456-->
5<!--Designer: @YanSanzo-->
6<!--Tester: @tinygreyy-->
7<!--Adviser: @zengyawen-->
8
9用于播放动态照片文件并控制其播放状态的组件。
10
11> **说明:**
12>
13> 该组件从API Version 12开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
14> 当前不支持在预览器中使用MovingPhotoView组件。
15
16## 导入模块
17
18```
19import { MovingPhotoView, MovingPhotoViewController, MovingPhotoViewAttribute } from '@kit.MediaLibraryKit';
20```
21
22## MovingPhotoView
23
24> **说明:**
25>
26> - 当前不支持动态属性设置。
27> - 当前不支持ArkUI通用属性ComponentOptions中expandSafeArea属性设置。
28> - 该组件长按触发播放时组件区域放大为1.1倍。
29> - 该组件使用[AVPlayer](../apis-media-kit/arkts-apis-media-AVPlayer.md)进行播放,同时开启的AVPlayer个数不建议超过3个,超过3个可能会出现视频播放卡顿现象。
30
31MovingPhotoView(options: MovingPhotoViewOptions)
32
33**参数:**
34
35
36| 参数名  | 参数类型                                                  | 必填 | 参数描述       |
37| ------- | --------------------------------------------------------- | ---- | -------------- |
38| options | [MovingPhotoViewOptions](#movingphotoviewoptions) | 是   | 动态照片信息。 |
39
40## MovingPhotoViewOptions
41
42
43| 参数名      | 参数类型                                                                                         | 必填 | 参数描述                                                                                                                                        |
44| ----------- | ------------------------------------------------------------------------------------------------ | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
45| movingPhoto | [MovingPhoto](arkts-apis-photoAccessHelper-MovingPhoto.md) | 是   | 支持媒体库MovingPhoto数据源,具体信息详见[MovingPhoto说明](arkts-apis-photoAccessHelper-MovingPhoto.md)。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
46| controller  | [MovingPhotoViewController](#movingphotoviewcontroller)                                          | 否   | 设置动态照片控制器,可以控制动态照片的播放状态。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。                      |
47| imageAIOptions<sup>18+</sup>   | [ImageAIOptions](../apis-arkui/arkui-ts/ts-image-common.md#imageaioptions12) | 否   | 设置动态照片AI分析选项,可配置分析类型或绑定一个分析控制器。<br/>**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 |
48
49## 属性
50
51除支持[通用属性](../apis-arkui/arkui-ts/ts-component-general-attributes.md)外,还支持以下属性:
52
53### muted
54
55muted(isMuted: boolean)
56
57设置是否静音。
58
59**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
60
61**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
62
63**参数:**
64
65
66| 参数名  | 类型    | 必填 | 说明                         |
67| ------- | ------- | ---- | ---------------------------- |
68| isMuted | boolean | 是   | 是否静音。<br/>默认值:false。<br/>false:非静音。<br/>true:静音。|
69
70### objectFit
71
72objectFit(value: ImageFit)
73
74设置动态照片显示模式。
75
76**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
77
78**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
79
80**参数:**
81
82
83| 参数名 | 类型                                                                          | 必填 | 说明                             |
84| ------ | ----------------------------------------------------------------------------- | ---- | -------------------------------- |
85| value  | [ImageFit](../apis-arkui/arkui-ts/ts-appendix-enums.md#imagefit) | 是   | 视频显示模式。<br/>默认值:Cover。 |
86
87### autoPlayPeriod<sup>13+</sup>
88
89autoPlayPeriod(startTime: number, endTime: number)
90
91设置自动播放区间,附属于autoPlay的子配置项。
92
93在调用此方法前,需将[autoPlay](#autoplay13)设置为true,设置自动播放,否则指定的视频区间(startTime, endTime)无法生效。
94
95**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。
96
97**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
98
99**参数:**
100
101
102| 参数名  | 类型    | 必填 | 说明                         |
103| ------- | ------- | ---- | ---------------------------- |
104| startTime| number| 是   | 区间播放开始时间,单位:ms。<br/>取值范围:大于等于0。|
105| endTime| number| 是   | 区间播放结束时间,单位:ms。<br/>取值范围:大于startTime。 |
106
107### autoPlay<sup>13+</sup>
108
109autoPlay(isAutoPlay: boolean)
110
111设置自动播放,自动播放一遍视频。
112
113动态照片加载完成后,准备播放时可以调用,播放完成后显示静态图。
114
115**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。
116
117**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
118
119**参数:**
120
121
122| 参数名  | 类型    | 必填 | 说明                         |
123| ------- | ------- | ---- | ---------------------------- |
124| isAutoPlay| boolean| 是   | 是否自动播放。<br/>false:不自动播放。<br/>true:自动播放。<br/>默认值:false。|
125
126### repeatPlay<sup>13+</sup>
127
128repeatPlay(isRepeatPlay: boolean)
129
130设置循环播放,重复播放视频。 repeatPlay与autoPlay及长按播放互斥,repeatPlay设置时,autoPlay和长按播放均不生效。
131
132**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。
133
134**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
135
136**参数:**
137
138
139| 参数名  | 类型    | 必填 | 说明                         |
140| ------- | ------- | ---- | ---------------------------- |
141| isRepeatPlay| boolean| 是   | 是否循环播放。<br/>false:不循环播放。<br/>true:循环播放。<br/>默认值:false。|
142
143### enableAnalyzer<sup>18+</sup>
144
145enableAnalyzer(enabled: boolean)
146
147设置该图片是否支持AI分析,当前支持主体识别、文字识别和对象查找等功能。
148
149**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
150
151**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
152
153**参数:**
154
155
156| 参数名  | 类型    | 必填 | 说明                         |
157| ------- | ------- | ---- | ---------------------------- |
158| enabled| boolean| 是   | 是否开启AI分析。<br/>false:不开启AI分析。<br/>true:开启AI分析。<br/>默认值:true。|
159
160## 事件
161
162除支持[通用事件](../apis-arkui/arkui-ts/ts-component-general-events.md)外,还支持以下事件:
163
164### onComplete<sup>13+</sup>
165
166onComplete(callback: MovingPhotoViewEventCallback)
167
168动态照片加载完成图片时触发该事件。
169
170**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。
171
172**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
173
174**参数:**
175
176
177| 参数名   | 类型                                                          | 必填 | 说明                           |
178| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
179| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | 是   | 动态照片加载完成图片的回调。 |
180
181### onStart
182
183onStart(callback: MovingPhotoViewEventCallback)
184
185播放时触发该事件。
186
187**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
188
189**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
190
191**参数:**
192
193
194| 参数名   | 类型                                                          | 必填 | 说明                           |
195| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
196| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | 是   | 动态照片开始播放时触发的回调。 |
197
198### onPause
199
200onPause(callback: MovingPhotoViewEventCallback)
201
202播放暂停时触发该事件。
203
204**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
205
206**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
207
208**参数:**
209
210
211| 参数名   | 类型                                                          | 必填 | 说明                           |
212| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
213| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | 是   | 动态照片播放暂停时触发的回调。 |
214
215### onFinish
216
217onFinish(callback: MovingPhotoViewEventCallback)
218
219播放结束时触发该事件。
220
221**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
222
223**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
224
225**参数:**
226
227
228| 参数名   | 类型                                                          | 必填 | 说明                           |
229| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
230| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | 是   | 动态照片播放结束时触发的回调。 |
231
232### onError
233
234onError(callback: MovingPhotoViewEventCallback)
235
236播放失败时触发该事件。
237
238**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
239
240**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
241
242**参数:**
243
244
245| 参数名   | 类型                                                          | 必填 | 说明                           |
246| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
247| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | 是   | 动态照片播放失败时触发的回调。 |
248
249### onStop
250
251onStop(callback: MovingPhotoViewEventCallback)
252
253播放停止时触发该事件(当stop()方法被调用后触发)。
254
255**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
256
257**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
258
259**参数:**
260
261
262| 参数名   | 类型                                                          | 必填 | 说明                           |
263| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
264| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | 是   | 动态照片停止播放时触发的回调。 |
265
266### onPrepared<sup>20+</sup>
267
268onPrepared(callback: MovingPhotoViewEventCallback)
269
270动态照片准备播放时触发该事件。
271
272**原子化服务API:** 从API version 20开始,该接口支持在原子化服务中使用。
273
274**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
275
276**参数:**
277
278
279| 参数名   | 类型                                                          | 必填 | 说明                           |
280| -------- | ------------------------------------------------------------- | ---- | ------------------------------ |
281| callback | [MovingPhotoViewEventCallback](#movingphotovieweventcallback) | 是   | 动态照片准备播放时的回调。 |
282
283## MovingPhotoViewEventCallback
284
285declare type MovingPhotoViewEventCallback = () => void
286
287动态照片播放状态发生变化时触发的回调。
288
289**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
290
291**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
292
293## MovingPhotoViewController
294
295一个MovingPhotoViewController对象可以控制一个MovingPhotoView,可用视频播放实例请参考[@ohos.multimedia.media](../apis-media-kit/arkts-apis-media.md)。
296
297### constructor
298
299constructor()
300
301MovingPhotoViewController的构造函数。
302
303**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
304
305**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
306
307### startPlayback
308
309startPlayback()
310
311开始播放,动态照片加载完成后,在播放准备,暂停,完成时调用。
312
313**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
314
315**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
316
317### stopPlayback
318
319stopPlayback()
320
321停止播放,再次播放时从头开始播放。
322
323**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
324
325**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
326
327### refreshMovingPhoto<sup>18+</sup>
328
329refreshMovingPhoto()
330
331强制刷新动态照片组件加载的视频和图片资源,会打断组件当前的行为,使用时要谨慎。
332
333**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
334
335**系统能力:** SystemCapability.FileManagement.PhotoAccessHelper.Core
336
337## 示例1:多种形式播放动态照片
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## 示例2:在原子化服务中使用动态照片
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    // 需要确保imageFileUri和videoFileUri对应的资源在应用沙箱存在。
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
576<!--RP1--><!--RP1End-->