家人们,在鸿蒙应用开发这个超广阔的领域里,音频处理可是相当重要的一环!它让应用的功能更丰富,用户体验也更好啦。像社交类应用里收发语音消息,教育类应用播放有声读物,还有音乐类应用的核心播放功能,都离不开音频处理。通过有效的音频处理,应用能和用户互动得更生动、更直接,用户用的时候既能享受听觉上的快乐,又觉得方便,应用的吸引力和实用性一下子就提升了。
在音频处理的各种功能实现里,用 AvPlayer 实现录音朗读功能真的超亮眼!录音功能能满足大家记录声音、语音输入这些需求,朗读功能在获取信息、无障碍辅助这些方面也特别关键。把这俩功能结合起来,再借助 AvPlayer 强大的媒体播放管理能力,就能打造出超实用、功能超丰富的音频交互体验。比如说在学习类应用里,用户可以把自己的学习笔记录成语音,之后用 AvPlayer 的朗读功能来复习,既方便又高效,完全符合咱现代用户快节奏的学习和生活需求。这个功能的实现,不仅展示了鸿蒙开发框架在多媒体处理方面有多厉害,也给开发者们提供了超多创新空间,大家可以尽情去探索更多好玩又实用的音频应用场景啦!
搭建鸿蒙开发环境是开启鸿蒙应用开发之旅的首要任务,而 DevEco Studio 则是我们手中的关键工具,它是基于 IntelliJ IDEA Community 开源版本精心打造的,面向华为终端全场景多设备的一站式集成开发环境(IDE),为我们提供了从工程模板创建、开发、编译、调试到发布等端到端(E2E)的 HarmonyOS 应用开发服务。
首先,我们需要前往华为开发者联盟官网下载 DevEco Studio 安装包。下载完成后,双击安装包开始安装,在安装过程中,会自动安装 Open JDK 1.8,这是 DevEco Studio 编译构建所依赖的。安装选项界面中,记得勾选 64 - bit launcher,然后按照提示逐步完成安装。
安装完成后,首次运行 DevEco Studio 时,选择 “Do not import settings”,点击 “OK”。接着,工具会自动检查本地路径下是否存在 HarmonyOS SDK,如果不存在,会弹出向导提示下载。默认情况下,SDK 会下载到 user 目录下,当然你也可以指定存储路径,但要注意路径不能包含中文字符。在下载过程中,SDK Manager 会自动下载该 SDK 包依赖的工具链,默认会下载最新版本的 HarmonyOS Java 语言 SDK 和 Toolchains,在弹出的 “License Agreement” 窗口,点击 “Accept” 开始下载。
如果工程还会用到 JS、C/C++ 语言和预览器,我们还需要进行额外的配置。点击欢迎页中的 “Configure(或图标)” -> “Settings”,进入 HarmonyOS SDK 页面。在 “SDK Platforms” 中,勾选对应的 SDK 包,在 “SDK Tools” 中勾选 Previewer,然后点击 “Apply”,SDK Manager 会自动将 SDK 包和预览器工具链下载到之前设置的 SDK 存储路径中。
在鸿蒙应用里,要是想用录音功能,那肯定得申请麦克风权限。毕竟麦克风可是获取声音的关键设备,要是没有权限,应用就没法用麦克风录音啦。
申请麦克风权限有下面这几个步骤:
声明权限:在entry/src/main/module.json5
文件中添加权限声明,代码如下:
{
"module": {
// 其他配置项...
"requestPermissions": [
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:apply_microphone",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}
其中,name
指定权限名称为 “ohos.permission.MICROPHONE”,reason
是申请权限的原因,这里引用了$string:apply_microphone
,这个字符串需要在entry/src/main/resources/base/element/string.json
文件中进行定义,例如:
{
"string": [
{
"name": "apply_microphone",
"value": "用于录音功能,获取麦克风权限"
}
]
}
usedScene
用于描述权限的使用场景,abilities
指定哪些 Ability 会使用该权限,when
表示何时使用权限,“inuse” 表示在使用相关功能时申请权限。
检查权限:在代码中,我们可以使用abilityAccessCtrl
模块来检查是否已经拥有麦克风权限。示例代码如下:
import { abilityAccessCtrl, Permissions } from '@ohos.abilityAccessCtrl';
import bundleManager from '@ohos.bundle.bundleManager';
async function checkMicrophonePermission() {
let atManager = abilityAccessCtrl.createAtManager();
let tokenId: number;
try {
let bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
let appInfo = bundleInfo.appInfo;
tokenId = appInfo.accessTokenId;
} catch (err) {
console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`);
return false;
}
let grantStatus = await atManager.checkAccessToken(tokenId, Permissions.MICROPHONE);
return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
}
申请权限:如果检查发现没有权限,就需要向用户申请权限。使用abilityAccessCtrl
模块的requestPermissionsFromUser
方法来申请权限,示例代码如下:
import { abilityAccessCtrl, common, Permissions } from '@ohos.abilityAccessCtrl';
async function requestMicrophonePermission(context: common.UIAbilityContext) {
let atManager = abilityAccessCtrl.createAtManager();
let permissions: Array<Permissions> = [Permissions.MICROPHONE];
let result = await atManager.requestPermissionsFromUser(context, permissions);
return result.authResults.every((authResult) => authResult === 0);
}
在实际用的时候呢,一般是先调用checkMicrophonePermission
检查一下权限,要是没有权限,就调用requestMicrophonePermission
去申请权限,然后根据申请的结果做相应的操作。比如说:
import { getContext } from '@ohos.app.ability';
@Entry
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
async aboutToAppear() {
let hasPermission = await checkMicrophonePermission();
if (!hasPermission) {
let isGranted = await requestMicrophonePermission(this.context);
if (isGranted) {
console.log('麦克风权限已授予');
} else {
console.log('用户拒绝授予麦克风权限');
}
}
}
build() {
// 页面布局等代码
}
}
好啦,按照上面这些步骤,开发环境就搭好啦,麦克风权限也申请完咯,这样后续用 AvPlayer 实现录音朗读功能就有基础啦。
AVPlayer 是鸿蒙多媒体框架中极为关键的播放管理类,它肩负着管理和播放媒体资源的重任,就像是一位经验丰富的指挥家,精准地掌控着音频播放的每一个环节 。无论是本地存储的音频文件,还是来自网络的音频流,AVPlayer 都能轻松应对,将其转化为美妙的声音传递给用户。它支持多种常见的音频格式,如 MP3、AAC 等,这使得开发者在进行音频播放功能开发时,无需过多担忧格式兼容性问题,能够更加专注于功能的实现和用户体验的优化。
在鸿蒙开发中,AVPlayer 扮演着举足轻重的角色。它提供了一系列丰富且易于使用的接口,让开发者能够便捷地实现音频的播放控制。通过这些接口,开发者可以轻松地实现播放、暂停、跳转、停止等基本操作,满足用户在不同场景下的音频播放需求。例如,在音乐播放应用中,用户可以通过调用 AVPlayer 的接口,实现歌曲的播放、暂停、上一曲、下一曲等操作,为用户带来流畅的音乐播放体验。同时,AVPlayer 还支持设置播放参数,如音量调节、播放倍速设置、焦点模式选择等,这些功能进一步丰富了音频播放的灵活性和个性化,能够满足不同用户的多样化需求。在一些语言学习类应用中,用户可以根据自己的学习进度和能力,通过 AVPlayer 设置不同的播放倍速,以便更好地学习和理解音频内容。
AVRecorder 是专门用于音频录制的工具,它就像是一位忠实的记录者,能够准确地捕获声音信号,并将其转化为音频数据进行存储 。在音频录制过程中,AVRecorder 的工作方式严谨而有序。首先,它会与设备的麦克风等音频输入设备建立连接,实时获取外界的声音信号。然后,根据预先设置的录制配置参数,对获取到的声音信号进行处理和编码。这些配置参数涵盖了多个方面,包括音频源类型(如选择麦克风作为音频源)、音频编码格式(如常见的 AAC 编码格式,它在保证音质的同时,能够有效地控制文件大小)、音频采样率(例如 48kHz 的采样率可以提供高质量的音频录制效果,适用于大多数音频录制场景)、音频声道数(单声道或立体声等选择,以满足不同的录制需求)以及封装格式(如 MPEG - 4 音频容器格式,常用于存储音频数据)等。通过合理设置这些参数,AVRecorder 能够根据不同的应用场景和需求,生成符合要求的音频文件,并将其存储到指定的位置,通常是应用的沙箱目录中,以确保数据的安全性和隔离性。
AVRecorder 的功能强大且全面,为音频录制提供了丰富的操作选项。它不仅支持基本的开始录音和结束录音操作,还具备暂停录制和恢复录制的功能,这在一些需要灵活控制录制过程的场景中非常实用。在采访、会议记录等场景中,用户可能需要根据实际情况暂停和恢复录音,AVRecorder 的这些功能就能很好地满足此类需求。同时,AVRecorder 还提供了获取录音状态、获取音频捕获器最大振幅等功能。通过获取录音状态,开发者可以实时了解录音的进度和状态,以便在界面上向用户展示准确的信息;而获取音频捕获器最大振幅的功能,则可以用于实现一些有趣的音频可视化效果,如根据声音大小动态显示柱状图、波形图等,增强用户与应用之间的交互性和趣味性 。
在鸿蒙应用里用 AVRecorder 录音,首先得在应用沙箱里搞个文件,用来存录制的音频数据。这就跟准备个空白笔记本一样,等着记声音 “文字” 呢。
要创建录音文件,关键第一步就是拿到应用沙箱的文件目录。在鸿蒙开发中,用getContext(this).filesDir
就能获取应用的文件目录。这个目录就像是你的私人文件柜,是应用专属的存储空间,数据的安全性和隔离性都有保障。
有了文件目录后,还得生成一个独一无二的文件路径,这样才能保证录音文件是唯一的。一般的做法就是结合当前时间戳来生成文件名,比如:
const ctx = getContext(this);
const filePath = ctx.filesDir + '/' + Date.now() + '.m4a';
咱用Date.now()
获取当前时间戳,把它当成文件名的一部分,再加上.m4a
文件后缀,就搞出了一个独一无二的文件路径,比如说/data/user/0/com.example.myapp/files/1678945632145.m4a
。
接着呢,用fileIo.openSync
方法以读写模式打开文件,要是文件不存在,就直接创建一个。这就跟打开笔记本一样,要是没找到笔记本,那就新弄一个:
import fileIo from '@ohos.file.fs';
const file = fileIo.openSync(filePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ\_WRITE);
const fd = file.fd;
fileIo.OpenMode.CREATE
表示如果文件不存在则创建,fileIo.OpenMode.READ_WRITE
表示以读写模式打开文件。通过file.fd
获取文件描述符fd
,后续在配置录音参数时会用到它。
AVRecorder 录音时,录音配置对象就像是一本 “指挥手册”,里面详细列出了各种录音参数,这些参数直接影响着录出来音频的质量和格式。
音频源类型是录音配置里的一个基础参数,它主要用来确定声音从哪儿来。一般来说,咱们都是拿麦克风当音频源。在鸿蒙开发里,设置方法是这样的:
const config: media.AVRecorderConfig = {
audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC,
// 其他配置项...
};
咱把audioSourceType
设成media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC
,这就表示要用麦克风来采集声音啦。
编码格式、采样率还有声道数这些参数,对音频质量影响可大了。编码格式决定了音频数据怎么压缩和存储,像常见的 AAC(Advanced Audio Coding),它压缩比高,音质也不错,在音频领域用得可多了。在鸿蒙开发里,设置 AAC 编码格式是这样弄的:
const config: media.AVRecorderConfig = {
// 其他配置项...
profile: {
audioCodec: media.CodecMimeType.AUDIO_AAC,
audioSampleRate: 48000,
audioChannels: 1
}
};
把audioCodec
设成media.CodecMimeType.AUDIO_AAC
,意思就是用 AAC 编码格式啦;audioSampleRate
设为 48000,也就是采样率 48kHz,这采样率很常见,录出来的音频质量挺高的;audioChannels
设为 1,就是用单声道录制,像录语音这种场景就很合适,既能减少数据量,又能满足基本的语音记录要求。
除了上面这些参数,音频比特率和封装格式这些参数也得好好配置。音频比特率决定了每秒传输多少音频数据,跟音频质量还有文件大小关系可大了。比如说,把音频比特率设为 100000,就表示每秒传输 100000 比特的数据。
const config: media.AVRecorderConfig = {
// 其他配置项...
profile: {
audioBitrate: 100000,
// 其他配置项...
}
};
在鸿蒙开发里,封装格式其实就是规定音频数据放在什么样的存储容器里。像常用的 MPEG - 4 音频容器格式(media.ContainerFormatType.CFT_MPEG_4A
)就属于一种封装格式啦。
const config: media.AVRecorderConfig = {
// 其他配置项...
profile: {
fileFormat: media.ContainerFormatType.CFT_MPEG_4A,
// 其他配置项...
}
};
最后,别忘了设置录音文件的输出路径哦,就用之前获取的那个文件描述符fd
来指定输出位置就行啦:
const config: media.AVRecorderConfig = {
// 其他配置项...
url: `fd://${fd}`
};
这么配置之后,AVRecorder 就能按咱们设定的参数录音啦,生成的音频文件也肯定符合要求。
录完音、调好参数,就可以用 AVRecorder 开始录音啦。这就好比按下录音设备的开始键,正式开启声音的记录之旅。
用media.createAVRecorder
方法创建 AVRecorder 实例,这可是录音的核心对象,就像拿到了一台超专业的录音设备:
let avRecorder;
try {
avRecorder = await media.createAVRecorder();
} catch (err) {
console.error(`创建AVRecorder失败: ${err.message}`);
return;
}
创建实例后,用await avRecorder.prepare(config)
方法把之前设置好的录音参数应用到 AVRecorder 实例里,这样就为录音做好准备啦:
try {
await avRecorder.prepare(config);
} catch (err) {
console.error(`准备录音失败: ${err.message}`);
if (avRecorder) {
avRecorder.release();
}
return;
}
等一切都弄好啦,直接调用await avRecorder.start()
方法就可以开始录音啦。这时候呢,AVRecorder 就会按照之前设置好的参数,通过麦克风把声音收集起来,然后自动转化成音频数据,存到指定的文件里咯:
try {
await avRecorder.start();
console.log('开始录音');
} catch (err) {
console.error(`开始录音失败: ${err.message}`);
if (avRecorder) {
avRecorder.release();
}
return;
}
要是想停止录音啦,就调用await avRecorder.stop()
方法把音频采集停下来,接着再调用await avRecorder.release()
方法,把 AVRecorder 占着的资源释放掉,这就跟关掉录音设备、清理相关资源是一个道理~
if (avRecorder) {
try {
await avRecorder.stop();
await avRecorder.release();
console.log('停止录音并释放资源');
} catch (err) {
console.error(`停止录音或释放资源失败: ${err.message}`);
}
}
录音的时候,可能会碰到些小状况,得好好处理。像创建 AVRecorder 实例、准备录音、开始录音这些步骤,要是出错了,咱就得赶紧抓住错误,做点相应处理,比如把错误信息打印出来,把资源释放掉,这样才能保证应用稳稳当当的。这么一来,咱就成功用 AVRecorder 实现录音功能啦,为后面的音频处理和应用打好了基础。
在鸿蒙开发里,用media.createAVPlayer
方法就能创建 AVPlayer 实例啦,这可是实现朗读功能的第一步哦,就好比开启了一台朗读机器。示例代码如下:
let avPlayer;
try {
avPlayer = await media.createAVPlayer();
console.log('AVPlayer实例创建成功');
} catch (err) {
console.error(`创建AVPlayer实例失败: ${err.message}`);
}
创建 AVPlayer 实例的时候,说不定会碰上些小麻烦。比如说,要是设备资源不够,media.createAVPlayer
方法就会抛异常。这时候,咱们可以用try...catch
块把异常抓住处理一下。就像上面代码里,在catch
块里把错误信息打印出来,这样开发者调试和排查问题就方便多啦。还有哦,要是创建实例的时候应用权限不够,也可能创建失败。所以在创建之前,一定要记得确认应用已经申请了必要的权限。
要实现朗读功能,给 AVPlayer 设置播放资源可是关键的一步,这就跟给朗读机器准备好要读的东西一样。播放资源呢,既可以是本地的录音文件,也能是网络上的音频资源。
要是用本地录音文件,首先得拿到文件的路径。在应用沙箱里,我们可以通过之前录音时生成的文件路径来设置播放资源。比如说,把录音文件路径存到filePath
变量里,设置播放资源的代码像下面这样::
import fileIo from '@ohos.file.fs';
if (avPlayer && filePath) {
try {
const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_ONLY);
avPlayer.url = `fd://${file.fd}`;
console.log('设置本地播放资源成功');
} catch (err) {
console.error(`设置本地播放资源失败: ${err.message}`);
}
}
嘿,咱就用fileIo.openSync
方法,以只读模式把文件打开,接着通过avPlayer.url = fd://\${file.fd};
把文件描述符对应的路径设成播放资源就行啦。
要是网络音频资源,那就更简单咯,直接把网络音频的 URL 设置成播放资源就 OK。比如说:
if (avPlayer) {
const networkUrl = 'https://example.com/audio.mp3';
avPlayer.url = networkUrl;
console.log('设置网络播放资源成功');
}
设置网络播放资源的时候,得先保证设备连上网了,而且应用也申请了网络访问权限哦。要是网络连接不太稳定,或者权限不够,就可能加载不了网络音频资源。这时候可以在avPlayer.on('error', (err) => {... })
回调函数里捕获错误,再做些相应处理,比如提醒用户检查一下网络连接啥的。
咱用 AVPlayer 的方法,就能实现播放、暂停、停止、跳转这些播放控制功能啦。这样用户就能按照自己的想法,灵活控制朗读过程,就跟操作一台超多功能的朗读设备一样简单。
调用avPlayer.play()
方法就能实现播放功能,示例代码如下:
if (avPlayer) {
try {
avPlayer.play();
console.log('开始播放');
} catch (err) {
console.error(`播放失败: ${err.message}`);
}
}
要是想暂停播放,直接调用avPlayer.pause()
方法就行啦,代码如下:
if (avPlayer) {
try {
avPlayer.pause();
console.log('暂停播放');
} catch (err) {
console.error(`暂停失败: ${err.message}`);
}
}
想停止播放的话,就调用avPlayer.stop()
方法,示例如下:
if (avPlayer) {
try {
avPlayer.stop();
console.log('停止播放');
} catch (err) {
console.error(`停止失败: ${err.message}`);
}
}
想实现跳转功能,比如跳到指定的播放位置(单位是毫秒),很简单,用avPlayer.seek(time)
方法就行。这里的time
就是你想跳转的时间点,代码如下:
if (avPlayer) {
const targetTime = 10000; // 跳转到10秒的位置
try {
avPlayer.seek(targetTime);
console.log(`跳转到 ${targetTime} 毫秒处`);
} catch (err) {
console.error(`跳转失败: ${err.message}`);
}
}
播放控制的时候,记得留意 AVPlayer 的状态哦。比如说,调用play
方法之前,得先确保 AVPlayer 已经设置好播放资源,而且处于能播放的状态,不然说不定会抛出异常呢。可以监听avPlayer.on('stateChange', (state) => {... })
这个事件来获取 AVPlayer 的状态,然后根据不同状态做对应的操作。像在initialized
状态下调用prepare
方法,只有到了prepared
状态才能进行播放这些操作。
在鸿蒙开发里,要是能监听 AVPlayer 的播放进度,然后在界面上实时显示播放进度条,那可太方便啦!用户能更直观地知道播放状态,体验感直接拉满。好在 AVPlayer 提供了timeUpdate
事件,专门用来监听播放进度变化。实现这个功能其实不难,按下面几步来就行:
先在组件里定义两个状态变量,一个存音频的总时长,另一个存当前播放进度。
@State total: number = 0;
@State value: number = 0;
接着呢,创建一个 AVPlayer 实例,设置好播放资源后,监听timeUpdate
事件。每次这个事件触发,就把value
状态变量更新成当前播放进度。还有哦,在stateChange
事件的prepared
状态回调里,获取音频的总时长,然后更新total
状态变量。
if (avPlayer) {
avPlayer.on('timeUpdate', (time) => {
this.value = time;
});
avPlayer.on('stateChange', state => {
if (state === 'prepared') {
this.total = avPlayer.duration;
}
});
}
接下来,在界面上用Slider
组件展示播放进度条就行啦。把Slider
组件的value
属性和value
状态变量绑在一起,max
属性和total
状态变量绑一起,播放进度就能实时显示出来咯。
Slider({ value: this.value, min: 0, max: this.total, style: SliderStyle.OutSet })
.showTips(true)
.onChange((value: number) => {
if (avPlayer) {
avPlayer.seek(value);
}
})
.width('100%')
.height(4);
上面代码里,showTips(true)
就是显示进度条提示信息啦。在 onChange
事件回调里,当用户拖动进度条的时候,就会调用 avPlayer.seek(value)
方法,把播放位置跳到用户指定的进度。
想让录音质量变好其实有好多办法哦,能让录出来的声音又清楚又干净。调整录音参数就是个挺重要的办法呢。配置录音参数的时候,像音频采样率、比特率还有声道数这些参数,设置得合理不合理,对录音质量影响可大啦。采样率高一点,比如说 48kHz ,比特率也高一点,128kbps 以上,一般来说音质就会更好,不过这样文件也会变得更大。要是你对音质要求比较高,而且存储和传输都不是问题,那就可以把采样率和比特率适当调高些;但要是你更在意文件大小还有传输效率,那在保证基本音质的情况下,把这些参数调低也没问题。声道数方面呢,单声道用来录语音啥的就挺合适,立体声更适合录音乐这种需要声音有立体感的场景,你就根据自己实际需要选就行。
选个合适的麦克风也很关键哦。不同类型的麦克风,在灵敏度、指向性还有频率响应这些方面都不太一样,得根据录音场景和需求来挑。要是个人录音的话,手机或者电脑的内置麦克风用起来方便,就是音质可能不太好;外接麦克风一般录出来的效果会更好,像电容式麦克风,灵敏度超高,能捕捉到特别细微的声音细节,很适合专业录音;动圈式麦克风对环境噪音没那么敏感,在嘈杂的地方用挺合适。要是在安静的室内录语音,电容式麦克风就能发挥它灵敏度高的优点,录出来的语音可清楚啦;要是在户外或者有点吵的地方录音,动圈式麦克风就能更好地抵抗环境噪音,保证录出来的声音清楚。另外呢,也可以考虑用带降噪功能的麦克风,这样录音质量还能再提高些。
除了这些,选个好的录音环境也很重要哦。理想的录音环境得没什么噪音,也没有回声。一般来说,在室内录音比在室外好,在室内的时候,可以用厚窗帘、地毯、泡沫板这些吸音材料,减少回声和混响,让录音质量更好。可千万别在太吵的地方录音,像靠近马路、工厂这些噪音大的地方,不然背景噪音会干扰录音的。要是条件允许,去专门的录音室录音就再好不过啦,录音室一般都做过特殊的声学处理,能把噪音和回声降得很低,给录音提供一个很棒的环境。还有哦,录音的时候一定要让麦克风稳稳的,别让它晃来晃去或者撞到别的东西,不然会产生额外的噪音,影响录音质量哒。
家人们,咱已经成功在鸿蒙开发里用 AvPlayer 实现录音朗读功能啦!从最开始搭建开发环境、申请权限,再到用 AVRecorder 录音、AVPlayer 朗读,最后对功能优化拓展,每一步可都是技术和咱开发者智慧的体现呀!在这个过程中,咱对 AVPlayer 和 AVRecorder 的强大功能还有使用方法都摸得透透的,像怎么创建录音文件、配置录音参数、控制播放这些关键技术点,都轻松拿捏。有了这些知识和技能,以后开发超棒的音频应用就更有底气啦!
往后看,音频处理这块儿的发展空间可大了去了。随着人工智能技术越来越厉害,咱完全可以把语音识别、语音合成这些 AI 技术和录音朗读功能结合起来,让音频交互体验更智能。录音完了,能自动把语音转成文字,还能编辑处理;朗读的时候,根据文本内容生成超自然流畅的语音,甚至还能实现多语言朗读。而且,鸿蒙生态越来越完善,AVPlayer 和 AVRecorder 这些多媒体接口也会不断优化更新,给咱开发者提供更多超厉害的功能和更方便的开发方式。咱就等着用这些新特性,开发出又创新又实用的音频应用,满足用户各种各样的需求,为鸿蒙应用生态的繁荣出份力!