在HarmonyOS多媒体应用开发中,视频缩略图的生成是一项常见的需求,尤其是在相册应用、视频播放器等场景中。HarmonyOS NEXT 提供了丰富的 API 来帮助开发者轻松实现这一功能。本文将介绍如何使用 getThumbnailAVImageGenerator 接口从原始媒体资源中获取视频指定时间的缩略图。

场景一:自动生成相册中视频的缩略图

实现思路

  1. 获取视频相册对象:使用 photoAccessHelpergetAlbums 方法获取视频相册对象。
  2. 获取视频对象:通过视频检索条件调用 album.getAssets 方法,获取视频对象。
  3. 获取视频缩略图:调用 Asset.getThumbnail 接口获取视频对象的缩略图(PixelMap)。
  4. 显示缩略图:通过 image 组件显示 PixelMap

HarmonyOS开发之获取视频缩略图_视频缩略图

核心代码

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 });
      }
    }
  }
}

场景二:指定时间获取视频的缩略图

实现思路

  1. 创建 AVImageGenerator 对象:使用 media.createAVImageGenerator() 创建 AVImageGenerator 对象。
  2. 设置资源:设置 AVImageGenerator 对象的 fdSrc 属性,表示文件描述符。
  3. 获取指定时间点的缩略图:调用 fetchFrameByTime() 方法,传入具体时间,获取缩略图的 PixelMap 对象。

HarmonyOS开发之获取视频缩略图_视频缩略图_02

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

HarmonyOS开发之获取视频缩略图_视频缩略图_03

  1. 间隔一秒时间获取视频缩略图:通过定时器或按钮点击事件,每隔一秒获取一次缩略图。
  1. 释放资源:调用 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微秒
    ("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();
    }
  }
}

代码解释

  1. 创建 AVImageGenerator 对象:在 aboutToAppear 生命周期方法中创建 AVImageGenerator 对象并设置 fdSrc
  2. 获取指定时间点的缩略图:在 testFetchFrameByTime 方法中调用 fetchFrameByTime 方法,传入时间点、查询选项和格式参数。
  3. 间隔一秒时间获取视频缩略图:通过按钮点击事件调用 onClick 方法,每隔一秒更新时间点并获取缩略图。
  4. 释放资源:在组件销毁时调用 release 方法释放 AVImageGenerator 资源。

通过上述两个场景的实现,我们可以看到 HarmonyOS NEXT 提供了强大的媒体处理能力,使得开发者可以轻松实现视频缩略图的生成和显示。希望本文对你在实际开发中有所帮助。