媒体文件操作是实际的业务场景中比较常用的操作,通常我们需要用户上传文件,然后对文件进行操作后,再上传服务器。本篇文章对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实现。
获取资源的流程如下
- 创建photoAccessHelper实例对象
- 调用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进行压缩。
压缩包图片的基本,流程如下
- 获取资源
- 创建imagePacker
- 创建imageSource
- 调用imagePacker的packing方法,进行压缩
- 把压缩后的文件写入文件系统
- 删除原文件
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录制声音的流程如下
- 创建AudioCapture
- 监听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播放音频的流程如下
- 创建AudioRenderer
- 监听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();
})
}
}
}
}
}