更新记录
1.0.0(2026-03-30) 下载此版本
音频文件选择原生插件,支持 iOS、Android、鸿蒙三平台
平台兼容性
uni-app(4.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | × | × | × | × | 5.0 | 12 | 鸿蒙 3.0+ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
audio-file-picker-uts 使用说明
📖 目录
插件简介
audio-file-picker-uts 是一款基于 UTS (UniApp TypeScript) 开发的跨平台音频文件选择插件,支持 iOS、Android、鸿蒙 三大平台,同时兼容 uni-app 和 uni-app X。
插件提供统一的 Promise API,可帮助用户从设备本地选择音频文件并获取文件信息,方便后续上传操作。
适用场景:
- 🎤 语音消息上传
- 🎵 音乐文件上传
- 🎧 音频作品提交
- 📝 录音文件选择
功能特性
- ✅ UTS 开发:基于 TypeScript,类型安全
- ✅ 三平台支持:iOS、Android、鸿蒙
- ✅ 兼容 uni-app X:支持最新的 uni-app X 框架
- ✅ Promise API:现代化的异步 API
- ✅ 完整的类型定义:TypeScript 类型支持
- ✅ 支持云打包:无需离线打包
- ✅ 多种音频格式:MP3、WAV、M4A、FLAC 等
- ✅ 自动文件处理:自动复制到临时目录
- ✅ 临时文件清理:提供清理 API
- ✅ 跨框架支持:Vue 3、uni-app X
支持的音频格式
| 格式 | 扩展名 | iOS | Android | 鸿蒙 |
|---|---|---|---|---|
| MP3 | .mp3 | ✅ | ✅ | ✅ |
| AAC/M4A | .m4a, .aac | ✅ | ✅ | ✅ |
| WAV | .wav | ✅ | ✅ | ✅ |
| FLAC | .flac | ✅ | ✅ | ✅ |
| AIFF | .aiff | ✅ | ❌ | ❌ |
| WMA | .wma | ❌ | ✅ | ❌ |
| OGG | .ogg | ❌ | ✅ | ✅ |
| AMR | .amr | ❌ | ✅ | ✅ |
文件大小限制:建议不超过 150MB
快速开始
步骤 1:安装插件
在 HBuilderX 中:
工具 → 插件安装 → 安装插件 → 搜索 "audio-file-picker-uts" → 安装
步骤 2:配置 manifest.json
在 manifest.json → app-plus → modules 中添加:
{
"modules": {
"audio-file-picker-uts": {}
}
}
步骤 3:配置权限
iOS 权限配置
在 manifest.json → app-plus → distribute → ios → privacyDescription 中添加:
{
"ios": {
"privacyDescription": {
"NSDocumentsFolderUsageDescription": "需要访问文件以选择音频文件",
"NSAppleMusicUsageDescription": "需要访问媒体库以选择音频文件"
}
}
}
Android 权限配置
在 manifest.json → app-plus → distribute → android → permissions 中添加:
{
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.READ_MEDIA_AUDIO\"/>"
]
}
}
步骤 4:使用插件
import { pickAudio } from '@/uni_modules/audio-file-picker-uts'
// 选择音频文件
const result = await pickAudio()
if (result.success && result.data) {
console.log('文件信息:', result.data)
// 上传文件...
}
API 文档
pickAudio(options?)
选择音频文件。
类型定义:
function pickAudio(options?: PickAudioOptions): Promise<PickAudioResult>
参数:
options(PickAudioOptions, 可选):配置选项maxFileSize(number, 可选):最大文件大小(字节),默认 150MBallowedExtensions(string[], 可选):允许的扩展名列表
返回:Promise<PickAudioResult>
PickAudioOptions 结构:
interface PickAudioOptions {
maxFileSize?: number; // 最大文件大小(字节)
allowedExtensions?: string[]; // 允许的扩展名列表
}
PickAudioResult 结构:
interface PickAudioResult {
success: boolean; // 是否成功
data?: {
name: string; // 文件名
size: number; // 文件大小(字节)
path: string; // 文件路径
tempFilePath: string; // 临时文件路径(用于上传)
extension: string; // 文件扩展名
originalURL?: string; // 原始文件 URL(仅 iOS)
};
message?: string; // 错误信息
}
示例:
// 基础用法
const result = await pickAudio()
// 带配置
const result = await pickAudio({
maxFileSize: 100 * 1024 * 1024, // 100MB
allowedExtensions: ['mp3', 'wav', 'm4a']
})
// 处理结果
if (result.success && result.data) {
console.log('文件名:', result.data.name)
console.log('文件大小:', result.data.size)
console.log('文件路径:', result.data.path)
console.log('文件格式:', result.data.extension)
} else {
console.error('选择失败:', result.message)
}
错误处理:
try {
const result = await pickAudio()
if (!result.success) {
console.error('选择失败:', result.message)
}
} catch (error) {
console.error('异常:', (error as Error).message)
}
cleanTempFile(filePath)
清理临时文件。
类型定义:
function cleanTempFile(filePath: string): Promise<CleanFileCallback>
参数:
filePath(string):文件路径
返回:Promise<CleanFileCallback>
CleanFileCallback 结构:
interface CleanFileCallback {
success: boolean; // 是否成功
message?: string; // 结果信息
}
示例:
// 基础用法
const result = await cleanTempFile('/path/to/temp/file')
if (result.success) {
console.log('清理成功')
} else {
console.error('清理失败:', result.message)
}
// 上传后清理
const audioResult = await pickAudio()
if (audioResult.success && audioResult.data) {
// 上传文件
await uni.uploadFile({
url: '你的接口',
filePath: audioResult.data.tempFilePath,
name: 'audio'
})
// 清理临时文件
await cleanTempFile(audioResult.data.path)
}
使用示例
示例 1:基础用法
import { pickAudio, cleanTempFile } from '@/uni_modules/audio-file-picker-uts'
async function selectAndUpload() {
try {
// 1. 选择音频文件
const result = await pickAudio()
if (!result.success || !result.data) {
console.error('选择失败:', result.message)
return
}
const file = result.data
console.log('文件信息:', file)
// 2. 上传文件
const uploadRes = await uni.uploadFile({
url: 'https://your-api.com/upload',
filePath: file.tempFilePath,
name: 'audio',
formData: {
fileName: file.name,
fileSize: file.size
}
})
console.log('上传结果:', uploadRes)
// 3. 清理临时文件
await cleanTempFile(file.path)
} catch (error) {
console.error('错误:', (error as Error).message)
}
}
示例 2:Vue 3 组件中使用
<template>
<view class="container">
<button @click="selectAudio" class="btn-choose">
🎤 选择音频文件
</button>
<view v-if="selectedFile" class="file-info">
<text class="file-name">{{ selectedFile.name }}</text>
<text class="file-size">{{ formatSize(selectedFile.size) }}</text>
<button @click="uploadFile" class="btn-upload">
⬆️ 上传文件
</button>
</view>
</view>
</template>
<script lang="ts">
import { ref } from 'vue'
import { pickAudio, cleanTempFile } from '@/uni_modules/audio-file-picker-uts'
import type { AudioFileInfo } from '@/uni_modules/audio-file-picker-uts'
export default {
setup() {
const selectedFile = ref<AudioFileInfo | null>(null)
// 选择音频
const selectAudio = async () => {
try {
const result = await pickAudio({
maxFileSize: 150 * 1024 * 1024,
allowedExtensions: ['mp3', 'wav', 'm4a']
})
if (result.success && result.data) {
selectedFile.value = result.data
uni.showToast({ title: '选择成功', icon: 'success' })
} else {
uni.showToast({
title: result.message || '选择失败',
icon: 'none'
})
}
} catch (error) {
uni.showToast({
title: (error as Error).message,
icon: 'none'
})
}
}
// 上传文件
const uploadFile = async () => {
if (!selectedFile.value) return
try {
await uni.uploadFile({
url: 'https://your-api.com/upload',
filePath: selectedFile.value.tempFilePath,
name: 'audio',
formData: {
fileName: selectedFile.value.name,
fileSize: selectedFile.value.size
},
success: () => {
uni.showToast({ title: '上传成功', icon: 'success' })
// 清理临时文件
cleanTempFile(selectedFile.value!.path)
},
fail: (err) => {
uni.showToast({ title: '上传失败', icon: 'none' })
}
})
} catch (error) {
uni.showToast({ title: '上传失败', icon: 'none' })
}
}
// 格式化文件大小
const formatSize = (bytes: number): string => {
if (bytes < 1024) return bytes + ' B'
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB'
return (bytes / (1024 * 1024)).toFixed(2) + ' MB'
}
return {
selectedFile,
selectAudio,
uploadFile,
formatSize
}
}
}
</script>
<style scoped>
.container {
padding: 30rpx;
}
.btn-choose {
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff;
border-radius: 44rpx;
}
.file-info {
margin-top: 30rpx;
padding: 30rpx;
background: #f5f5f5;
border-radius: 16rpx;
}
.btn-upload {
margin-top: 20rpx;
background: linear-gradient(135deg, #11998e, #38ef7d);
color: #fff;
border-radius: 44rpx;
}
</style>
示例 3:错误处理
import { pickAudio } from '@/uni_modules/audio-file-picker-uts'
async function selectAudioWithRetry(maxRetries = 3) {
let lastError: Error | null = null
for (let i = 0; i < maxRetries; i++) {
try {
const result = await pickAudio()
if (result.success && result.data) {
return result.data
} else {
console.warn(`尝试 ${i + 1} 失败:`, result.message)
lastError = new Error(result.message)
}
} catch (error) {
console.warn(`尝试 ${i + 1} 异常:`, (error as Error).message)
lastError = error as Error
}
// 等待一段时间后重试
if (i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, 1000))
}
}
throw lastError || new Error('选择音频失败')
}
示例 4:批量选择(多次调用)
import { pickAudio } from '@/uni_modules/audio-file-picker-uts'
async function selectMultipleAudioFiles(count: number) {
const files: AudioFileInfo[] = []
for (let i = 0; i < count; i++) {
try {
const result = await pickAudio()
if (result.success && result.data) {
files.push(result.data)
}
} catch (error) {
console.error(`选择第 ${i + 1} 个文件失败:`, error)
break
}
}
return files
}
// 使用
const files = await selectMultipleAudioFiles(3)
console.log('选择的文件:', files)
配置说明
manifest.json 完整配置
{
"app-plus": {
"modules": {
"audio-file-picker-uts": {}
},
"distribute": {
"ios": {
"devices": "universal",
"deploymentTarget": "11.0",
"privacyDescription": {
"NSDocumentsFolderUsageDescription": "需要访问文件以选择音频文件",
"NSAppleMusicUsageDescription": "需要访问媒体库以选择音频文件"
},
"LSSupportsOpeningFilesInPlace": true,
"UISupportsDocumentBrowser": true
},
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.READ_MEDIA_AUDIO\"/>"
]
}
}
}
}
版本要求
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| HBuilderX | 3.99.0 | UTS 语法支持 |
| uni-app | 4.0.0 | UTS 运行时支持 |
| uni-app X | 1.0.0 | 完整支持 |
| Vue | 3.0 | 仅支持 Vue 3 |
平台支持
| 平台 | 支持状态 | 最低版本 |
|---|---|---|
| iOS | ✅ | iOS 11.0+ |
| Android | ✅ | Android 5.0+ |
| 鸿蒙 | ✅ | HarmonyOS 3.0+ |
| H5 | ❌ | 不支持 |
| 小程序 | ❌ | 不支持 |
注意事项
1. 平台限制
- ✅ 仅支持 App 端:iOS、Android、鸿蒙
- ❌ 不支持 H5:H5 请使用
<input type="file"> - ❌ 不支持小程序:小程序请使用
uni.chooseFile
2. Vue 版本限制
- ✅ 支持 Vue 3
- ❌ 不支持 Vue 2
3. 文件大小
- 建议限制在 150MB 以内
- 过大的文件可能导致内存问题或上传失败
4. 临时文件
- 选择的文件会自动复制到临时目录
- 上传后建议调用
cleanTempFile清理 - 临时文件在应用重启后可能会被系统清理
5. 权限申请
- iOS:需要配置隐私描述
- Android:需要存储权限(插件会自动申请)
- 鸿蒙:无需特殊权限
6. 异步处理
- 使用
async/await或Promise.then()处理结果 - 建议添加错误处理逻辑
7. 真机测试
- 必须使用真机或模拟器测试
- HBuilderX 预览模式不支持原生插件
- 需要使用自定义基座或云打包
常见问题
Q1: 插件不可用?
A:
- 确认已安装插件
- 确认 manifest.json 已配置模块
- 确认 HBuilderX 版本 >= 3.99.0
- 重启 HBuilderX
- 使用自定义基座或云打包
Q2: 提示"pickAudio is not a function"?
A:
// ❌ 错误导入
import pickAudio from '@/uni_modules/audio-file-picker-uts'
// ✅ 正确导入
import { pickAudio } from '@/uni_modules/audio-file-picker-uts'
Q3: 选择文件后没有返回?
A:
- 查看控制台日志
- 确认平台支持(仅 App 端支持)
- 检查权限配置
- 确认使用真机或模拟器
Q4: 上传失败?
A:
- 确认上传接口地址正确
- 检查网络权限
- 查看上传接口日志
- 确认使用
tempFilePath上传
Q5: 如何在 H5 或小程序中使用?
A: UTS 插件是原生能力扩展,仅支持 App 端。
H5 替代方案:
<template>
<input type="file" @change="handleFileChange" accept="audio/*" />
</template>
小程序替代方案:
uni.chooseFile({
type: 'file',
success: (res) => {
console.log(res)
}
})
Q6: 如何获取文件时长?
A: 插件目前只返回文件基本信息。如需获取音频时长,可以使用:
// iOS/Android 需要使用原生插件或 API
// 简单方案:使用 uni.createInnerAudioContext
const audio = uni.createInnerAudioContext()
audio.src = file.path
audio.onCanplay(() => {
console.log('时长:', audio.duration)
audio.destroy()
})
Q7: 支持批量选择吗?
A: 目前不支持一次选择多个文件。可以多次调用实现:
const files = []
for (let i = 0; i < 3; i++) {
const result = await pickAudio()
if (result.success && result.data) {
files.push(result.data)
}
}
更新日志
v1.0.0 (2024-01-01)
- ✅ 初始版本发布
- ✅ 基于 UTS 开发
- ✅ 支持 iOS、Android、鸿蒙三平台
- ✅ 兼容 uni-app 和 uni-app X
- ✅ 完整的 TypeScript 类型支持
- ✅ Promise 异步 API
- ✅ 支持临时文件清理
🔗 相关资源
- UTS 官方文档:https://uniapp.dcloud.net.cn/uts/
- uni-app X 文档:https://uniapp.dcloud.net.cn/uni-app-x/
- 插件市场:https://ext.dcloud.net.cn/plugin?id=xxxxx
- TypeScript 文档:https://www.typescriptlang.org/
- uni-app 文档:https://uniapp.dcloud.net.cn/
📞 技术支持
如有问题,请:
- 查看本使用说明
- 在 DCloud 论坛提问:https://ask.dcloud.net.cn/
- 在插件市场留言
祝使用愉快! 🎉

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 0
赞赏 0
下载 11697572
赞赏 1898
赞赏
京公网安备:11010802035340号