HarmonyOS媒体文件操作

news2024/10/12 20:20:12

媒体文件操作是实际的业务场景中比较常用的操作,通常我们需要用户上传文件,然后对文件进行操作后,再上传服务器。本篇文章对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();
          })
        }
      }
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2208688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql(八) --- 视图

文章目录 前言1.什么是视图&#xff1f;2.创建视图3. 使用视图4. 修改数据4.1.注意事项 5. 删除视图6.视图的优点 前言 前面我们学习了索引&#xff0c;这次我们来学习视图 1.什么是视图&#xff1f; 视图是一个虚拟的表&#xff0c;它是基于一个或多个基本表或其他视图的查询…

8款宝藏手机app,适配安卓和苹果手机

好用的手机APP太多&#xff0c;差点挑花了眼&#xff01;今天来分享4款苹果手机和4款安卓手机上的宝藏软件&#xff0c;看看你喜欢哪一款~ IOS系统APP 1.搜图神器 一款拥有海量图片资源的图片搜索神器&#xff0c;它聚合海内外知名搜索引擎&#xff0c;想要图片直接搜索就行…

用java来编写web界面

一、ssm框架整体目录架构 二、编写后端代码 1、编写实体层代码 实体层代码就是你的对象 entity package com.cv.entity;public class Apple {private Integer id;private String name;private Integer quantity;private Integer price;private Integer categoryId;public…

【JavaScript】LeetCode:61-65

文章目录 61 课程表62 实现Trie&#xff08;前缀树&#xff09;63 全排列64 子集65 电话号码的字母组合 61 课程表 Map BFS拓扑排序&#xff1a;将有向无环图转为线性顺序。遍历prerequisites&#xff1a;1. 数组记录每个节点的入度&#xff0c;2. 哈希表记录依赖关系。n 6&a…

Vulnhub靶场案例渗透[7]- DC7

文章目录 1. 靶场搭建2. 信息收集2.1 确定靶机ip2.2 服务信息收集2.3 社工信息收集 3. 提权 1. 靶场搭建 靶场源地址 检验下载文件的检验码&#xff0c;对比没问题使用vmware打开 # windwos 命令 Get-FileHash <filePath> -Algorithm MD5 # linux md5sum filepath2. 信…

视频汇聚平台EasyCVR支持云端录像丨监控存储丨录像回看丨录像计划丨录像配置

EasyCVR视频汇聚融合平台&#xff0c;是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。平台以其强大的视频处理、汇聚与融合能力&#xff0c;在构建视频监控系统中展现出了独特的优势。 EasyCVR视频汇聚平台可接入传统监控行业中高清网络摄像机的RTSP…

提升实验室效率的秘籍

有组织、高效的实验室而言&#xff0c;业务“人、机、料、法、环、测”的多维度发展至关重要&#xff0c;为了提高实验室管理效率和质量&#xff0c;许多实验室开始采用LIMS&#xff08;实验室信息管理系统&#xff09;软件来辅助管理。LIMS软件能够帮助实验室实现信息化、自动…

leetcode 3217 从链表中移除在数组中的结点

1.题目要求: 给你一个整数数组 nums 和一个链表的头节点 head。从链表中移除所有存在于 nums 中的节点后&#xff0c;返回修改后的链表的头节点。 示例 1&#xff1a; 输入&#xff1a; nums [1,2,3], head [1,2,3,4,5] 输出&#xff1a; [4,5] 解释&#xff1a; 移除数值…

Java中的枚举

1.1 认识枚举 枚举是一种特殊的类&#xff0c;它的格式是&#xff1a; public enum 枚举类名{枚举项1,枚举项2,枚举项3; } 其实枚举项就表示枚举类的对象&#xff0c;只是这些对象在定义枚举类时就预先写好了&#xff0c;以后就只能用这几个固定的对象。 定义一个枚举类&am…

使用VS2015编写C语言程序

前面我们给出了一段完整的C语言代码&#xff0c;就是在显示器上输出“C语言中文网”&#xff0c;如下所示&#xff1a; #include <stdio.h>int main(){puts("C语言中文网");return 0;}本节我们就来看看如何通过 VS2015 来运行这段代码。 1) 创建项目&#xf…

QD1-P8 HTML 格式化标签(font、pre、b、strong、i、u、del、s、sub、sup)

本节学习&#xff1a;HTML 格式化标签。 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p8 ‍ 一、font 标签 用途&#xff1a;定义文本的字体大小、颜色和 face&#xff08;字体类型&#xff09;。 示例 <!DOCTYPE html> <html><head><meta cha…

Tkinter:为什么多个Frame相互覆盖?

在 Tkinter 中&#xff0c;Frame 是一个容器部件&#xff0c;用于组织和管理布局。如果多个 Frame 出现在同一个父容器中并且看起来相互覆盖&#xff0c;通常与布局管理器的使用方式或控件的创建顺序有关。 以下是几个常见的原因和解决方案&#xff0c;帮助你了解为什么多个 F…

生产报工信息化全流程大讲解

在企业的生产管理中&#xff0c;生产报工是一个关键环节&#xff0c;但传统的生产报工方式存在诸多痛点&#xff0c;制约了企业的发展。随着数字化技术的发展&#xff0c;多个平台为企业提供了有效的解决方案。基于生产报工信息化方案报告》白皮书&#xff0c;本文深入探讨生产…

三菱FX3U PLC绝对定位- DRVA指令

指令格式 相关软元件一览 功能和动作 这是采用绝对驱动的单速定位指令。采用从原点(0点)开始的距离指定方式&#xff0c; 也被称为绝对驱动方式。 1、在指令执行过程中&#xff0c;即使改变操作数的内容&#xff0c;也不反映到当前的运行中。 在下次的指令驱动时才有效…

客户服务的未来趋势:智能化与人性化的融合

在当今这个日新月异的数字时代&#xff0c;企业的竞争已不再局限于产品或服务的本身&#xff0c;而是延伸到了客户体验的每一个细微之处。数字化转型作为推动这一变革的重要力量&#xff0c;正深刻改变着客户服务的面貌&#xff0c;使之变得更加智能、便捷且充满人性化。随着人…

最长回文子串-双下标动态规划

题目来源&#xff1a;Leetcode 5.最长回文子串 DP定义&#xff1a; 容易想到&#xff0c;用一个二维数字dp[i][j]来表示s[i:j]是否是回文串&#xff0c;如s“daba”。dp[1][3]1表示"aba"为回文串&#xff1b; 递归条件 想要判断字符串"aba"是否为回文…

MySQL--事务(详解)

目录 一、前言二、本文章目标三、什么是事务&#xff1f;四、事务的ACID特性五、为什么要使用事务六、如何使用事务6.1 查看支持使用事务的引擎6.2语法6.3 开启⼀个事务&#xff0c;执行更新后回滚6.4 开启一个事务更新后提交6.5 保存点6.6 自动/手动提交事务 七、事务的隔离性…

X86、ARM架构镜像

1. 简介 ARM 镜像和 x86 镜像是为不同处理器架构设计的软件镜像。ARM&#xff08;Advanced RISC Machine&#xff09;架构和 x86 架构是两种主流的处理器指令集架构&#xff0c;它们在设计和性能特点上有所不同。以下是 ARM 镜像和 x86 镜像的一些主要区别&#xff1a; 处理器架…

LangGraph入门(一)为什么要用LangGraph

阅读langgraph文档后编写&#xff0c;原文链接 https://langchain-ai.github.io/langgraph/concepts/high_level/ agent介绍 大语音模型LLMs是非常强大的&#xff0c;特别是LLMs与外部API或者检索数据库结合时&#xff0c;将使得的大模型如虎添翼。所以&#xff0c;在调用LLM之…

xss-labs靶场第六关测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、注入点寻找 2、使用hackbar进行payload测试 3、绕过结果 四、源代码分析 五、结论 一、测试环境 1、系统环境 渗透机&#xff1a;本机(127.0.0.1) 靶 机&#xff1a;本机(127.0.0.…