HarmonyOS媒体文件操作

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

图片文件操作

设置媒体权限

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

json 复制代码
{
 
    "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方法
typescript 复制代码
// 导入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为例

typescript 复制代码
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. 删除原文件
typescript 复制代码
 // 压缩图片
  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文件中配置对应的权限才能进行操作。

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

录制音频

HarmonyOS提供了多种方式录制音频,本篇文章以AudioCapture为例。

AudioCapture录制声音的流程如下

  1. 创建AudioCapture
  2. 监听readData事件,在该事件的回调函数中将音频数据写入文件
typescript 复制代码
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
typescript 复制代码
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();
          })
        }
      }
    }
  }
}
相关推荐
一只栖枝6 小时前
华为 HCIE 大数据认证中 Linux 命令行的运用及价值
大数据·linux·运维·华为·华为认证·hcie·it
zhanshuo10 小时前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
harmonyos
zhanshuo10 小时前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos
whysqwhw16 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw17 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw19 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw20 小时前
鸿蒙音频编码
harmonyos
whysqwhw20 小时前
鸿蒙音频解码
harmonyos
whysqwhw20 小时前
鸿蒙视频解码
harmonyos
whysqwhw20 小时前
鸿蒙视频编码
harmonyos