网站做单链 好不好,松松软文平台,西安高端网站建设哪家好,备案期间网站能打开吗1 AVPlayer音频播放
使用AVPlayer可以实现端到端播放原始媒体资源#xff0c;本开发指导将以完整地播放一首音乐作为示例#xff0c;向开发者讲解AVPlayer音频播放相关功能。
以下指导仅介绍如何实现媒体资源播放#xff0c;如果要实现后台播放或熄屏播放#xff0c;需要…1 AVPlayer音频播放
使用AVPlayer可以实现端到端播放原始媒体资源本开发指导将以完整地播放一首音乐作为示例向开发者讲解AVPlayer音频播放相关功能。
以下指导仅介绍如何实现媒体资源播放如果要实现后台播放或熄屏播放需要使用AVSession媒体会话和申请长时任务避免播放被系统强制中断。
播放的全流程包含创建AVPlayer设置播放资源设置播放参数音量/倍速/焦点模式播放控制播放/暂停/跳转/停止重置销毁资源。
在进行应用开发的过程中开发者可以通过AVPlayer的state属性主动获取当前状态或使用on(‘stateChange’)方法监听状态变化。如果应用在音频播放器处于错误状态时执行操作系统可能会抛出异常或生成其他未定义的行为。 当播放处于prepared / playing / paused / completed状态时播放引擎处于工作状态这需要占用系统较多的运行内存。当客户端暂时不使用播放器时调用reset()或release()回收内存资源做好资源利用。
1.1 开发步骤及注意事项 创建实例createAVPlayer()AVPlayer初始化idle状态。 设置业务需要的监听事件搭配全流程场景使用。支持的监听事件包括 设置资源设置属性urlAVPlayer进入initialized状态。 说明 下面代码示例中的url仅作示意使用开发者需根据实际情况确认资源有效性并设置 1.如果使用本地资源播放必须确认资源文件可用并使用应用沙箱路径访问对应资源参考获取应用文件路径。应用沙箱的介绍及如何向应用沙箱推送文件请参考文件管理。 2.如果使用网络播放路径需声明权限ohos.permission.INTERNET。 3.如果使用ResourceManager.getRawFd打开HAP资源文件描述符使用方法可参考ResourceManager API参考。 4.需要使用支持的播放格式与协议。 准备播放调用prepare()AVPlayer进入prepared状态此时可以获取duration设置音量。音频播控播放play()暂停pause()跳转seek()停止stop() 等操作。可选更换资源调用reset()重置资源AVPlayer重新进入idle状态允许更换资源url。退出播放调用release()销毁实例AVPlayer进入released状态退出播放。
1.2 完整示例
参考以下示例完整地播放一首音乐。
import media from ohos.multimedia.media;
import fs from ohos.file.fs;
import common from ohos.app.ability.common;
import { BusinessError } from ohos.base;export class AVPlayerDemo {private count: number 0;private isSeek: boolean true; // 用于区分模式是否支持seek操作private fileSize: number -1;private fd: number 0;// 注册avplayer回调函数setAVPlayerCallback(avPlayer: media.AVPlayer) {// seek操作结果回调函数avPlayer.on(seekDone, (seekDoneTime: number) {console.info(AVPlayer seek succeeded, seek time is ${seekDoneTime});})// error回调监听函数,当avPlayer在操作过程中出现错误时调用 reset接口触发重置流程avPlayer.on(error, (err: BusinessError) {console.error(Invoke avPlayer failed, code is ${err.code}, message is ${err.message});avPlayer.reset(); // 调用reset重置资源触发idle状态})// 状态机变化回调函数avPlayer.on(stateChange, async (state: string, reason: media.StateChangeReason) {switch (state) {case idle: // 成功调用reset接口后触发该状态机上报console.info(AVPlayer state idle called.);avPlayer.release(); // 调用release接口销毁实例对象break;case initialized: // avplayer 设置播放源后触发该状态上报console.info(AVPlayer state initialized called.);avPlayer.prepare();break;case prepared: // prepare调用成功后上报该状态机console.info(AVPlayer state prepared called.);avPlayer.play(); // 调用播放接口开始播放break;case playing: // play成功调用后触发该状态机上报console.info(AVPlayer state playing called.);if (this.count ! 0) {if (this.isSeek) {console.info(AVPlayer start to seek.);avPlayer.seek(avPlayer.duration); //seek到音频末尾} else {// 当播放模式不支持seek操作时继续播放到结尾console.info(AVPlayer wait to play end.);}} else {avPlayer.pause(); // 调用暂停接口暂停播放}this.count;break;case paused: // pause成功调用后触发该状态机上报console.info(AVPlayer state paused called.);avPlayer.play(); // 再次播放接口开始播放break;case completed: // 播放结束后触发该状态机上报console.info(AVPlayer state completed called.);avPlayer.stop(); //调用播放结束接口break;case stopped: // stop接口成功调用后触发该状态机上报console.info(AVPlayer state stopped called.);avPlayer.reset(); // 调用reset接口初始化avplayer状态break;case released:console.info(AVPlayer state released called.);break;default:console.info(AVPlayer state unknown called.);break;}})}// 以下demo为使用fs文件系统打开沙箱地址获取媒体文件地址并通过url属性进行播放示例async avPlayerUrlDemo() {// 创建avPlayer实例对象let avPlayer: media.AVPlayer await media.createAVPlayer();// 创建状态机变化回调函数this.setAVPlayerCallback(avPlayer);let fdPath fd://;// 通过UIAbilityContext获取沙箱地址filesDir以Stage模型为例let context getContext(this) as common.UIAbilityContext;let pathDir context.filesDir;let path pathDir /01.mp3;// 打开相应的资源文件地址获取fd并为url赋值触发initialized状态机上报let file await fs.open(path);fdPath fdPath file.fd;this.isSeek true; // 支持seek操作avPlayer.url fdPath;}// 以下demo为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例async avPlayerFdSrcDemo() {// 创建avPlayer实例对象let avPlayer: media.AVPlayer await media.createAVPlayer();// 创建状态机变化回调函数this.setAVPlayerCallback(avPlayer);// 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址// 返回类型为{fd,offset,length},fd为HAP包fd地址offset为媒体资源偏移量length为播放长度let context getContext(this) as common.UIAbilityContext;let fileDescriptor await context.resourceManager.getRawFd(01.mp3);let avFileDescriptor: media.AVFileDescriptor { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length };this.isSeek true; // 支持seek操作// 为fdSrc赋值触发initialized状态机上报avPlayer.fdSrc avFileDescriptor;}// 以下demo为使用fs文件系统打开沙箱地址获取媒体文件地址并通过dataSrc属性进行播放(seek模式)示例async avPlayerDataSrcSeekDemo() {// 创建avPlayer实例对象let avPlayer: media.AVPlayer await media.createAVPlayer();// 创建状态机变化回调函数this.setAVPlayerCallback(avPlayer);// dataSrc播放模式的的播放源地址当播放为Seek模式时fileSize为播放文件的具体大小下面会对fileSize赋值let src: media.AVDataSrcDescriptor {fileSize: -1,callback: (buf: ArrayBuffer, length: number, pos: number | undefined) {let num 0;if (buf undefined || length undefined || pos undefined) {return -1;}num fs.readSync(this.fd, buf, { offset: pos, length: length });if (num 0 (this.fileSize pos)) {return num;}return -1;}}let context getContext(this) as common.UIAbilityContext;// 通过UIAbilityContext获取沙箱地址filesDir以Stage模型为例let pathDir context.filesDir;let path pathDir /01.mp3;await fs.open(path).then((file: fs.File) {this.fd file.fd;})// 获取播放文件的大小this.fileSize fs.statSync(path).size;src.fileSize this.fileSize;this.isSeek true; // 支持seek操作avPlayer.dataSrc src;}// 以下demo为使用fs文件系统打开沙箱地址获取媒体文件地址并通过dataSrc属性进行播放(No seek模式)示例async avPlayerDataSrcNoSeekDemo() {// 创建avPlayer实例对象let avPlayer: media.AVPlayer await media.createAVPlayer();// 创建状态机变化回调函数this.setAVPlayerCallback(avPlayer);let context getContext(this) as common.UIAbilityContext;let src: media.AVDataSrcDescriptor {fileSize: -1,callback: (buf: ArrayBuffer, length: number) {let num 0;if (buf undefined || length undefined) {return -1;}num fs.readSync(this.fd, buf);if (num 0) {return num;}return -1;}}// 通过UIAbilityContext获取沙箱地址filesDir以Stage模型为例let pathDir context.filesDir;let path pathDir /01.mp3;await fs.open(path).then((file: fs.File) {this.fd file.fd;})this.isSeek false; // 不支持seek操作avPlayer.dataSrc src;}// 以下demo为通过url设置网络地址来实现播放直播码流的demoasync avPlayerLiveDemo() {// 创建avPlayer实例对象let avPlayer: media.AVPlayer await media.createAVPlayer();// 创建状态机变化回调函数this.setAVPlayerCallback(avPlayer);this.isSeek false; // 不支持seek操作avPlayer.url http://xxx.xxx.xxx.xxx:xx/xx/index.m3u8;}
}
2 SoundPool音频播放
使用SoundPool音频池提供的接口可以实现低时延短音播放。
当应用开发时经常需要使用一些急促简短的音效如相机快门音效、系统通知音效等此时建议调用SoundPool实现一次加载多次低时延播放。
SoundPool当前支持播放1MB以下的音频资源大小超过1MB的长音频将截取1MB大小数据进行播放。
本开发指导将以SoundPool进行一次低时延播放音频的过程为例向开发者讲解如何使用SoundPool。详细的API声明请参考SoundPool API参考。
过程包括创建SoundPool实例加载音频资源包括资源的解封装与解码:解码格式参考音频解码支持设置播放参数循环模式/播放优先级等播放控制播放/停止释放资源。
在应用开发过程中开发者应通过监听方法检查当前播放状态并按照一定顺序调用接口执行对应操作否则系统可能会抛出异常或生成其他未定义的行为。具体顺序可参考下列开发步骤及对应说明。
2.1 开发步骤及注意事项
调用createSoundPool方法创建SoundPool实例。
import media from ohos.multimedia.media;
import audio from ohos.multimedia.audio;
import { BusinessError } from ohos.base;let soundPool: media.SoundPool;
let audioRendererInfo: audio.AudioRendererInfo {usage : audio.StreamUsage.STREAM_USAGE_MUSIC,rendererFlags : 0
}media.createSoundPool(5, audioRendererInfo).then((soundpool_: media.SoundPool) {if (soundpool_ ! null) {soundPool soundpool_;console.info(create SoundPool success);} else {console.error(create SoundPool fail);}
}).catch((error: BusinessError) {console.error(soundpool catchCallback, error message:${error.message});
});调用load()方法进行音频资源加载。 可以传入uri或fd加载资源此处使用传入uri的方式为例更多方法请参考API文档。
import { BusinessError } from ohos.base;
import fs from ohos.file.fs;let soundID: number;
let uri: string;
async function load() {await fs.open(/test_01.mp3, fs.OpenMode.READ_ONLY).then((file: fs.File) {console.info(file fd: file.fd);uri fd:// (file.fd).toString()}); // /test_01.mp3 作为样例使用时需要传入文件对应路径。soundPool.load(uri).then((soundId: number) {console.info(soundPool load uri success);soundID soundId;}).catch((err: BusinessError) {console.error(soundPool load failed and catch error is err.message);})
}调用on(‘loadComplete’)方法用于监听“资源加载完成”。
soundPool.on(loadComplete, (soundId: number) {console.info(loadComplete, soundId: soundId);
});调用on(‘playFinished’)方法用于监听“播放完成”。
soundPool.on(playFinished, () {console.info(receive play finished message);
});调用on(‘error’)方法设置错误类型监听。
soundPool.on(error, (error) {console.info(error happened,message is : error.message);
});配置播放参数PlayParameters并调用play方法播放音频。多次调用play播放同一个soundID只会播放一次。
let soundID: number;
let streamID: number;
let playParameters: media.PlayParameters {loop: 0, // 循环0次rate: 2, // 2倍速leftVolume: 0.5, // range 0.0-1.0rightVolume: 0.5, // range 0.0-1.0priority: 0, // 最低优先级}
soundPool.play(soundID, playParameters, (error, streamId: number) {if (error) {console.info(play sound Error: errCode is ${error.code}, errMessage is ${error.message})} else {streamID streamId;console.info(play success soundid: streamId);}
});调用setLoop()方法设置循环次数。
import { BusinessError } from ohos.base;let streamID: number;
soundPool.setLoop(streamID, 1).then(() {console.info(setLoop success streamID: streamID);
}).catch((err: BusinessError) {console.error(soundpool setLoop failed and catch error is err.message);
});调用setPriority()方法设置优先级。
let streamID: number;
soundPool.setPriority(streamID, 1);调用setVolume()方法设置音量。
import { BusinessError } from ohos.base;let streamID: number;
// 先调用play方法获取到对应资源的streamIDsoundPool.setVolume(streamID, 0.5, 0.5).then(() {console.info(setVolume success);
}).catch((err: BusinessError) {console.error(soundpool setVolume failed and catch error is err.message);
});调用stop()方法终止指定流的播放。
import { BusinessError } from ohos.base;let streamID: number;
//先调用play方法给拿到对应的streamIDsoundPool.stop(streamID).then(() {console.info(stop success);
}).catch((err: BusinessError) {console.error(soundpool load stop and catch error is err.message);
});调用unload()方法卸载音频资源。
import { BusinessError } from ohos.base;let soundID: number;
// 先调用load方法获取到对应资源的soundIDsoundPool.unload(soundID).then(() {console.info(unload success);
}).catch((err: BusinessError) {console.error(soundpool unload failed and catch error is err.message);
});调用off(‘loadComplete’)方法注销加载完成监听。
soundPool.off(loadComplete);调用off(‘playFinished’)方法注销播放完成监听。
soundPool.off(playFinished);调用off(‘error’)方法注销错误错误类型监听。
soundPool.off(error);调用release()方法释放SoundPool实例。
import { BusinessError } from ohos.base;soundPool.release().then(() {console.info(release success);
}).catch((err: BusinessError) {console.error(soundpool release failed and catch error is err.message);
});2.2 完整示例
下面展示了使用SoundPool进行低时延播放的完整示例代码。
import audio from ohos.multimedia.audio;
import media from ohos.multimedia.media;
import fs from ohos.file.fslet soundPool: media.SoundPool;
let streamId: number 0;
let soundId: number 0;
let audioRendererInfo: audio.AudioRendererInfo {usage: audio.StreamUsage.STREAM_USAGE_MUSIC,rendererFlags: 1
}
let PlayParameters: media.PlayParameters {loop: 3, // 循环4次rate: audio.AudioRendererRate.RENDER_RATE_NORMAL, // 正常倍速leftVolume: 0.5, // range 0.0-1.0rightVolume: 0.5, // range 0.0-1.0priority: 0, // 最低优先级
}
let uri: string ;
async function create() {//创建soundPool实例soundPool await media.createSoundPool(5, audioRendererInfo);//注册监听loadCallback();finishPlayCallback();setErrorCallback();// 加载音频资源await fs.open(/test_01.mp3, fs.OpenMode.READ_ONLY).then((file: fs.File) {console.info(file fd: file.fd);uri fd:// (file.fd).toString()}); // /test_01.mp3 作为样例使用时需要传入文件对应路径。soundId await soundPool.load(uri);
}
async function loadCallback() {// 加载完成回调soundPool.on(loadComplete, (soundId_: number) {console.info(loadComplete, soundId: soundId_);})
}
//设置播放完成监听
async function finishPlayCallback() {// 播放完成回调soundPool.on(playFinished, () {console.info(recive play finished message);// 可进行下次播放})
}
//设置错误类型监听
function setErrorCallback() {soundPool.on(error, (error) {console.info(error happened,message is : error.message);})
}
async function PlaySoundPool() {// 开始播放,这边play也可带播放播放的参数PlayParametersstreamId await soundPool.play(soundId);// 设置循环播放次数soundPool.setLoop(streamId, 2); // 播放3次// 设置对应流的优先级soundPool.setPriority(streamId, 1);// 设置音量soundPool.setVolume(streamId, 0.5, 0.5);
}
async function release() {// 终止指定流的播放soundPool.stop(streamId);// 卸载音频资源await soundPool.unload(soundId);//关闭监听setOffCallback();// 释放SoundPoolawait soundPool.release();
}
//关闭监听
function setOffCallback() {soundPool.off(loadComplete);soundPool.off(playFinished);soundPool.off(error);
}
3 AVRecorder音频录制
使用AVRecorder可以实现音频录制功能本开发指导将以“开始录制-暂停录制-恢复录制-停止录制”的一次流程为示例向开发者讲解AVRecorder音频录制相关功能。
在进行应用开发的过程中开发者可以通过AVRecorder的state属性主动获取当前状态或使用on(‘stateChange’)方法监听状态变化。开发过程中应该严格遵循状态机要求例如只能在started状态下调用pause()接口只能在paused状态下调用resume()接口。
3.1 开发步骤及注意事项
详细的API说明请参考AVRecorder API参考。
创建AVRecorder实例实例创建完成进入idle状态。 说明 需要在avRecorder完成赋值即“avRecorder recorder; ”运行完成后再进行剩余操作。 import media from ohos.multimedia.media;
import { BusinessError } from ohos.base;let avRecorder: media.AVRecorder;
media.createAVRecorder().then((recorder: media.AVRecorder) {avRecorder recorder;
}, (error: BusinessError) {console.error(createAVRecorder failed);
})设置业务需要的监听事件监听状态变化及错误上报。
import { BusinessError } from ohos.base;// 状态上报回调函数
avRecorder.on(stateChange, (state: media.AVRecorderState, reason: media.StateChangeReason) {console.log(current state is ${state});// 用户可以在此补充状态发生切换后想要进行的动作
})// 错误上报回调函数
avRecorder.on(error, (err: BusinessError) {console.error(avRecorder failed, code is ${err.code}, message is ${err.message});
})
配置音频录制参数调用prepare()接口此时进入prepared状态。 说明 配置参数需要注意 prepare接口的入参avConfig中仅设置音频相关的配置参数如示例代码所示。 如果只需要录制音频请不要设置视频相关配置参数如果需要录制视频可以参考视频录制开发指导进行开发。直接设置视频相关参数会导致后续步骤报错。 需要使用支持的录制规格。 录制输出的url地址即示例里avConfig中的url形式为fd://xx (fd number)。需要基础文件操作接口ohos.file.fs实现应用文件访问能力获取方式参考应用文件访问与管理。 import media from ohos.multimedia.media;
import { BusinessError } from ohos.base;let avProfile: media.AVRecorderProfile {audioBitrate: 100000, // 音频比特率audioChannels: 2, // 音频声道数audioCodec: media.CodecMimeType.AUDIO_AAC, // 音频编码格式当前只支持aacaudioSampleRate: 48000, // 音频采样率fileFormat: media.ContainerFormatType.CFT_MPEG_4A, // 封装格式当前只支持m4a
}
let avConfig: media.AVRecorderConfig {audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, // 音频输入源这里设置为麦克风profile: avProfile,url: fd://35, // 参考应用文件访问与管理中的开发示例获取创建的音频文件fd填入此处
}
avRecorder.prepare(avConfig).then(() {console.log(Invoke prepare succeeded.);
}, (err: BusinessError) {console.error(Invoke prepare failed, code is ${err.code}, message is ${err.message});
})开始录制调用start()接口此时进入started状态。
// 开始录制
avRecorder.start();暂停录制调用pause()接口此时进入paused状态。
// 暂停录制
avRecorder.pause();恢复录制调用resume()接口此时再次进入started状态。
// 恢复录制
avRecorder.resume();停止录制调用stop()接口此时进入stopped状态。
// 停止录制
avRecorder.stop();重置资源调用reset()重新进入idle状态允许重新配置录制参数。
// 重置资源
avRecorder.reset();销毁实例调用release()进入released状态退出录制。
// 销毁实例
avRecorder.release();3.2 完整示例
参考以下示例完成“开始录制-暂停录制-恢复录制-停止录制”的完整流程。
import media from ohos.multimedia.media;
import { BusinessError } from ohos.base;export class AudioRecorderDemo {private avRecorder: media.AVRecorder | undefined undefined;private avProfile: media.AVRecorderProfile {audioBitrate: 100000, // 音频比特率audioChannels: 2, // 音频声道数audioCodec: media.CodecMimeType.AUDIO_AAC, // 音频编码格式当前只支持aacaudioSampleRate: 48000, // 音频采样率fileFormat: media.ContainerFormatType.CFT_MPEG_4A, // 封装格式当前只支持m4a};private avConfig: media.AVRecorderConfig {audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, // 音频输入源这里设置为麦克风profile: this.avProfile,url: fd://35, // 参考应用文件访问与管理开发示例新建并读写一个文件};// 注册audioRecorder回调函数setAudioRecorderCallback() {if (this.avRecorder ! undefined) {// 状态机变化回调函数this.avRecorder.on(stateChange, (state: media.AVRecorderState, reason: media.StateChangeReason) {console.log(AudioRecorder current state is ${state});})// 错误上报回调函数this.avRecorder.on(error, (err: BusinessError) {console.error(AudioRecorder failed, code is ${err.code}, message is ${err.message});})}}// 开始录制对应的流程async startRecordingProcess() {if (this.avRecorder ! undefined) {await this.avRecorder.release();this.avRecorder undefined;}// 1.创建录制实例this.avRecorder await media.createAVRecorder();this.setAudioRecorderCallback();// 2.获取录制文件fd赋予avConfig里的url参考FilePicker文档// 3.配置录制参数完成准备工作await this.avRecorder.prepare(this.avConfig);// 4.开始录制await this.avRecorder.start();}// 暂停录制对应的流程async pauseRecordingProcess() {if (this.avRecorder ! undefined this.avRecorder.state started) { // 仅在started状态下调用pause为合理状态切换await this.avRecorder.pause();}}// 恢复录制对应的流程async resumeRecordingProcess() {if (this.avRecorder ! undefined this.avRecorder.state paused) { // 仅在paused状态下调用resume为合理状态切换await this.avRecorder.resume();}}// 停止录制对应的流程async stopRecordingProcess() {if (this.avRecorder ! undefined) {// 1. 停止录制if (this.avRecorder.state started|| this.avRecorder.state paused) { // 仅在started或者paused状态下调用stop为合理状态切换await this.avRecorder.stop();}// 2.重置await this.avRecorder.reset();// 3.释放录制实例await this.avRecorder.release();this.avRecorder undefined;// 4.关闭录制文件fd}}// 一个完整的【开始录制-暂停录制-恢复录制-停止录制】示例async audioRecorderDemo() {await this.startRecordingProcess(); // 开始录制// 用户此处可以自行设置录制时长例如通过设置休眠阻止代码执行await this.pauseRecordingProcess(); //暂停录制await this.resumeRecordingProcess(); // 恢复录制await this.stopRecordingProcess(); // 停止录制}
}
4 音视频元数据获取
使用AVMetadataExtractor可以实现从原始媒体资源中获取元信息本开发指导将以获取一个音频资源的元信息作为示例向开发者讲解AVMetadataExtractor元信息相关功能。视频资源的元信息获取流程与音频类似由于视频没有专辑封面所以无法获取视频资源的专辑封面。
获取音频资源的元信息的全流程包含创建AVMetadataExtractor设置资源获取元信息获取专辑封面销毁资源。
4.1 开发步骤及注意事项
详细的API说明请参考AVMetadataExtractor API参考。 使用createAVMetadataExtractor()创建实例。 设置资源用户可以根据需要选择设置属性fdSrc表示文件描述符, 或者设置属性dataSrc表示dataSource描述符。 说明 开发者需根据实际情况确认资源有效性并设置 1.如果设置fdSrc可以使用ResourceManager.getRawFd打开HAP资源文件描述符使用方法可参考ResourceManager API参考。 2.如果设置dataSrc必须正确设置dataSrc中的callback属性确保callback被调用时能正确读取到对应资源使用应用沙箱路径访问对应资源参考获取应用文件路径。应用沙箱的介绍及如何向应用沙箱推送文件请参考文件管理。 获取元信息调用fetchMetadata()可以获取到一个AVMetadata对象通过访问该对象的各个属性可以获取到元信息。 可选获取专辑封面调用fetchAlbumCover()可以获取到专辑封面。 释放资源调用release()销毁实例释放资源。
4.2 完整示例
参考以下示例设置文件描述符获取一个音频的元信息和专辑封面。
import media from ohos.multimedia.media
import image from ohos.multimedia.image
import type common from ohos.app.ability.common;
import fs from ohos.file.fs;const TAG MetadataDemo
Entry
Component
struct Index {State message: string Hello World// pixelMap对象声明用于图片显示State pixelMap: image.PixelMap | undefined undefined;build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)Button() {Text(TestButton).fontSize(30).fontWeight(FontWeight.Bold)}.type(ButtonType.Capsule).margin({top: 20}).backgroundColor(#0D9FFB).width(60%).height(5%).onClick(() {// 设置fdSrc, 获取音频元信息和专辑封面异步接口以Callback形式调用this.testFetchMetadataFromFdSrcByCallback()// 设置fdSrc, 获取音频元信息和专辑封面异步接口以Promise形式调用this.testFetchMetadataFromFdSrcByPromise()// 设置dataSrc, 获取音频元信息和专辑封面this.testFetchMetadataFromDataSrc()})Image(this.pixelMap).width(300).height(300).margin({top: 20})}.width(100%)}.height(100%)}// 在以下demo中使用资源管理接口获取打包在HAP内的媒体资源文件通过设置fdSrc属性获取音频元信息并打印// 获取音频专辑封面并通过Image控件显示在屏幕上。该demo以Callback形式进行异步接口调用async testFetchMetadataFromFdSrcByCallback() {// 创建AVMetadataExtractor对象let avMetadataExtractor: media.AVMetadataExtractor await media.createAVMetadataExtractor()// 设置fdSrcavMetadataExtractor.fdSrc await getContext(this).resourceManager.getRawFd(cover.mp3);// 获取元信息callback模式avMetadataExtractor.fetchMetadata((error, metadata) {if (error) {console.error(TAG, fetchMetadata callback failed, err ${JSON.stringify(error)})return}console.info(TAG, fetchMetadata callback success, genre: ${metadata.genre})})//获取专辑封面callback模式avMetadataExtractor.fetchAlbumCover((err, pixelMap) {if (err) {console.error(TAG, fetchAlbumCover callback failed, err ${JSON.stringify(err)})return}this.pixelMap pixelMap// 释放资源callback模式avMetadataExtractor.release((error) {if (error) {console.error(TAG, release failed, err ${JSON.stringify(error)})return}console.info(TAG, release success.)})})}// 在以下demo中使用资源管理接口获取打包在HAP内的媒体资源文件通过设置fdSrc属性获取音频元信息并打印// 获取音频专辑封面并通过Image控件显示在屏幕上。该demo以Promise形式进行异步接口调用async testFetchMetadataFromFdSrcByPromise() {// 创建AVMetadataExtractor对象let avMetadataExtractor: media.AVMetadataExtractor await media.createAVMetadataExtractor()// 设置fdSrcavMetadataExtractor.fdSrc await getContext(this).resourceManager.getRawFd(cover.mp3);// 获取元信息promise模式let metadata await avMetadataExtractor.fetchMetadata()console.info(TAG, get meta data, hasAudio: ${metadata.hasAudio})// 获取专辑封面promise模式this.pixelMap await avMetadataExtractor.fetchAlbumCover()// 释放资源promise模式avMetadataExtractor.release()console.info(TAG, release success.)}// 在以下demo中使用fs文件系统打开沙箱地址获取媒体文件地址设置dataSrc属性获取音频元信息并打印// 获取音频专辑封面并通过Image控件显示在屏幕上。async testFetchMetadataFromDataSrc() {let context getContext(this) as common.UIAbilityContext// 通过UIAbilityContext获取沙箱地址filesDir以Stage模型为例let filePath: string context.filesDir /cover.mp3;let fd: number fs.openSync(filePath, 0o0).fd;let fileSize: number fs.statSync(filePath).size;// 设置dataSrc描述符通过callback从文件中获取资源写入buffer中let dataSrc: media.AVDataSrcDescriptor {fileSize: fileSize,callback: (buffer, len, pos) {if (buffer undefined || len undefined || pos undefined) {console.error(TAG, dataSrc callback param invalid)return -1}class Option {offset: number | undefined 0;length: number | undefined len;position: number | undefined pos;}let options new Option();let num fs.readSync(fd, buffer, options)console.info(TAG, readAt end, num: num)if (num 0 fileSize pos) {return num;}return -1;}}// 创建AVMetadataExtractor对象let avMetadataExtractor await media.createAVMetadataExtractor()// 设置dataSrcavMetadataExtractor.dataSrc dataSrc;// 获取元信息promise模式let metadata await avMetadataExtractor.fetchMetadata()console.info(TAG, get meta data, mimeType: ${metadata.mimeType})// 获取专辑封面promise模式this.pixelMap await avMetadataExtractor.fetchAlbumCover()// 释放资源promise模式avMetadataExtractor.release()console.info(TAG, release data source success.)}
}
参考文献 [1]OpenHarmoney应用开发文档 文章转载自: http://www.morning.ghcfx.cn.gov.cn.ghcfx.cn http://www.morning.xkhxl.cn.gov.cn.xkhxl.cn http://www.morning.pdmsj.cn.gov.cn.pdmsj.cn http://www.morning.wjfzp.cn.gov.cn.wjfzp.cn http://www.morning.httzf.cn.gov.cn.httzf.cn http://www.morning.fglxh.cn.gov.cn.fglxh.cn http://www.morning.ljxps.cn.gov.cn.ljxps.cn http://www.morning.ympcj.cn.gov.cn.ympcj.cn http://www.morning.mhpkz.cn.gov.cn.mhpkz.cn http://www.morning.tdxlj.cn.gov.cn.tdxlj.cn http://www.morning.rfdqr.cn.gov.cn.rfdqr.cn http://www.morning.zfgh.cn.gov.cn.zfgh.cn http://www.morning.syynx.cn.gov.cn.syynx.cn http://www.morning.gzzncl.cn.gov.cn.gzzncl.cn http://www.morning.dsxgc.cn.gov.cn.dsxgc.cn http://www.morning.rbkgp.cn.gov.cn.rbkgp.cn http://www.morning.ljmbd.cn.gov.cn.ljmbd.cn http://www.morning.jfbrt.cn.gov.cn.jfbrt.cn http://www.morning.tpkxs.cn.gov.cn.tpkxs.cn http://www.morning.kmkpm.cn.gov.cn.kmkpm.cn http://www.morning.nhzxr.cn.gov.cn.nhzxr.cn http://www.morning.ygxf.cn.gov.cn.ygxf.cn http://www.morning.eshixi.com.gov.cn.eshixi.com http://www.morning.nldsd.cn.gov.cn.nldsd.cn http://www.morning.bgpch.cn.gov.cn.bgpch.cn http://www.morning.gghhmi.cn.gov.cn.gghhmi.cn http://www.morning.kxrld.cn.gov.cn.kxrld.cn http://www.morning.i-bins.com.gov.cn.i-bins.com http://www.morning.wngpq.cn.gov.cn.wngpq.cn http://www.morning.yybcx.cn.gov.cn.yybcx.cn http://www.morning.pqkrh.cn.gov.cn.pqkrh.cn http://www.morning.ktmbr.cn.gov.cn.ktmbr.cn http://www.morning.qcygd.cn.gov.cn.qcygd.cn http://www.morning.rfwgg.cn.gov.cn.rfwgg.cn http://www.morning.khtyz.cn.gov.cn.khtyz.cn http://www.morning.etsaf.com.gov.cn.etsaf.com http://www.morning.pzss.cn.gov.cn.pzss.cn http://www.morning.qhkx.cn.gov.cn.qhkx.cn http://www.morning.ltypx.cn.gov.cn.ltypx.cn http://www.morning.bfcxf.cn.gov.cn.bfcxf.cn http://www.morning.jfxdy.cn.gov.cn.jfxdy.cn http://www.morning.hxmqb.cn.gov.cn.hxmqb.cn http://www.morning.tpnx.cn.gov.cn.tpnx.cn http://www.morning.hbjqn.cn.gov.cn.hbjqn.cn http://www.morning.jfbpf.cn.gov.cn.jfbpf.cn http://www.morning.fhjnh.cn.gov.cn.fhjnh.cn http://www.morning.wddmr.cn.gov.cn.wddmr.cn http://www.morning.cpnlq.cn.gov.cn.cpnlq.cn http://www.morning.ryspp.cn.gov.cn.ryspp.cn http://www.morning.qghjc.cn.gov.cn.qghjc.cn http://www.morning.tgtwy.cn.gov.cn.tgtwy.cn http://www.morning.srbl.cn.gov.cn.srbl.cn http://www.morning.cbtn.cn.gov.cn.cbtn.cn http://www.morning.ftsmg.com.gov.cn.ftsmg.com http://www.morning.prxqd.cn.gov.cn.prxqd.cn http://www.morning.hzryl.cn.gov.cn.hzryl.cn http://www.morning.qgjwx.cn.gov.cn.qgjwx.cn http://www.morning.jkfyt.cn.gov.cn.jkfyt.cn http://www.morning.ypdhl.cn.gov.cn.ypdhl.cn http://www.morning.kwqqs.cn.gov.cn.kwqqs.cn http://www.morning.lcdtb.cn.gov.cn.lcdtb.cn http://www.morning.tzmjc.cn.gov.cn.tzmjc.cn http://www.morning.ldnrf.cn.gov.cn.ldnrf.cn http://www.morning.gpmrj.cn.gov.cn.gpmrj.cn http://www.morning.gtbjf.cn.gov.cn.gtbjf.cn http://www.morning.rbhqz.cn.gov.cn.rbhqz.cn http://www.morning.nnykz.cn.gov.cn.nnykz.cn http://www.morning.mzgq.cn.gov.cn.mzgq.cn http://www.morning.nmyrg.cn.gov.cn.nmyrg.cn http://www.morning.tpchy.cn.gov.cn.tpchy.cn http://www.morning.ksggr.cn.gov.cn.ksggr.cn http://www.morning.chehb.com.gov.cn.chehb.com http://www.morning.mzcrs.cn.gov.cn.mzcrs.cn http://www.morning.tllws.cn.gov.cn.tllws.cn http://www.morning.mdplm.cn.gov.cn.mdplm.cn http://www.morning.kndst.cn.gov.cn.kndst.cn http://www.morning.ykyfq.cn.gov.cn.ykyfq.cn http://www.morning.qxjck.cn.gov.cn.qxjck.cn http://www.morning.crqbt.cn.gov.cn.crqbt.cn http://www.morning.hcwjls.com.gov.cn.hcwjls.com