HarmonyOS 获取沙箱视频文件元数据失败

HarmonyOS
2024-12-25 16:27:32
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zxjiu

通过拉起相册,然后把相册视频保存到沙箱目录,然后访问是可以的。

参考示例如下:

import { common } from '@kit.AbilityKit';
import { 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';
import { media } from '@kit.MediaKit';

@Entry
@Component
struct Index5 {
  @State imagePath: string = ''
  @State pixelMap:image.PixelMap  | undefined = undefined
  private controller:VideoController | undefined
  private context = getContext(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; // 过滤选择媒体文件类型为IMAGE
    photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
    photoViewPicker.select(photoSelectOptions).then((photoSelectResult: picker.PhotoSelectResult) => {
      const fileUri = photoSelectResult.photoUris[0]

      this.getFileInfo(fileUri)
      this.testFetchMetadataFromFdSrcByPromise(this.imagePath)
    })
  }
  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(videoUri:string) {
    try {
      let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context);
      let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
      // 配置查询条件,使用PhotoViewPicker选择图片返回的uri进行查询
      predicates.equalTo('uri', videoUri);
      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('width'));

      // 获取缩略图
      asset.getThumbnail((err, pixelMap) => {
        if (err == undefined) {
          this.pixelMap = pixelMap
          console.info('getThumbnail successful ' + JSON.stringify(pixelMap));
        } else {
          console.error('getThumbnail fail', err.code + err.message);
        }
      });
    } catch (error){
      console.error('uriGetAssets failed with err: ' + JSON.stringify(error));
    }
  }

  async testFetchFrameByTime(fileUri:string) {
    // 创建AVImageGenerator对象
    try {
      let avImageGenerator: media.AVImageGenerator = await media.createAVImageGenerator()
      // 设置fdSrc
      let resFile = fs.openSync(fileUri, fs.OpenMode.READ_ONLY)
      let fileLength = fs.statSync(resFile.fd).size
      avImageGenerator.fdSrc = { fd: resFile.fd, offset: 0, length: fileLength }
      // 初始化入参
      let timeUs = 0
      let queryOption = media.AVImageQueryOptions.AV_IMAGE_QUERY_NEXT_SYNC
      let param: media.PixelMapParams = {
        width: 300,
        height: 300
      }
      // 获取缩略图(promise模式)
      let pixelMap = await avImageGenerator.fetchFrameByTime(timeUs, queryOption, param)
      this.pixelMap = pixelMap
      // 释放资源(promise模式)
      avImageGenerator.release()
      fs.closeSync(resFile.fd)
    } catch (e) {
      console.info(`testTag fetchFrameByTime catch exception: ${JSON.stringify(e)}`)
    }
  }

  async testFetchMetadataFromFdSrcByPromise(fileUri:string) {
    // 创建AVMetadataExtractor对象
    console.debug(fileUri)
    let avMetadataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor()
    // 设置fdSrc
    let resFile = fs.openSync(fileUri, fs.OpenMode.READ_ONLY)
    let fileLength = fs.statSync(resFile.fd).size
    avMetadataExtractor.fdSrc = { fd: resFile.fd, offset: 0, length: fileLength }
    try {
      // 获取元数据(promise模式)
      let metadata = await avMetadataExtractor.fetchMetadata()
      console.info('TAG', `get meta data, hasVideo: ${metadata.hasVideo}`)
      console.info('TAG', `get meta data, mimeType: ${metadata.mimeType}`)
      console.info('TAG', `get meta data, videoHeight: ${metadata.videoHeight}`)
      console.info('TAG', `get meta data, videoWidth: ${metadata.videoWidth}`)
      // 获取专辑封面(promise模式)
      this.pixelMap = await avMetadataExtractor.fetchAlbumCover()
    } catch (error){
      console.error('get meta datafailed with err: ' + JSON.stringify(error));
    }

    // 释放资源(promise模式)
    avMetadataExtractor.release()
    console.info('TAG', `release success.`)
  }
}
分享
微博
QQ
微信
回复
2024-12-25 18:51:37
相关问题
HarmonyOS 如何获取视频文件的第一帧
175浏览 • 1回复 待解决
HarmonyOS 图片、视频文件压缩的demo
59浏览 • 1回复 待解决
Harmony 如何读取本地视频文件路径?
14951浏览 • 2回复 待解决
HarmonyOS web加载沙箱文件失败
273浏览 • 1回复 待解决
HarmonyOS 预览沙箱路径下的文件失败
166浏览 • 1回复 待解决
HarmonyOS 沙箱访问获取不到文件
226浏览 • 1回复 待解决
av_player新增支持本地音视频文件播放
2314浏览 • 1回复 待解决
HarmonyOS 获取媒体文件失败13900012
242浏览 • 1回复 待解决