基于鸿蒙的音频深度伪造检测应用(前端),使用deveco studio ,采用arkTS开发。
项目采用标准的 HarmonyOS 应用结构,核心代码位于 src/main/ets
目录下:
- Audio 目录:包含音频核心功能模块(如播放、录制、数据库操作等组件)。
- commons/comp:存放公共组件。
- entryability:应用入口能力,如
EntryAbility.ets
定义应用启动逻辑。 - pages:页面组件,
Index.ets
为主页,recordIndex.ets
为录音页。 - utils:工具类,如权限管理 (
Permission.ets
) 和窗口管理 (WindowManager.ets
)。 - resources:存放资源文件(如图片、配置文件
module.json5
)。
代码实现了一个 音频伪造检测 功能,核心流程如下:
- 状态管理:
@State percent
:动态显示伪造概率百分比。@State loading
:控制上传按钮的禁用状态和文本显示。@State name
:显示用户选择的文件名。
- UI 组件:
- 通过
Text
组件动态显示百分比和文件名,颜色根据概率值切换(红/绿)。 - 通过
Button
组件实现文件上传和页面跳转功能。
- 通过
- 文件选择:
- 使用
picker.DocumentViewPicker
创建文件选择器,限制用户选择.wav
/.mp3
/.m4a
格式的音频文件。 - 通过
authMode: true
请求用户授权访问文件。
- 使用
- 文件处理:
- 将选中的文件复制到应用缓存目录(
context.cacheDir
),避免直接操作原始文件导致的权限问题。 - 使用
fs.copyFileSync
实现文件拷贝,生成带时间戳的新文件名。
- 将选中的文件复制到应用缓存目录(
- 网络通信:
- 使用
rcp
模块创建Session
,通过multipart/form-data
格式上传文件。 - 调用
session.post
发送 POST 请求到服务器http://110.41.61.229:3006/common/upload
。
- 使用
- 响应处理:
- 解析服务器返回的 JSON 数据,提取
probability
字段计算伪造概率百分比。 - 通过
promptAction.showToast
显示服务器返回的提示信息(成功/失败)。
- 解析服务器返回的 JSON 数据,提取
- 通过
router.pushUrl
跳转到录音页面 (pages/recordIndex
),使用Single
模式确保页面栈唯一。
省略部分片段,仅供参考逻辑。
// 文件选择与上传逻辑
const documentViewPicker = new picker.DocumentViewPicker(context);
//...
documentSelectOptions.fileSuffixFilters = ['.wav','.mp3','m4a'];
//...
await documentViewPicker.select(documentSelectOptions).then((result: string[]) => {
//...
// 文件拷贝到缓存目录
fs.copyFileSync(file.fd, copyFilePath);
//...
// 构造 FormData 并发送请求
session.post('http://110.41.61.229:3006/common/upload', formData)
.then(response => {
this.percent = Number((parseFloat(a.probability)*100).toFixed(2));
});
});
该功能通过 文件选择 → 本地缓存 → HTTP 上传 → 结果解析 的流程实现音频伪造检测,结合状态驱动 UI 更新,并提供了友好的用户交互提示。代码中需注意文件权限管理和网络请求的异常处理,确保应用稳定性和安全性。
- 权限声明与请求:
- 在组件中声明需要
ohos.permission.MICROPHONE
权限。 - 通过
getPermission
方法调用Permission.requestPermissions
动态申请麦克风权限。 - 若用户拒绝授权,弹出对话框(
promptAction.showDialog
)引导用户跳转系统设置页面重新授权。
- 在组件中声明需要
- 录音触发:
- 页面底部通过
AudioRecordComp
组件实现录音按钮的 UI 和交互。 - 该组件接收
onEnd
回调函数,当录音结束时,将录音数据(IInterviewAudioItem
对象)通过回调传递到父组件。
- 页面底部通过
- 数据存储:
- 使用
audioDB.add(item)
将录音数据(如文件名、路径、时长等)存入本地数据库(如 SQLite)。 - 通过
audioDB.getAllData()
获取所有录音记录,并更新@State list
状态驱动 UI 刷新。
- 使用
- 列表渲染:
- 通过
List
和ForEach
动态渲染录音列表,每条记录使用RecordingListItemComp
组件显示基本信息(如文件名、时长)。 - 点击列表项时,通过
currentItem
状态控制展开/收起对应的AudioPlayer
播放器组件。
- 通过
- 音频播放:
AudioPlayer
组件接收当前选中录音项(currentItem
),实现播放、暂停、删除等功能。- 删除操作后,通过
getList
回调重新从数据库加载数据,更新列表状态。
省略部分片段,仅供参考逻辑。
// 权限请求逻辑
async getPermission() {
const isAgree = await Permission.requestPermissions(this.permissions);
if (!isAgree) {
const res = await promptAction.showDialog(this.confirmConfig);
if (res.index === 1) await Permission.openPermissionsSetting(this.permissions);
}
}
//...
// 录音结束回调(保存数据并刷新列表)
AudioRecordComp({
onEnd: (item: IInterviewAudioItem) => {
this.list = audioDB.add(item); // 存入数据库并更新列表
}
})
//...
// 点击列表项展开播放器
ListItem().onClick(() => {
if (this.currentItem.id === item.id) {
this.currentItem = {} as IInterviewAudioItem; // 收起
} else {
this.currentItem = item; // 展开
}
})
//...
- 状态驱动:
@State list
:存储所有录音记录,列表数据变化自动触发 UI 更新。@State currentItem
:控制当前选中录音项的播放器展开状态。@StorageProp('topHeight')
:持久化存储顶部安全区域高度,适配不同设备。
- 布局设计:
- 使用
RelativeContainer
实现相对布局,包含导航栏、标题、录音列表和底部录音按钮。 - 录音按钮固定在页面底部,通过
alignRules
实现动态位置调整。
- 使用
录音功能通过 权限申请 → 录音触发 → 数据存储 → 列表渲染 → 播放交互 的流程实现,核心依赖以下模块:
- 权限管理模块(
Permission.ets
):处理动态权限申请和系统设置跳转。 - 数据库模块(
AudioDB.ets
):实现录音数据的增删查改。 - 录音组件(
AudioRecordComp.ets
):封装录音开始/结束、文件保存逻辑。 - 播放组件(
AudioPlayer.ets
):实现音频播放控制。
代码通过状态管理和组件化设计,确保 UI 与数据的实时同步,并提供流畅的用户交互体验。