guoyu/fronted_uniapp/pages/mp3-record-test.vue

302 lines
11 KiB
Vue
Raw Normal View History

2025-12-10 22:53:20 +08:00
<template>
<view class="test-page">
<view class="header">🎵 MP3录音测试</view>
<view class="tip-box">
<text>测试MP3格式录音如果这个也失败说明不是格式问题</text>
</view>
<view class="card">
<view class="card-title">📱 设备信息</view>
<view class="info">{{ deviceInfo }}</view>
</view>
<view class="card">
<button @click="testMP3Record" :disabled="testing" class="btn-primary">
{{ testing ? '录音中...' : '测试MP3录音3秒' }}
</button>
<view class="result">{{ result }}</view>
</view>
<view class="card">
<view class="card-title">📋 日志</view>
<view class="log-box">
<text v-for="(log, index) in logs" :key="index" class="log-line">{{ log }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
deviceInfo: '',
testing: false,
result: '未测试',
logs: [],
recorder: null
}
},
onLoad() {
this.getDeviceInfo()
this.checkPermission()
},
methods: {
log(msg) {
const time = new Date().toLocaleTimeString()
this.logs.push(`[${time}] ${msg}`)
console.log(msg)
},
getDeviceInfo() {
// #ifdef APP-PLUS
this.deviceInfo = `${plus.os.name} ${plus.os.version} (${plus.device.model})`
this.log(`设备: ${this.deviceInfo}`)
// #endif
},
checkPermission() {
// #ifdef APP-PLUS
const result = plus.android.checkPermission('android.permission.RECORD_AUDIO')
this.log(`权限状态: ${result === 1 ? '已授权' : '未授权'}`)
if (result !== 1) {
plus.android.requestPermissions(['android.permission.RECORD_AUDIO'], (res) => {
this.log('权限请求结果: ' + JSON.stringify(res))
})
}
// #endif
},
testMP3Record() {
this.testing = true
this.result = '测试中...'
this.log('=== 开始MP3录音测试 ===')
// #ifdef APP-PLUS
try {
// 方法1使用MediaRecorder原生API
this.testNativeMP3()
} catch (e) {
this.log(`错误: ${e.message}`)
this.result = `${e.message}`
this.testing = false
}
// #endif
},
// 使用Android原生MediaRecorder录制MP3
testNativeMP3() {
// #ifdef APP-PLUS
try {
this.log('使用原生MediaRecorder (AAC格式可作为MP3替代)')
const MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
const recorder = new MediaRecorder()
const timestamp = Date.now()
const fileName = 'test_mp3_' + timestamp + '.m4a' // AAC格式
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, (fs) => {
fs.root.getFile(fileName, {create: true}, (fileEntry) => {
const filePath = fileEntry.fullPath
this.log(`文件路径: ${filePath}`)
try {
// 配置录音器AAC编码接近MP3质量
recorder.setAudioSource(MediaRecorder.AudioSource.MIC)
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
recorder.setAudioSamplingRate(16000)
recorder.setAudioEncodingBitRate(96000)
recorder.setOutputFile(filePath)
this.log('准备录音...')
recorder.prepare()
this.log('开始录音...')
recorder.start()
this.result = '✓ 录音中...3秒'
// 3秒后停止
setTimeout(() => {
try {
this.log('停止录音...')
// 先停止
try {
recorder.stop()
} catch (e) {
this.log('停止时出错(可忽略): ' + e.message)
}
// 再释放
try {
recorder.release()
} catch (e) {
this.log('释放时出错(可忽略): ' + e.message)
}
this.log('检查文件...')
// 检查文件
setTimeout(() => {
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
entry.file((file) => {
const sizeKB = (file.size / 1024).toFixed(2)
this.log(`文件大小: ${file.size} bytes (${sizeKB}KB)`)
if (file.size > 1000) {
this.result = `✅ 成功!\n格式: AAC (类MP3)\n大小: ${sizeKB}KB\n\n录音功能正常`
this.log('✅ 测试成功!')
} else if (file.size > 100) {
this.result = `⚠️ 部分成功\n文件较小: ${sizeKB}KB\n可能录音质量差`
this.log('⚠️ 文件较小')
} else {
this.result = `❌ 失败\n文件过小: ${file.size}字节\n\n说明不是格式问题\n是设备录音功能异常`
this.log('❌ 文件过小,录音失败')
this.log('结论: 所有格式都失败,不是格式问题')
}
this.testing = false
}, (err) => {
this.log('获取文件信息失败: ' + JSON.stringify(err))
this.result = '❌ 获取文件信息失败'
this.testing = false
})
}, (err) => {
this.log('文件不存在: ' + JSON.stringify(err))
this.result = '❌ 文件不存在'
this.testing = false
})
}, 500)
} catch (e) {
this.log('停止录音失败: ' + e.message)
this.result = `❌ 停止失败: ${e.message}`
this.testing = false
}
}, 3000)
} catch (e) {
this.log('启动录音失败: ' + e.message)
this.result = `❌ 启动失败: ${e.message}`
this.testing = false
}
}, (err) => {
this.log('创建文件失败: ' + JSON.stringify(err))
this.result = '❌ 创建文件失败'
this.testing = false
})
}, (err) => {
this.log('文件系统错误: ' + JSON.stringify(err))
this.result = '❌ 文件系统错误'
this.testing = false
})
} catch (e) {
this.log('异常: ' + e.message)
this.result = `❌ 异常: ${e.message}`
this.testing = false
}
// #endif
}
}
}
</script>
<style scoped>
.test-page {
min-height: 100vh;
background: #f5f7fa;
padding: 20rpx;
}
.header {
text-align: center;
font-size: 40rpx;
font-weight: bold;
padding: 30rpx;
color: #333;
}
.tip-box {
background: #fff9e6;
border-left: 4rpx solid #ffc107;
padding: 20rpx;
margin-bottom: 20rpx;
border-radius: 8rpx;
font-size: 26rpx;
color: #856404;
}
.card {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
}
.card-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 20rpx;
color: #333;
}
.info {
padding: 15rpx;
background: #f5f5f5;
border-radius: 8rpx;
font-size: 28rpx;
color: #666;
}
.btn-primary {
width: 100%;
padding: 30rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #fff;
border: none;
border-radius: 12rpx;
font-size: 32rpx;
box-shadow: 0 4rpx 15rpx rgba(102, 126, 234, 0.4);
}
button:disabled {
background: #ccc;
color: #999;
box-shadow: none;
}
.result {
margin-top: 20rpx;
padding: 20rpx;
background: #f5f5f5;
border-radius: 8rpx;
font-size: 28rpx;
min-height: 100rpx;
white-space: pre-line;
color: #333;
}
.log-box {
max-height: 400rpx;
overflow-y: auto;
background: #2d2d2d;
border-radius: 8rpx;
padding: 20rpx;
}
.log-line {
display: block;
font-size: 24rpx;
color: #0f0;
font-family: monospace;
line-height: 1.8;
}
</style>