HarmonyOS鸿蒙Next中如何获取视频的缩略图

HarmonyOS鸿蒙Next中如何获取视频的缩略图 相册中选择一个视频,如何获取视频的缩略图
阻塞

3 回复

您看下这个文档是否能满足需求:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/avimagegenerator-V5

demo:

import { common } from '@kit.AbilityKit';
import { fileUri, picker } from '@kit.CoreFileKit';
import fs from '@ohos.file.fs';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { dataSharePredicates } from '@kit.ArkData';
import { image } from '@kit.ImageKit';

let uri: string = '';
@Entry
@Component
struct PhotoPage {
    @State imagePath: string = ''
    @State pixelMap: image.PixelMap | undefined = undefined
    private controller: VideoController | undefined
    private context = this as common.UIAbilityContext;

    build() {
        Row() {
            Column() {
                Video({
                    src: this.imagePath,
                    controller: this.controller
                }).height(300).width('100%').margin({ bottom: 20 })
                Button("选择视频")
                    .onClick(() => {
                        this.selectPhoto()
                    })
                Image(this.pixelMap).width(300).height(400)
            }.width('100%')
        }.height('100%')
    }

    selectPhoto() {
        const photoSelectOptions = new picker.PhotoSelectOptions();
        const photoViewPicker = new picker.PhotoViewPicker();
        photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.VIDEO_TYPE; // 过滤选择媒体文件类型为VIDEO
        photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
        photoViewPicker.select(photoSelectOptions).then((photoSelectResult: picker.PhotoSelectResult) => {
            const fileUri = photoSelectResult.photoUris[0]
            uri = fileUri
            this.getFileInfo(fileUri)
            this.uriGetAssets()
        })
    }

    async getFileInfo(filePathString: string) {
        let resFile = fs.openSync(filePathString, fs.OpenMode.READ_ONLY)
        const dateStr = (new Date().getTime()).toString()
        // 临时文件目录
        let newPath = this.context.filesDir + `/${dateStr + resFile.name}`;
        // 转化路径
        fs.copyFileSync(resFile.fd, newPath);
        // 新的路径
        let realUri = 'file://' + newPath;
        this.imagePath = realUri
        console.log(this.imagePath)
    }

    async uriGetAssets() {
        try {
            let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context);
            let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
            // 配置查询条件,使用PhotoViewPicker选择图片返回的uri进行查询
            predicates.equalTo('uri', uri);
            let fetchOption: photoAccessHelper.FetchOptions = {
                fetchColumns: [],
                predicates: predicates
            };
            let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOption);
            // 得到uri对应的PhotoAsset对象,读取文件的部分信息
            const asset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
            console.info('asset displayName: ', asset.displayName);
            console.info('asset uri: ', asset.uri);
            console.info('asset photoType: ', asset.photoType);
            console.info('asset width: ', asset.get(photoAccessHelper.PhotoKeys.WIDTH));
            console.info('asset height: ', asset.get(photoAccessHelper.PhotoKeys.HEIGHT));
            console.info('asset title: ' + asset.get(photoAccessHelper.PhotoKeys.TITLE));
            // 获取缩略图
            asset.getThumbnail((err, pixelMap) => {
                if (err == undefined) {
                    this.pixelMap = pixelMap
                    console.info('getThumbnail successful ' + JSON.stringify(pixelMap));
                } else {
                    console.error('getThumbnail fail', err);
                }
            });
        } catch (error) {
            console.error('uriGetAssets failed with err: ' + JSON.stringify(error));
        }
    }
}

沙箱路径的话您看下这个能不能实现:

public static writeVideo(ctx: Context) {
    let mgr = ctx.resourceManager
    let buf = mgr.getRawFileContentSync(""test1.mp4"");
    let file = fileIo.openSync(ctx.cacheDir + ""/test1.mp4"", fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
    fileIo.writeSync(file.fd, buf.buffer);
}

public static async getVideoPicture(path: string): Promise<PixelMap> {
    let avImageG = await media.createAVImageGenerator();
    let file = fileIo.openSync(path, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
    avImageG.fdSrc = file;
    let pix = avImageG.fetchFrameByTime(0, media.AVImageQueryOptions.AV_IMAGE_QUERY_NEXT_SYNC, { width: 300, height: 300 });
    return pix;
}

获取相册视频缩略图模糊问题可以通过AVImageGenerator 获取相册视频缩略图:

1.通picker获取视频uri:

.onClick(() => {
    //创建图库选择器对象实例
    const photoViewPicker = new photoAccessHelper.PhotoViewPicker();
    //调用select()接口拉起图库界面进行文件选择,文件选择成功后,返回PhotoSelectResult结果集
    photoViewPicker.select().then(async (photoSelectResult: picker.PhotoSelectResult) => {
        //用一个全局变量存储返回的uri
        selectUris = photoSelectResult.photoUris;
        console.info('photoViewPicker.select to file succeed and uris are:' + selectUris);
    }).catch((err: BusinessError) => {
        console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
    })
})

2.通过视频uri指定AVImageGenerator 的fdSrc属性,获取缩略图:

async testFetchFrameByTime() {
    // 创建AVImageGenerator对象
    let avImageGenerator: media.AVImageGenerator = await media.createAVImageGenerator()
    let file = fs.openSync(selectUris[0], fs.OpenMode.READ_ONLY);
    console.info('file fd: ' + file.fd);
    let avFileDescriptor: media.AVFileDescriptor = { fd: file.fd };
    avImageGenerator.fdSrc = avFileDescriptor
    let queryOption = media.AVImageQueryOptions.AV_IMAGE_QUERY_NEXT_SYNC
    let param: media.PixelMapParams = {
        width: 300,
        height: 400,
    }
    // 获取缩略图(promise模式)
    this.pixelMap = await avImageGenerator.fetchFrameByTime(0, queryOption, param)
    // 释放资源(promise模式)
    avImageGenerator.release()
    console.info(TAG, `release success.`);
    fs.closeSync(file);
}

更多关于HarmonyOS鸿蒙Next中如何获取视频的缩略图的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,获取视频缩略图可以通过AVMetadataHelper类实现。首先,创建AVMetadataHelper实例并初始化,指定视频文件路径。然后,使用fetchVideoThumbnail方法获取缩略图,该方法返回一个PixelMap对象,即视频的缩略图。最后,释放AVMetadataHelper实例。示例代码如下:

import media from '@ohos.multimedia.media';

let avMetadataHelper = media.createAVMetadataHelper();
avMetadataHelper.setSource('/path/to/video.mp4');
let thumbnail = avMetadataHelper.fetchVideoThumbnail();
avMetadataHelper.release();

fetchVideoThumbnail方法支持指定缩略图的时间点和尺寸,通过fetchVideoThumbnail(long timeUs, int width, int height)实现。获取的PixelMap可直接用于UI显示或进一步处理。

在HarmonyOS鸿蒙Next中,可以通过Image.SourceMediaLibrary来获取视频的缩略图。首先使用MediaLibrary获取视频文件,然后通过Image.Source生成缩略图。具体步骤如下:

  1. 使用MediaLibrary.getFileAssets获取视频文件。
  2. 调用Image.createImageSource创建图像源,传入视频文件路径。
  3. 使用ImageSource.createPixelMap生成缩略图。
  4. 将缩略图显示在UI组件中。

示例代码:

let media = mediaLibrary.getMediaLibrary(context);
let fileAsset = media.getFileAssets(fetchOptions);
let imageSource = image.createImageSource(fileAsset.uri);
let pixelMap = imageSource.createPixelMap(thumbnailOptions);
imageComponent.pixelMap = pixelMap;
回到顶部