diff --git a/apps/web-antd/src/views/business/chat/composables/useRecording.ts b/apps/web-antd/src/views/business/chat/composables/useRecording.ts index 0e0ec4ae..7b7bfa5b 100644 --- a/apps/web-antd/src/views/business/chat/composables/useRecording.ts +++ b/apps/web-antd/src/views/business/chat/composables/useRecording.ts @@ -1,12 +1,13 @@ import { ref } from 'vue'; import { message } from 'ant-design-vue'; -import {uploadChatFile} from "#/api/core/upload"; + +import { uploadChatFile } from '#/api/core/upload'; export function useRecording() { const isRecording = ref(false); - const mediaRecorder = ref(null); - const audioChunks = ref([]); + const mediaRecorder = ref(null); + const audioChunks = ref([]); const recordingStartTime = ref(0); const startRecording = () => { @@ -19,34 +20,64 @@ export function useRecording() { audioChunks.value = []; recordingStartTime.value = Date.now(); - mediaRecorder.value = new MediaRecorder(stream); + // 尝试获取支持的MIME类型 + const options = { mimeType: 'audio/webm' }; + mediaRecorder.value = new MediaRecorder(stream, options); mediaRecorder.value.ondataavailable = (event) => { audioChunks.value.push(event.data); }; mediaRecorder.value.onstop = () => { - const audioBlob = new Blob(audioChunks.value, { type: 'audio/wav' }); + // 1. 获取实际录制的MIME类型 + const mimeType = mediaRecorder.value?.mimeType || 'audio/webm'; + + // 2. 根据MIME类型确定文件扩展名 + const extension = mimeType.includes('webm') + ? '.webm' + : mimeType.includes('mp4') + ? '.mp4' + : mimeType.includes('ogg') + ? '.ogg' + : '.wav'; + + // 3. 创建正确类型的Blob + const audioBlob = new Blob(audioChunks.value, { type: mimeType }); + + // 4. 创建带扩展名的文件名 + const fileName = `recording_${Date.now()}${extension}`; const duration = Math.floor( (Date.now() - recordingStartTime.value) / 1000, ); - uploadChatFile({ - file: audioBlob, - }).then((res) => { - // 触发音频消息发送事件 - const event = new CustomEvent('audioRecorded', { - detail: { - url: res.url, - duration, - blob: audioBlob, - }, - }); - window.dispatchEvent(event); + // 5. 创建File对象(包含文件名和类型) + const audioFile = new File([audioBlob], fileName, { + type: mimeType, + lastModified: Date.now(), }); - // 停止所有音频轨道 - stream.getTracks().forEach((track) => track.stop()); + uploadChatFile({ + file: audioFile, // 使用File对象替代Blob + }) + .then((res) => { + // 触发音频消息发送事件 + const event = new CustomEvent('audioRecorded', { + detail: { + url: res.url, + duration, + blob: audioBlob, + }, + }); + window.dispatchEvent(event); + }) + .catch((error) => { + console.error('上传录音失败:', error); + message.error('录音上传失败'); + }) + .finally(() => { + // 确保在任何情况下都停止音频轨道 + stream.getTracks().forEach((track) => track.stop()); + }); }; mediaRecorder.value.start();