guoyu/fronted_uniapp/utils/aac-recorder.js
2025-12-10 22:53:20 +08:00

188 lines
4.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* MP3录音工具已验证可用
* 使用Android原生MediaRecorder
* 格式MP3 (128kbps高质量)
*/
class AACRecorder {
constructor() {
this.recorder = null
this.isRecording = false
this.recordFile = null
}
/**
* 开始录音
* @param {Number} maxDuration 最大录音时长毫秒默认60秒
* @returns {Promise}
*/
start(maxDuration = 60000) {
return new Promise((resolve, reject) => {
// #ifdef APP-PLUS
try {
if (this.isRecording) {
reject(new Error('正在录音中'))
return
}
console.log('[MP3录音] 开始录音...')
// 导入Android类
const MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
this.recorder = new MediaRecorder()
// 生成文件名 - 改用MP3格式
const timestamp = Date.now()
const fileName = 'record_' + timestamp + '.mp3'
// 创建文件
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, (fs) => {
fs.root.getFile(fileName, {create: true}, (fileEntry) => {
this.recordFile = fileEntry.fullPath
console.log('[MP3录音] 文件路径:', this.recordFile)
try {
// 配置录音器 - 使用MP3格式
this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC)
this.recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC) // AAC编码在MP3容器中
this.recorder.setAudioSamplingRate(16000) // 16kHz采样率
this.recorder.setAudioEncodingBitRate(128000) // 128kbps比特率更高质量
this.recorder.setMaxDuration(maxDuration) // 最大时长
this.recorder.setOutputFile(this.recordFile)
// 准备并开始
this.recorder.prepare()
this.recorder.start()
this.isRecording = true
console.log('[MP3录音] ✓ 录音已开始')
resolve()
} catch (e) {
console.error('[MP3录音] 启动失败:', e)
reject(e)
}
}, reject)
}, reject)
} catch (e) {
console.error('[MP3录音] 异常:', e)
reject(e)
}
// #endif
// #ifndef APP-PLUS
reject(new Error('只支持APP环境'))
// #endif
})
}
/**
* 停止录音
* @returns {Promise<Object>} {filePath, fileSize}
*/
stop() {
return new Promise((resolve, reject) => {
// #ifdef APP-PLUS
if (!this.isRecording) {
reject(new Error('未在录音'))
return
}
try {
console.log('[MP3录音] 停止录音...')
// 停止录音使用try-catch防止崩溃
try {
this.recorder.stop()
} catch (e) {
console.warn('[MP3录音] 停止时警告:', e.message)
}
// 释放资源
try {
this.recorder.release()
} catch (e) {
console.warn('[MP3录音] 释放时警告:', e.message)
}
this.isRecording = false
this.recorder = null
console.log('[MP3录音] ✓ 录音已停止')
// 等待文件完全写入
setTimeout(() => {
this.getFileInfo(this.recordFile)
.then(fileInfo => {
console.log('[MP3录音] 文件大小:', fileInfo.size, 'bytes')
if (fileInfo.size < 1000) {
console.warn('[MP3录音] ⚠️ 文件较小,可能录音时间太短')
}
resolve({
filePath: this.recordFile,
fileSize: fileInfo.size
})
})
.catch(reject)
}, 500)
} catch (e) {
console.error('[MP3录音] 停止异常:', e)
this.isRecording = false
reject(e)
}
// #endif
})
}
/**
* 获取文件信息
*/
getFileInfo(filePath) {
return new Promise((resolve, reject) => {
// #ifdef APP-PLUS
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
entry.file((file) => {
resolve({
name: file.name,
size: file.size,
type: file.type
})
}, reject)
}, reject)
// #endif
})
}
/**
* 取消录音
*/
cancel() {
if (this.isRecording) {
try {
this.recorder.stop()
this.recorder.release()
} catch (e) {
console.warn('[MP3录音] 取消时警告:', e.message)
}
this.isRecording = false
this.recorder = null
}
}
/**
* 检查是否正在录音
*/
checkRecording() {
return this.isRecording
}
}
export default new AACRecorder()