HarmonyOS媒体文件操作

发布于:2024-10-13 ⋅ 阅读:(55) ⋅ 点赞:(0)

媒体文件操作是实际的业务场景中比较常用的操作,通常我们需要用户上传文件,然后对文件进行操作后,再上传服务器。本篇文章对HarmonyOS中对文件的获取以及基本操作进行说明。

图片文件操作

设置媒体权限

在操作媒体文件之前需要在module.josn5文件中配置对应的权限才能进行操作

{
 
    "requestPermissions": [
     {
        "name": "ohos.permission.READ_IMAGEVIDEO",
        "reason": "$string:app_name",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        },
      },{
      	"name":'ohos.permission.WRITE_IMAGEVIDEO',
      	"reason":"$string:app_name",
      	"usedScene":{
      		"abilities":["EntryAbility"],
      		"when":"inuse"	
      	}
      }
    ]
}

获取媒体文件

HarmonyOS提供了多种获取媒体文件的方式,可以根据业务场景自行选择。

获取系统的所有媒体资源

获取所有媒体资源可以使用PhotoAccessHelper API实现。
获取资源的流程如下

  1. 创建photoAccessHelper实例对象
  2. 调用phtotAccessHelper的getAssets方法
// 导入PhotoAccessHelper模块
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import dataSharePredicates from '@ohos.data.dataSharePredicates';
@Component
export default struct Asset{
  fetchColumns: photoAccessHelper.PhotoKeys[] = [
    photoAccessHelper.PhotoKeys.DATE_ADDED,
    photoAccessHelper.PhotoKeys.SIZE
  ]

  @State list:List[] = [];
  async aboutToAppear(): Promise<void> {
    const list = await this.getScreenShotList()
  }
  // 获取所有媒体资源
  async getAssets() {
    const photoAccess = this.getPhotoAccessHelper();
    const fetchResult = await photoAccess.getAssets({
      fetchColumns: this.fetchColumns,
      predicates: new dataSharePredicates.DataSharePredicates()
    });
    const photoAssets = await fetchResult.getAllObjects();
    return photoAssets
  }
  // 获取截图列表
  async getScreenShotList() {
    const list = await this.getAssets()
    return list.filter(item => item.displayName.includes('screenshot'))
  }

  // 获取PhotoAccessHelper
  getPhotoAccessHelper() {
    return photoAccessHelper.getPhotoAccessHelper(getContext())
  }
  // 获取视频列表
  async getVideoList() {
    const list = await this.getAssets()
    return list.filter(item => item.photoType === photoAccessHelper.PhotoType.VIDEO)
  }

  // 获取大尺寸图片
  async getLargeList(){
    const list = await this.getAssets();
   return list.filter((item)=>{
      return item.get(photoAccessHelper.PhotoKeys.SIZE) >= 200 * 1000
    })
  }
 

  build() {}
  }

通过用户上传文件

通过用户上传文件可以通过PhotoAccessHelper模块的PhotoViewPicker实例对象通过手动的方式打开文件选择界面,也可以通过PhotoPicker组件的方式自动打开文件选择界面。
我们以PhotoPicker为例

import {
  PhotoPickerComponent,
  PickerController,
  PickerOptions
} from '@ohos.file.PhotoPickerComponent';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
@Component
struct PhotoPicker{
@State selectedUri:string[] = []
@State pickerOptions:PickerOptions = new PickerOptions()
aboutToAppear(){
	// 初始化pickerOptions
	// 设置最大选择数量
	this.pickerOptions.maxSelectNumber= 5;
	// 设置显示的可选择的文件类型
	this.pickerOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE
}
	build(){
		PhotoPickerComponent(pickerOptions:this.pickerOptions,
		onSelect:(uri:string)=>{
			// 用户选择文件后的回调
			this.selectedUri.push(uri);
		}
		onDeselect:(uri:string)=>{
			// 用户取消选择的回调
			this.selectedUri= this.selectedUri.filter((item:string)=> item !== uri)
		}
		)
	}
}

压缩图片

获取图片之后,我们可以对图片进行一些操作,例如压缩、转换图片格式等。压缩图片使用的是Image模块,使用Image模块的imagePacker进行压缩。
压缩包图片的基本,流程如下

  1. 获取资源
  2. 创建imagePacker
  3. 创建imageSource
  4. 调用imagePacker的packing方法,进行压缩
  5. 把压缩后的文件写入文件系统
  6. 删除原文件
 // 压缩图片
  async compressFile(uri:string){
    const imagePacker = image.createImagePacker();
    const file = fileIo.openSync(uri)
    const imageSource = image.createImageSource(file.fd)
    const arraybuffer = await imagePacker.packing(imageSource,{format:'image/jpeg',quality:20})
    const phAccessHelper = this.getPhotoAccessHelper();
    const createAssetUri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE,'jpg');
    const fd = fileIo.openSync(createAssetUri,fileIo.OpenMode.READ_WRITE);
    fileIo.writeSync(fd.fd,arraybuffer)
    fileIo.close(fd.fd);
  }

音频文件操作

权限设置

在操作媒体文件之前需要在module.josn5文件中配置对应的权限才能进行操作。

{
"requestPermissions": [
      {
        "name": "ohos.permission.MICROPHONE",
        "reason": "$string:app_name",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        }
      }
    ]
}

录制音频

HarmonyOS提供了多种方式录制音频,本篇文章以AudioCapture为例。
AudioCapture录制声音的流程如下

  1. 创建AudioCapture
  2. 监听readData事件,在该事件的回调函数中将音频数据写入文件
import { audio } from "@kit.AudioKit"
import { fileIo } from "@kit.CoreFileKit";
interface Options {
  offset?:number;
  length?:number
}
@Component
export default struct RecordVoice{
  capture:audio.AudioCapturer|null = null;
  filePath:string = ''
  streamInfo:audio.AudioStreamInfo = {
    samplingRate:audio.AudioSamplingRate.SAMPLE_RATE_48000,
    channels:audio.AudioChannel.CHANNEL_2,
    sampleFormat:audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
    encodingType:audio.AudioEncodingType.ENCODING_TYPE_RAW
  }
  capturerInfo:audio.AudioCapturerInfo = {
    source:audio.SourceType.SOURCE_TYPE_MIC,
    capturerFlags:0
  }
  audioCaptureOptions:audio.AudioCapturerOptions = {
    streamInfo:this.streamInfo,
    capturerInfo:this.capturerInfo
  }
  // 创建AudioCapture
  createAudioCapture(){
    audio.createAudioCapturer(this.audioCaptureOptions,(err,data)=>{
      if(err){
        return;
      }
      this.capture = data;
   	  // 获取当前上下文以便于获取文件目录
      const context = getContext()
      // 设置文件名
      const fileName = Date.now()
      // 拼接文件路径
      this.filePath = `${context.filesDir}/${fileName}.wav`
      const file = fileIo.openSync(this.filePath,fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE)
      // 监听readData事件,将数据写入文件
      data.on('readData',(buffer:ArrayBuffer)=>{
        const options:Options = {
          offset:bufferSize,
          length:buffer.byteLength
        }
        fileIo.readSync(file.fd,buffer,options)
      })
     // 开始录制
      this.capture?.start();
    })
  }
  build(){
    Navigation(){
      Scroll(){
        Column(){
          Button('开始录音').onClick(()=>{
            if(!this.capture){
              this.createAudioCapture();
            }else {
            this.capture.start();
          })
          Button('结束录音').onClick(()=>{
            if(this.capture?.state === audio.AudioState.STATE_RUNNING){
              this.capture?.stop();
              this.capture = null;
            }
          })
        }
      }
    }
  }
}

播放音频

HarmonyOS提供了多种播放音频的方式,本篇以AudioRenderer为例。
AudioRenderer播放音频的流程如下

  1. 创建AudioRenderer
  2. 监听writeData事件,读取音频文件数据,将数据写入AudioRenderer
import { audio } from "@kit.AudioKit"
import { fileIo } from "@kit.CoreFileKit";
interface Options {
  offset?:number;
  length?:number
}
@Component
export default struct RecordVoice{
 	filePath:string = ''
  // 创建AudioRenderer
  createAudioRenderer(){
   const streamInfo:audio.AudioStreamInfo = {
      samplingRate:audio.AudioSamplingRate.SAMPLE_RATE_48000,
      channels:audio.AudioChannel.CHANNEL_2,
      sampleFormat:audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
      encodingType:audio.AudioEncodingType.ENCODING_TYPE_RAW
    }
    const rendererInfo:audio.AudioRendererInfo = {
      usage:audio.StreamUsage.STREAM_USAGE_MOVIE,
      rendererFlags:0
    }
   const audioRendererOptions:audio.AudioRendererOptions = {
      streamInfo:streamInfo,
      rendererInfo:rendererInfo
    }
    audio.createAudioRenderer(audioRendererOptions,(err,data)=>{
      if(err){
        return;
      }
      const audioRenderer = data;
      // 读取文件
      const file = fileIo.openSync(this.filePath,fileIo.OpenMode.READ_ONLY)
      // 获取文件信息
      const fileStat = fileIo.statSync(file.fd);
      // 记录已经播放的数据大小
      let bufferSize = 0;
      audioRenderer.on('writeData',(buffer)=>{
        const options:Options = {
          offset:bufferSize,
          length:buffer.byteLength
        }
        // 读取文件,将文件数据写入AudioRenderer
        fileIo.readSync(file.fd,buffer,options)
        bufferSize += buffer.byteLength;
        // 判断文件是否播放完毕
        if(bufferSize >= fileStat.size){
          audioRenderer.stop();
        }
      })
      audioRenderer.start();
    })
  }
  aboutToAppear(): void {
  }
  build(){
    Navigation(){
      Scroll(){
        Column(){
          Button('播放音频').onClick(()=>{
			this.createAudioRenderer();
          })
        }
      }
    }
  }
}