openharmony 鸿蒙 ohos-multimedia-movingphotoview

2025-06-12 浏览 (2)

@ohos.multimedia.movingphotoview (MovingPhotoView)

The MovingPhotoView component is used to play moving photos and control the playback status.

NOTE

This component is supported since API version 12. Updates will be marked with a superscript to indicate their earliest API version.

Currently, the MovingPhotoView component cannot be used in Previewer.

Modules to Import

import { MovingPhotoView, MovingPhotoViewController, MovingPhotoViewAttribute } from '@kit.MediaLibraryKit';

MovingPhotoView

NOTE

  • Currently, live attributes cannot be set.
  • Currently, expandSafeArea in the ArkUI common attribute ComponentOptions cannot be set.
  • When this component is long pressed to trigger playback, the component area is zoomed in to 1.1 times.
  • This component uses AVPlayer to play moving photos. A maximum of three AVPlayers can be used at the same time. Otherwise, frame freezing may occur.

MovingPhotoView(options: MovingPhotoViewOptions)

Parameters

NameTypeMandatoryDescription
optionsMovingPhotoViewOptionsYesMoving photo information.

MovingPhotoViewOptions

NameTypeMandatoryDescription
movingPhotoMovingPhotoYesMovingPhoto instance. For details, see MovingPhoto.
Atomic service API: This API can be used in atomic services since API version 12.
controllerMovingPhotoViewControllerNoController used to control the playback status of the moving photo.
Atomic service API: This API can be used in atomic services since API version 12.
imageAIOptions18+ImageAIOptionsNoAI options. You can set the image analyzer type or bind an image analyzer controller.
Atomic service API: This API can be used in atomic services since API version 18.

Properties

In addition to the universal properties, the following properties are supported.

muted

muted(isMuted: boolean)

Sets whether to mute the player.

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
isMutedbooleanYesWhether to mute the player.
Default value: false
The value true means to mute the player; the value false means the opposite.

objectFit

objectFit(value: ImageFit)

Sets the display mode of the moving photo.

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
valueImageFitYesImage scale type.
Default value: Cover

autoPlayPeriod13+

autoPlayPeriod(startTime: number, endTime: number)

Sets the autoplay period, which is a configuration item of autoPlay.

Before this API is called, autoPlay must be set to true. Otherwise, the specified video play period (startTime, endTime) does not take effect.

Atomic service API: This API can be used in atomic services since API version 13.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
startTimenumberYesStart playback time, in ms.
The value must be greater than or equal to 0.
endTimenumberYesEnd playback time, in ms.
The value must be greater than startTime.

autoPlay13+

autoPlay(isAutoPlay: boolean)

Sets autoplay. After the moving photo is played once, a static image is displayed.

Atomic service API: This API can be used in atomic services since API version 13.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
isAutoPlaybooleanYesWhether to enable autoplay.
The value true means to enable autoplay; the value false means the opposite.
Default value: false

repeatPlay13+

repeatPlay(isRepeatPlay: boolean)

Sets repeat play. repeatPlay is mutually exclusive with autoPlay and Long Press, and takes precedence over them.

Atomic service API: This API can be used in atomic services since API version 13.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
isRepeatPlaybooleanYesWhether to enable repeat play.
The value true means to enable repeat play; the value false means the opposite.
Default value: false

enableAnalyzer18+

enableAnalyzer(enabled: boolean)

Sets the AI analyzer. Currently, the AI analyzer supports features, such as subject recognition, text recognition, and object search.

Atomic service API: This API can be used in atomic services since API version 18.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
enabledbooleanYesWhether to enable the AI analyzer.
The value false means to disable the AI analyzer; true means the opposite.
Default value: true

Events

In addition to universal events, the following events are supported.

onComplete13+

onComplete(callback: MovingPhotoViewEventCallback)

Called when the image of a moving photo is loaded.

Atomic service API: This API can be used in atomic services since API version 13.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
callbackMovingPhotoViewEventCallbackYesCallback to be invoked when the image of a moving photo is loaded.

onStart

onStart(callback: MovingPhotoViewEventCallback)

Called when a moving photo starts playing.

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
callbackMovingPhotoViewEventCallbackYesCallback to be invoked when a moving photo starts playing.

onPause

onPause(callback: MovingPhotoViewEventCallback)

Called when the playback is paused.

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
callbackMovingPhotoViewEventCallbackYesCallback to be invoked when the playback of a moving photo is paused.

onFinish

onFinish(callback: MovingPhotoViewEventCallback)

Called when the playback is finished.

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
callbackMovingPhotoViewEventCallbackYesCallback to be invoked when the playback of a moving photo ends.

onError

onError(callback: MovingPhotoViewEventCallback)

Called when the playback fails.

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
callbackMovingPhotoViewEventCallbackYesCallback to be invoked when the playback of a moving photo fails.

onStop

onStop(callback: MovingPhotoViewEventCallback)

Called when the playback is stopped by stop().

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Parameters

NameTypeMandatoryDescription
callbackMovingPhotoViewEventCallbackYesCallback to be invoked when the playback of a moving photo is stopped.

MovingPhotoViewEventCallback

declare type MovingPhotoViewEventCallback = () => void

Defines a callback to be invoked when the playback status of a moving photo changes.

MovingPhotoViewController

A MovingPhotoViewController object can be used to control a MovingPhotoView component. For details, see @ohos.multimedia.media.

startPlayback

startPlayback(): void

Starts playback.

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

stopPlayback

stopPlayback(): void

Stops playback. Once started again, the playback starts from the beginning.

Atomic service API: This API can be used in atomic services since API version 12.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

refreshMovingPhoto18+

refreshMovingPhoto(): void

Forcibly 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.

Atomic service API: This API can be used in atomic services since API version 18.

System capability: SystemCapability.FileManagement.PhotoAccessHelper.Core

Example 1: Play a moving photo in multiple modes.

// xxx.ets
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { emitter } from '@kit.BasicServicesKit';
import { dataSharePredicates } from '@kit.ArkData';
import { MovingPhotoView, MovingPhotoViewController, MovingPhotoViewAttribute } from '@kit.MediaLibraryKit';

const PHOTO_SELECT_EVENT_ID: number = 80001

@Entry
@Component
struct MovingPhotoViewDemo {
  @State src: photoAccessHelper.MovingPhoto|undefined = undefined
  @State isMuted: boolean = false
  controller: MovingPhotoViewController = new MovingPhotoViewController()
  private uiContext: UIContext = this.getUIContext()

  aboutToAppear(): void {
    emitter.on({
      eventId: PHOTO_SELECT_EVENT_ID,
      priority: emitter.EventPriority.IMMEDIATE,
    }, (eventData: emitter.EventData) => {
      this.src = AppStorage.get<photoAccessHelper.MovingPhoto>('mv_data') as photoAccessHelper.MovingPhoto
    })
  }

  aboutToDisappear(): void {
    emitter.off(PHOTO_SELECT_EVENT_ID)
  }

  build() {
    Column() {
      Row() {
        Button('PICK')
          .margin(5)
          .onClick(async () => {
            try {
              let uris: Array<string> = []
              const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions()
              photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE
              photoSelectOptions.maxSelectNumber = 2
              const photoViewPicker = new photoAccessHelper.PhotoViewPicker()
              let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions)
              uris = photoSelectResult.photoUris
              if (uris[0]) {
                this.handlePickerResult(this.uiContext.getHostContext()!, uris[0], new MediaDataHandlerMovingPhoto())
              }
            } catch (e) {
              console.error(`pick file failed`)
            }
          })
      }
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.Center)
      .height('15%')

      Row() {
        Column() {
          MovingPhotoView({
            movingPhoto: this.src,
            controller: this.controller
          })
            .width('100%')
            .height('100%')
            .muted(this.isMuted)
            .autoPlay(true)
            .repeatPlay(false)
            .autoPlayPeriod(0, 600)
            .objectFit(ImageFit.Cover)
            .onComplete(() => {
              console.log('Completed');
            })
            .onStart(() => {
              console.log('onStart')
            })
            .onFinish(() => {
              console.log('onFinish')
            })
            .onStop(() => {
              console.log('onStop')
            })
            .onError(() => {
              console.log('onError')
            })
        }
      }
      .height('70%')

      Row() {
        Button('start')
          .onClick(() => {
            this.controller.startPlayback()
          })
          .margin(5)
        Button('stop')
          .onClick(() => {
            this.controller.stopPlayback()
          })
          .margin(5)
        Button('mute')
          .onClick(() => {
            this.isMuted = !this.isMuted
          })
          .margin(5)
      }
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.Center)
      .height('15%')
    }
  }

  async handlePickerResult(context: Context, uri: string, handler: photoAccessHelper.MediaAssetDataHandler<photoAccessHelper.MovingPhoto>): Promise<void> {
    let uriPredicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
    uriPredicates.equalTo('uri', uri)
    let fetchOptions: photoAccessHelper.FetchOptions = {
      fetchColumns: [],
      predicates: uriPredicates
    };
    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context)
    let assetResult = await phAccessHelper.getAssets(fetchOptions)
    let asset = await assetResult.getFirstObject()
    let requestOptions: photoAccessHelper.RequestOptions = {
      deliveryMode: photoAccessHelper.DeliveryMode.FAST_MODE,
    }
    try {
      photoAccessHelper.MediaAssetManager.requestMovingPhoto(context, asset, requestOptions, handler)
    } catch (err) {
      console.error("request error: ", err)
    }
  }
}

class MediaDataHandlerMovingPhoto implements photoAccessHelper.MediaAssetDataHandler<photoAccessHelper.MovingPhoto> {
  async onDataPrepared(movingPhoto: photoAccessHelper.MovingPhoto) {
    AppStorage.setOrCreate('mv_data', movingPhoto)
    emitter.emit({
      eventId: PHOTO_SELECT_EVENT_ID,
      priority: emitter.EventPriority.IMMEDIATE,
    }, {
    })
  }
}

Example 2: Enable the AI analyzer.

// xxx.ets
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { emitter } from '@kit.BasicServicesKit';
import { dataSharePredicates } from '@kit.ArkData';
import { MovingPhotoView, MovingPhotoViewController, MovingPhotoViewAttribute } from '@kit.MediaLibraryKit';
import visionImageAnalyzer from '@hms.ai.visionImageAnalyzer';
const PHOTO_SELECT_EVENT_ID: number = 80001

@Entry
@Component
struct MovingPhotoViewDemo {
  @State src: photoAccessHelper.MovingPhoto|undefined = undefined
  @State isMuted: boolean = false
  controller: MovingPhotoViewController = new MovingPhotoViewController()
  private aiController: visionImageAnalyzer.VisionImageAnalyzerController =
    new visionImageAnalyzer.VisionImageAnalyzerController()
  private options: ImageAIOptions = {
    types: [ImageAnalyzerType.SUBJECT, ImageAnalyzerType.TEXT, ImageAnalyzerType.OBJECT_LOOKUP],
    aiController: this.aiController
  }
  private uiContext: UIContext = this.getUIContext()

  aboutToAppear(): void {
    emitter.on({
      eventId: PHOTO_SELECT_EVENT_ID,
      priority: emitter.EventPriority.IMMEDIATE,
    }, (eventData: emitter.EventData) => {
      this.src = AppStorage.get<photoAccessHelper.MovingPhoto>('mv_data') as photoAccessHelper.MovingPhoto
    })
  }

  aboutToDisappear(): void {
    emitter.off(PHOTO_SELECT_EVENT_ID)
  }

  build() {
    Column() {
      Row() {
        Button('PICK')
          .margin(5)
          .onClick(async () => {
            try {
              let uris: Array<string> = []
              const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions()
              photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE
              photoSelectOptions.maxSelectNumber = 2
              const photoViewPicker = new photoAccessHelper.PhotoViewPicker()
              let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions)
              uris = photoSelectResult.photoUris
              if (uris[0]) {
                this.handlePickerResult(this.uiContext.getHostContext()!, uris[0], new MediaDataHandlerMovingPhoto())
              }
            } catch (e) {
              console.error(`pick file failed`)
            }
          })
      }
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.Center)
      .height('15%')

      Row() {
        Column() {
          MovingPhotoView({
            movingPhoto: this.src,
            controller: this.controller,
            imageAIOptions: this.options
          })
            .width('100%')
            .height('100%')
            .muted(this.isMuted)
            .autoPlay(true)
            .repeatPlay(false)
            .autoPlayPeriod(0, 600)
            .objectFit(ImageFit.Cover)
            .enableAnalyzer(true)
            .onComplete(() => {
              console.log('Completed');
            })
            .onStart(() => {
              console.log('onStart')
            })
            .onFinish(() => {
              console.log('onFinish')
            })
            .onStop(() => {
              console.log('onStop')
            })
            .onError(() => {
              console.log('onError')
            })
        }
      }
      .height('70%')

      Row() {
        Button('start')
          .onClick(() => {
            this.controller.startPlayback()
          })
          .margin(5)
        Button('stop')
          .onClick(() => {
            this.controller.stopPlayback()
          })
          .margin(5)
        Button('mute')
          .onClick(() => {
            this.isMuted = !this.isMuted
          })
          .margin(5)
      }
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.Center)
      .height('15%')
    }
  }

  async handlePickerResult(context: Context, uri: string, handler: photoAccessHelper.MediaAssetDataHandler<photoAccessHelper.MovingPhoto>): Promise<void> {
    let uriPredicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
    uriPredicates.equalTo('uri', uri)
    let fetchOptions: photoAccessHelper.FetchOptions = {
      fetchColumns: [],
      predicates: uriPredicates
    };
    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context)
    let assetResult = await phAccessHelper.getAssets(fetchOptions)
    let asset = await assetResult.getFirstObject()
    let requestOptions: photoAccessHelper.RequestOptions = {
      deliveryMode: photoAccessHelper.DeliveryMode.FAST_MODE,
    }
    try {
      photoAccessHelper.MediaAssetManager.requestMovingPhoto(context, asset, requestOptions, handler)
    } catch (err) {
      console.error("request error: ", err)
    }
  }
}

class MediaDataHandlerMovingPhoto implements photoAccessHelper.MediaAssetDataHandler<photoAccessHelper.MovingPhoto> {
  async onDataPrepared(movingPhoto: photoAccessHelper.MovingPhoto) {
    AppStorage.setOrCreate('mv_data', movingPhoto)
    emitter.emit({
      eventId: PHOTO_SELECT_EVENT_ID,
      priority: emitter.EventPriority.IMMEDIATE,
    }, {
    })
  }
}

Example 3: Use moving photos in an atomic service.

// xxx.ets
import { photoAccessHelper, MovingPhotoView, MovingPhotoViewController, MovingPhotoViewAttribute } from '@kit.MediaLibraryKit';

let data: photoAccessHelper.MovingPhoto
async function loading(context: Context) {
  try {
    // Ensure that the media assets corresponding to imageFileUri and videoFileUri exist in the application sandbox directory.
    let imageFileUri = 'file://{bundleName}/data/storage/el2/base/haps/entry/files/xxx.jpg';
    let videoFileUri = 'file://{bundleName}/data/storage/el2/base/haps/entry/files/xxx.mp4';
    data = await photoAccessHelper.MediaAssetManager.loadMovingPhoto(context, imageFileUri, videoFileUri);
    console.info('load moving photo successfully');
  } catch (err) {
    console.error(`load moving photo failed with error: ${err.code}, ${err.message}`);
  }
}
@Entry
@Component
struct Index {
  controller: MovingPhotoViewController = new MovingPhotoViewController()
  private uiContext: UIContext = this.getUIContext()
  @State ImageFit: ImageFit|undefined|null = ImageFit.Contain;
  @State flag: boolean = true;
  @State autoPlayFlag: boolean = true;
  @State repeatPlayFlag: boolean = false;
  @State autoPlayPeriodStart: number = 0;
  @State autoPlayPeriodEnd: number = 500;
  aboutToAppear(): void {
    loading(this.uiContext.getHostContext()!)
  }

  build() {
    NavDestination() {
      Column() {
        Stack({ alignContent: Alignment.BottomStart }) {
          MovingPhotoView({
            movingPhoto: data,
            controller: this.controller
          })
            .width(300)
            .height(400)
            .muted(this.flag)
            .objectFit(this.ImageFit)
            .autoPlay(this.autoPlayFlag)
            .autoPlayPeriod(this.autoPlayPeriodStart, this.autoPlayPeriodEnd)
            .repeatPlay(this.repeatPlayFlag)
            .onComplete(() => {
              console.info('onComplete')
            })
            .onStart(() => {
              console.info('onStart')
            })
            .onStop(() => {
              console.info('onStop')
            })
            .onPause(() => {
              console.info('onPause')
            })
            .onFinish(() => {
              console.info('onFinish')
            })
            .onError(() => {
              console.info('onError')
            })
        }

        Row() {
          Button('Play')
            .onClick(() => {
              this.controller.startPlayback()
            })
          Button('StopPlay')
            .onClick(() => {
              this.controller.stopPlayback()
            })
          Button('refreshMovingPhoto')
            .onClick(() => {
              this.controller.refreshMovingPhoto()
            })
          Button('mute').id('MovingPhotoView_true')
            .onClick(() => {
              this.flag = false
            })
        }
      }
    }
  }
}

你可能感兴趣的鸿蒙文章

harmony 鸿蒙Media Library Kit (Media File Management Service)

harmony 鸿蒙media_access_helper_capi.h

harmony 鸿蒙media_asset_base_capi.h

harmony 鸿蒙media_asset_capi.h

harmony 鸿蒙media_asset_change_request_capi.h

harmony 鸿蒙media_asset_manager_capi.h

harmony 鸿蒙MediaAssetManager

harmony 鸿蒙MediaLibrary_RequestId

harmony 鸿蒙MediaLibrary_RequestOptions

harmony 鸿蒙moving_photo_capi.h

  • 所属分类: 后端技术
  • 本文标签: 软件 鸿蒙
  • 版权声明: 本文链接 https://seaxiang.com/blog/t09wdG