鸿蒙5.0 APP开发案例分析:基于系统能力获取视频缩略图
视频缩略图是视频的静态预览图像,是从视频中截取的某一帧画面,经常用作视频的封面。在视频浏览、分享和管理等场景中使用可以帮助用户快速浏览和选择想要的内容,提高用户的使用体验。HarmonyOS提供了对应的模块能力,帮助开发者获取视频文件的缩略图。获取视频默认缩略图选取视频帧作为缩略图。
·
往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)
✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?
✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~
✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?
✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?
✏️ 记录一场鸿蒙开发岗位面试经历~
✏️ 持续更新中……
概述
视频缩略图是视频的静态预览图像,是从视频中截取的某一帧画面,经常用作视频的封面。在视频浏览、分享和管理等场景中使用可以帮助用户快速浏览和选择想要的内容,提高用户的使用体验。HarmonyOS提供了对应的模块能力,帮助开发者获取视频文件的缩略图。根据应用获取缩略图策略的不同,可以分为以下两种场景:
- 获取视频默认缩略图
- 选取视频帧作为缩略图
获取视频默认缩略图
实现原理
视频的默认缩略图一般为视频的第一帧,可以通过PhotoAsset类的getThumbnail()方法获取。这里以获取图库视频缩略图场景为例。
开发步骤
- 通过相册管理模块@ohos.file.photoAccessHelper的PhotoViewPicker选取图库视频,获得视频的URL。
//src/main/ets/common/utils/PhotoUtils.ets
/**
* Pull up the gallery picker and select a video.
* @returns The url of the selected video.
*/
async selectVideo(): Promise<string> {
let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
return photoViewPicker.select({
MIMEType: photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE,
maxSelectNumber: 1
}).then((photoSelectResult: photoAccessHelper.PhotoSelectResult): string => {
if (photoSelectResult.photoUris.length <= 0) {
return '';
}
return photoSelectResult.photoUris[0];
})
}
- 使用getAssets()方法,通过选择的图库视频的URL获取视频资源。
//src/main/ets/common/utils/PhotoUtils.ets
// Obtain video resources.
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
predicates.equalTo('uri', videoUrl);
let videoFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> =
await this.phAccessHelper.getAssets({
fetchColumns: ['width', 'height', 'orientation'],
predicates: predicates
});
let photoAsset: photoAccessHelper.PhotoAsset = await videoFetchResult.getFirstObject();
- 根据视频资源的属性配置缩略图的尺寸信息,调用getThumbnail()方法获取PixelMap格式的图片。
//src/main/ets/common/utils/PhotoUtils.ets
// Configure thumbnail parameters.
let thumbnailSize: Size = { width: 0, height: 0 };
if (photoAsset.get(photoAccessHelper.PhotoKeys.ORIENTATION) === 90 ||
photoAsset.get(photoAccessHelper.PhotoKeys.ORIENTATION) === 270) {
thumbnailSize.width = photoAsset.get(photoAccessHelper.PhotoKeys.HEIGHT) as number;
thumbnailSize.height = photoAsset.get(photoAccessHelper.PhotoKeys.WIDTH) as number;
} else {
thumbnailSize.width = photoAsset.get(photoAccessHelper.PhotoKeys.WIDTH) as number;
thumbnailSize.height = photoAsset.get(photoAccessHelper.PhotoKeys.HEIGHT) as number;
}
return photoAsset.getThumbnail(thumbnailSize);
说明
使用getAsset()和getThumbnail()方法需要申请受限开放权限 ‘ohos.permission.READ_IMAGEVIDEO’ ,对于需要克隆、备份或同步图片/视频类文件的应用可申请获取该权限,并通过 getAlbums() 方法获取相册资源再调用这两个方法获取缩略图。或者通过picker的方式可以在不获取权限的情况下,使用这两个方法来访问用户指定的图库资源获取缩略图。本文中的示例使用的是第二种picker的方式。
实现效果

选取视频帧作为缩略图
实现原理
HarmonyOS提供视频缩略图获取类AVImageGenerator 用于选取视频指定时间的帧作为缩略图,这里以选取图库视频缩略图场景为例。
开发步骤
- 拉起图库picker,选取视频获取文件资源描述符。
//src/main/ets/pages/Index.ets
/**
* Obtain video resources through AVImageGenerator.
*/
async imageGeneratorGetThumbnail() {
this.photoUtils.selectVideo().then(async (result: string) => {
// ...
this.fileAlbum = fileIo.openSync(result, fileIo.OpenMode.READ_ONLY);
this.avFileDescriptor = { fd: this.fileAlbum.fd };
// ...
}
).catch((error: BusinessError) => {
hilog.error(0x0000, TAG,
`Invoke imageGeneratorGetThumbnail failed!, error code: ${error.code}, message: ${error.message}`);
})
}
- 根据文件资源描述符获取视频元数据信息。
//src/main/ets/common/utils/PhotoUtils.ets
/**
* Get video infos through video file descriptor.
* @param avFileDescriptor AVFileDescriptor of video.
* @returns the size infos of video.
*/
async getVideoData(avFileDescriptor: media.AVFileDescriptor): Promise<VideoSizeData> {
let videoSize: VideoSizeData = new VideoSizeData();
let avMetaDataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor();
avMetaDataExtractor.fdSrc = avFileDescriptor;
let metadata = await avMetaDataExtractor.fetchMetadata();
videoSize.photoSize.width = parseInt(metadata.videoWidth as string);
videoSize.photoSize.height = parseInt(metadata.videoHeight as string);
if (metadata.duration) {
videoSize.totalTime = parseInt(metadata.duration);
}
avMetaDataExtractor.release();
return videoSize;
}
- 创建AVImageGenerator。
//src/main/ets/pages/Index.ets
this.avImageGenerator = await media.createAVImageGenerator();
if (this.avImageGenerator) {
this.avImageGenerator.fdSrc = this.avFileDescriptor;
} else {
hilog.error(0X0000, TAG, 'Create AVImageGenerator failed!');
return;
}
- 使用 fetchFrameByTime() 方法来获取指定时间的缩略图,返回PixelMap格式的图片。
//src/main/ets/pages/Index.ets
/**
* Obtain a frame at a certain point in time of the video.
* @param time A certain point in time of the video.
*/
async fetchFrameByTime(time: number) {
this.pixelMap = await this.avImageGenerator?.fetchFrameByTime(time,
media.AVImageQueryOptions.AV_IMAGE_QUERY_CLOSEST_SYNC, this.videoSize.photoSize);
}
实现效果

更多推荐



所有评论(0)