保存录制的音频 blob [JS]

Posted

技术标签:

【中文标题】保存录制的音频 blob [JS]【英文标题】:Saving recorded audio blob [JS] 【发布时间】:2021-08-09 23:51:14 【问题描述】:

我正在通过麦克风录制用户语音并将其保存为 Google Drive 上的文件(使用 GDrive API)。当我在浏览器中收听时,我在执行此操作并收听上传到驱动器的音频时没有任何问题。但是,当我从 GDrive 下载文件时,它会在没有扩展名的情况下下载(有点像 textedit 文档)。

我尝试修改下载文件的扩展名并播放它,但它不能在 QuickTime、VLC 甚至 Audacity 等上播放。

这是我录制音频的方式

function recordVisitorMsg() 
    navigator.mediaDevices.getUserMedia(
            audio: true
        )
        .then(stream => 
            const mediaRecorder = new MediaRecorder(stream);
            mediaRecorder = new MediaRecorder(stream);
            mediaRecorder.start();
            const audioChunks = [];
            mediaRecorder.addEventListener("dataavailable", event => 
                audioChunks.push(event.data);
            );

            mediaRecorder.addEventListener("stop", () => 
                audioBlob = new Blob(audioChunks, 
                    'type': 'audio/mp3'
                );
                const audioUrl = URL.createObjectURL(audioBlob);

                const audio = new Audio(audioUrl);
                audio = new Audio(audioUrl);
                audio.play();
            );

            setTimeout(() => 
                mediaRecorder.stop();
            , 3000);
        );

这是我上传到云端硬盘的方式。

form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], 
        type: 'application/json'
    ));


    form.append('audio-file', audioBlob);

let refresh_request = 
            body: post_body,
            method: "POST",
            headers: new Headers(
                'Content-Type': 'application/x-www-form-urlencoded'
            )
        

        // trimmed the secret keys code for length, not necessary here 
        fetch(refresh_url, refresh_request).then(response => 
            return (response.json());
        ).then(response_json => 
            console.log(response_json);
            var xhr = new XMLHttpRequest();
            xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id');
            xhr.setRequestHeader('Authorization', 'Bearer ' + response_json.access_token);
            xhr.responseType = 'json';
            xhr.onload = () => 
                console.log(xhr.response.id); // Retrieve uploaded file ID.
            ;
            xhr.send(form);
        );

我是新手,所以如果在此过程中出现一些小问题,请原谅。同样,当我在浏览器的 GDrive 中播放它时,它也能正常播放。问题是当我下载时 - 它没有扩展名。手动扩展/修改也无助于在任何播放器中播放文件。请帮忙,谢谢!

【问题讨论】:

【参考方案1】:

我不确定这是否能完全解决问题,但我认为在创建Blob 时设置正确的mimeType 将是一个好的开始。不幸的是,没有允许使用MediaRecorder 录制 MP3 的浏览器。例如,Chrome 中的默认 mimeType'audio/webm'。您可以在创建Blob 时从MediaRecorder 中读取mimeType 来设置它。

audioBlob = new Blob(
    audioChunks,
     type: mediaRecorder.mimeType 
);

创建File 而不是Blob 也可能会有所帮助。它允许您设置文件名,从而设置扩展名。一种快速而肮脏的方法是像这样解析mimeType

audioBlob = new File(
    audioChunks,
    `my-file.$mediaRecorder.mimeType.match(/\/([\w\d]+);?/)[1]`,
     type: mediaRecorder.mimeType 
);

在 Chrome 中,这应该等于以下硬编码版本。

audioBlob = new File(
    audioChunks,
    'my-file.webm',
     type: 'audio/webm' 
);

【讨论】:

以上是关于保存录制的音频 blob [JS]的主要内容,如果未能解决你的问题,请参考以下文章

如何将 blob URL 转换为音频文件并将其保存到服务器

合并两个音频 blob 记录

如何将base64音频数据解码为wav格式

HTML5 音频 - 录制保存文件正常,但通过音频控制播放时没有声音

保存多个录制音频文件并获取所有录制音频

如何保存录制的音频iOS?