鸿蒙开发获取视频的第一帧缩略图(打开相册,写入沙箱,视频压缩,获取缩略图)
在开发过程中,遇到上传视频的场景,往往需要,压缩视频,以及获取视频第一帧缩略图,本文提供四个函数分别用于 打开相册获取视频 将视频写到沙箱目录 压缩视频 获取视频缩略图,附上效果图,以及完整实例。
·
项目场景:
在开发过程中,遇到上传视频的场景,往往需要,压缩视频,以及获取视频第一帧缩略图,本文提供四个函数分别用于 打开相册获取视频 将视频写到沙箱目录 压缩视频 获取视频缩略图,附上效果图,以及完整实例
打开相册获取视频
调用原生能力获取到视频原路径
// 弹出相册选择器
async selectUri(type: photoAccessHelper.PhotoViewMIMETypes, max?: number) {
let imgList: string[] = []
// 创建相册选择器
let photoPicker = new photoAccessHelper.PhotoViewPicker();
// 创建选择参数
const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions()
photoSelectOptions.MIMEType = type
photoSelectOptions.maxSelectNumber = max
// 获取相册选择结果
const result = await photoPicker.select(photoSelectOptions)
// 获取相册选择结果
imgList.push(...result.photoUris)
return imgList
}
将视频写到沙箱目录
将视频写到沙箱目录,压缩时需要沙箱目录
// 将文件拷贝到cache目录下
fileToCache(filePath: string) {
const saveDir = getContext().cacheDir // cache目录
// 生成一个唯一的名字
let filename = util.generateRandomUUID() + ".mp4"
// item.url 相册路径 => 拷贝到cache目录下
const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_ONLY)
// 拷贝文件到cache目录下
fileIo.copyFileSync(file.fd, saveDir + "/" + filename)
return saveDir + "/" + filename
}
压缩视频
压缩视频需要用到一个第三方的工具包 ,这个第三方工具包为可对沙箱路径里的文件进行压缩
使用前需要创建视频压缩器 new VideoCompressor() 从工具包中导入
OpenHarmony三方库中心仓
https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Fvideocompressor终端运行以下命令安装
ohpm i @ohos/videocompressor
Button('压缩视频').onClick(async () => {
// 创建视频压缩器
let videoCompressor = new VideoCompressor();
const data =
// this.selectFilePath 为沙箱路径
await videoCompressor.compressVideo(getContext(), this.selectFilePath, CompressQuality.COMPRESS_QUALITY_HIGH)
const file = fileIo.openSync(data.outputPath, fileIo.OpenMode.READ_ONLY)
this.fd = file.fd
AlertDialog.show({ message: '压缩成功' + JSON.stringify(data) })
})
获取视频缩略图
这里参考了官方文档:
// 获取缩略图
async testFetchFrameByTime() {
// 创建AVImageGenerator对象。
let avImageGenerator: media.AVImageGenerator = await media.createAVImageGenerator();
// 设置fdSrc。
avImageGenerator.fdSrc = { fd: this.fd }
// 初始化入参。
let timeUs = 0;
let queryOption = media.AVImageQueryOptions.AV_IMAGE_QUERY_NEXT_SYNC;
let param: media.PixelMapParams = {
width: 200,
height: 200
};
// 获取缩略图(promise模式)。
this.pixelMap = await avImageGenerator.fetchFrameByTime(timeUs, queryOption, param);
// 释放资源(promise模式)。
avImageGenerator.release();
}
以下是完整案例:
效果图:


完整代码:
import { camera, cameraPicker } from '@kit.CameraKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { CompressQuality, VideoCompressor } from '@ohos/videocompressor';
import { util } from '@kit.ArkTS';
import { fileIo } from '@kit.CoreFileKit';
import { media } from '@kit.MediaKit';
import { image } from '@kit.ImageKit';
@Entry
@Component
struct VideoPage {
array: string[] = []
selectFilePath: string = ''
fd: number = 1
// pixelMap对象声明,用于图片显示。
@State pixelMap: image.PixelMap | undefined = undefined;
// 弹出相册选择器
async selectUri(type: photoAccessHelper.PhotoViewMIMETypes, max?: number) {
let imgList: string[] = []
// 创建相册选择器
let photoPicker = new photoAccessHelper.PhotoViewPicker();
// 创建选择参数
const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions()
photoSelectOptions.MIMEType = type
photoSelectOptions.maxSelectNumber = max
// 获取相册选择结果
const result = await photoPicker.select(photoSelectOptions)
// 获取相册选择结果
imgList.push(...result.photoUris)
return imgList
}
// 将文件拷贝到cache目录下
fileToCache(filePath: string) {
const saveDir = getContext().cacheDir // cache目录
// 生成一个唯一的名字
let filename = util.generateRandomUUID() + ".mp4"
// item.url 相册路径 => 拷贝到cache目录下
const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_ONLY)
// 拷贝文件到cache目录下
fileIo.copyFileSync(file.fd, saveDir + "/" + filename)
return saveDir + "/" + filename
}
// 获取缩略图
async testFetchFrameByTime() {
// 创建AVImageGenerator对象。
let avImageGenerator: media.AVImageGenerator = await media.createAVImageGenerator();
// 设置fdSrc。
avImageGenerator.fdSrc = { fd: this.fd }
// 初始化入参。
let timeUs = 0;
let queryOption = media.AVImageQueryOptions.AV_IMAGE_QUERY_NEXT_SYNC;
let param: media.PixelMapParams = {
width: 200,
height: 200
};
// 获取缩略图(promise模式)。
this.pixelMap = await avImageGenerator.fetchFrameByTime(timeUs, queryOption, param);
// 释放资源(promise模式)。
avImageGenerator.release();
}
build() {
Column({ space: 30 }) {
Button('打开相册,获取视频')
.onClick(async () => {
// 打开相机
this.array = await this.selectUri(photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE, 2)
// const arr = await this.openCamera(cameraPicker.PickerMediaType.VIDEO)
AlertDialog.show({ message: '视频路径' + JSON.stringify(this.array) })
})
Button('写到沙箱')
.onClick(() => {
this.selectFilePath = this.fileToCache(this.array[0])
AlertDialog.show({ message: '沙箱路径' + this.selectFilePath })
})
Button('压缩视频').onClick(async () => {
// 创建视频压缩器
let videoCompressor = new VideoCompressor();
const data =
// this.selectFilePath 为沙箱路径
await videoCompressor.compressVideo(getContext(), this.selectFilePath, CompressQuality.COMPRESS_QUALITY_HIGH)
const file = fileIo.openSync(data.outputPath, fileIo.OpenMode.READ_ONLY)
this.fd = file.fd
AlertDialog.show({ message: '压缩成功' + JSON.stringify(data) })
})
Button('缩略图')
.onClick(() => {
try {
this.testFetchFrameByTime()
} catch (e) {
AlertDialog.show({ message: JSON.stringify(e) })
}
})
Image(this.pixelMap)
.width(300)
.height(300)
}
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.height('100%')
.width('100%')
}
}
更多推荐



所有评论(0)