在HarmonyOS多媒体应用开发中,视频缩略图的生成是一项常见的需求,尤其是在相册应用、视频播放器等场景中。HarmonyOS NEXT 提供了丰富的 API 来帮助开发者轻松实现这一功能。本文将介绍如何使用 getThumbnail 和 AVImageGenerator 接口从原始媒体资源中获取视频指定时间的缩略图。
场景一:自动生成相册中视频的缩略图
实现思路
- 获取视频相册对象:使用 
photoAccessHelper的getAlbums方法获取视频相册对象。 - 获取视频对象:通过视频检索条件调用 
album.getAssets方法,获取视频对象。 - 获取视频缩略图:调用 
Asset.getThumbnail接口获取视频对象的缩略图(PixelMap)。 - 显示缩略图:通过 
image组件显示PixelMap。 

核心代码
async getThumbnail() {
  try {
    // 建立视频检索条件,用于获取视频
    let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
    let fetchOptions: photoAccessHelper.FetchOptions = {
      fetchColumns: [],
      predicates: predicates
    };
    // 获取视频相册
    let albumFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> = await photoAccessHelper.getAlbums(photoAccessHelper.AlbumType.SYSTEM, photoAccessHelper.AlbumSubtype.VIDEO);
    let album: photoAccessHelper.Album = await albumFetchResult.getFirstObject();
    console.info('get video album successfully, albumUri: ' + album.albumUri);
    // 获取视频相册的视频资源
    let videoFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await album.getAssets(fetchOptions);
    // 调用 FetchResult.getFirstObject 接口获取第一个视频
    let photoAsset: photoAccessHelper.PhotoAsset = await videoFetchResult.getFirstObject();
    console.info('video album getAssets successfully, photoAsset displayName: ' + photoAsset.displayName);
    // 调用 PhotoAsset.getThumbnail 获取图片的缩略图的 PixelMap
    this.pixelMap = await photoAsset.getThumbnail();
    let imageInfo: image.ImageInfo = await this.pixelMap.getImageInfo();
    console.info('getThumbnail successful, pixelMap ImageInfo size: ' + JSON.stringify(imageInfo.size));
    videoFetchResult.close();
    albumFetchResult.close();
  } catch (err) {
    console.error('getThumbnail failed with err: ' + err);
  }
}显示缩略图
@Entry
@Component
struct VideoThumbnail {
  @State pixelMap: image.PixelMap | undefined;
  build() {
    Column() {
      Button('获取视频缩略图').onClick(() => {
        this.getThumbnail();
      });
      if (this.pixelMap) {
        Image(this.pixelMap)
          .width(350)
          .height(300)
          .margin({ top: 20 });
      }
    }
  }
}场景二:指定时间获取视频的缩略图
实现思路
- 创建 
AVImageGenerator对象:使用media.createAVImageGenerator()创建AVImageGenerator对象。 - 设置资源:设置 
AVImageGenerator对象的fdSrc属性,表示文件描述符。 - 获取指定时间点的缩略图:调用 
fetchFrameByTime()方法,传入具体时间,获取缩略图的PixelMap对象。 

取的缩略图时间点与视频帧的对应关系AVImageQueryOptions。

- 间隔一秒时间获取视频缩略图:通过定时器或按钮点击事件,每隔一秒获取一次缩略图。
 
- 释放资源:调用 
release()方法销毁avImageGenerator实例,释放资源。 
核心代码
@Entry
@Component
struct VideoFrameThumbnail {
  @State pixelMap: image.PixelMap | undefined;
  @State i: number = 0;
  private avImageGenerator: media.AVImageGenerator | undefined;
  async aboutToAppear(): Promise<void> {
    // 创建 AVImageGenerator 对象
    this.avImageGenerator = await media.createAVImageGenerator();
    // 设置 fdSrc
    this.avImageGenerator.fdSrc = await getContext(this).resourceManager.getRawFd('VID_1713928724_004.mp4');
  }
  async testFetchFrameByTime(i: number) {
    // 声明缩略图时间点与视频帧的对应关系
    let queryOption = media.AVImageQueryOptions.AV_IMAGE_QUERY_CLOSEST_SYNC;
    // 缩略图的格式参数
    let param: media.PixelMapParams = {
      width: 300,
      height: 300,
    };
    // 获取缩略图(promise 模式)
    this.pixelMap = await this.avImageGenerator.fetchFrameByTime(i, queryOption, param);
  }
  onClick() {
    this.i = this.i + 1000000; // 1秒 = 1000000微秒
    Logger.info("current i is :" + this.i);
    this.testFetchFrameByTime(this.i);
  }
  build() {
    Column() {
      Button('获取指定时间的视频缩略图').onClick(() => {
        this.onClick();
      });
      if (this.pixelMap) {
        Image(this.pixelMap)
          .width(300)
          .height('30%')
          .margin({ top: 20 });
      }
    }
  }
  onDestroy() {
    if (this.avImageGenerator) {
      this.avImageGenerator.release();
    }
  }
}代码解释
- 创建 
AVImageGenerator对象:在aboutToAppear生命周期方法中创建AVImageGenerator对象并设置fdSrc。 - 获取指定时间点的缩略图:在 
testFetchFrameByTime方法中调用fetchFrameByTime方法,传入时间点、查询选项和格式参数。 - 间隔一秒时间获取视频缩略图:通过按钮点击事件调用 
onClick方法,每隔一秒更新时间点并获取缩略图。 - 释放资源:在组件销毁时调用 
release方法释放AVImageGenerator资源。 
通过上述两个场景的实现,我们可以看到 HarmonyOS NEXT 提供了强大的媒体处理能力,使得开发者可以轻松实现视频缩略图的生成和显示。希望本文对你在实际开发中有所帮助。









