我有一个用例,其中每个音频流块都被发送到服务器进行转录,但除了第一个块之外,其他所有音频块(blob)都不起作用。
所以我做了一个小原型,通过生成 blob url 来查看所有块是否都使用音频元素正常播放
代码示例
import React, { useState, useRef } from 'react'
const RecordAudio: React.FC = () => {
const [isRecording, setIsRecording] = useState(false)
const mediaRecorderRef = useRef<MediaRecorder | null>(null)
const audioChunksRef = useRef<Blob[]>([])
const startRecording = async () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
const mediaRecorder = new MediaRecorder(stream)
mediaRecorderRef.current = mediaRecorder
audioChunksRef.current = []
mediaRecorder.ondataavailable = async (event) => {
if (event.data.size > 0) {
console.log('event.data', event.data)
audioChunksRef.current.push(event.data)
}
}
mediaRecorder.start(5000) // Capture audio in chunks every 500ms
setIsRecording(true)
}
const stopRecording = () => {
if (mediaRecorderRef.current) {
mediaRecorderRef.current.stop()
setIsRecording(false)
// sendAudioChunk(audioChunksRef.current)
}
}
const getAudioBlobUrl = (chunk: Blob) => {
const audioBlob = new Blob([chunk], {
type: 'audio/wav',
})
const blobUrl = URL.createObjectURL(audioBlob)
return blobUrl
}
return (
<div>
<button onClick={isRecording ? stopRecording : startRecording}>
{isRecording ? 'Stop Recording' : 'Start Recording'}
</button>
<div>
{audioChunksRef.current.map((blob) => {
return (
<>
<audio
style={{ marginLeft: '16px' }}
src={getAudioBlobUrl(blob)}
controls
/>
</>
)
})}
</div>
</div>
)
}
export default RecordAudio
但是除了第一个音频块外,其他播放器都没有播放,附上截图供参考
这里有什么问题吗?如何使每个块都流式传输到服务器?
传递给您的
ondataavailable
处理程序的各个数据块并不是独立的。您不能“播放”任何给定的块,而是必须从第一个块开始播放整个数据流。
而且,它们的内容类型(FKA MIME 类型)为
'audio/webm'
(在 Chromium 和 Firefox 世界中)而不是 'audio/wav'
。
评论中提到的问答将为您提供更多详细信息。