iOS can't play uploaded audio: JS MediaRecorder -> Blob -> Django Server -> AWS s3 -> JS decodeAudioData --> "EncodingError: Decoding Failed"

iOS can't play uploaded audio: JS MediaRecorder -> Blob -> Django Server -> AWS s3 -> JS decodeAudioData --> "EncodingError: Decoding Failed"

回答:不应该设置content/mime类型浏览器端用JS,应该使用原生浏览器mimeType然后转换服务器端(我用PyDub)。

问题: 我正在使用 Javascript MediaRecorder、Django、AWS s3 和 Javascript Web Audio API 来录制音频文件,供用户彼此共享语音笔记。我在网上看到了关于如何记录和上传音频数据以及 Safari/iOS 问题的公开答案,但我认为这可能是一个将其整合起来并解决其中一些问题的话题。

Javascript:

mediaRecorder = new MediaRecorder(stream);

mediaRecorder.onstop = function (e) {
    var blob = new Blob(
        chunks,
        {
            type:"audio/mp3",
        }
    );
    var formdata = new FormData();
    formdata.append('recording', blob)
    var resp = await fetch(url, { // Your POST endpoint
        method: 'POST',
        mode: 'same-origin',
        headers: {
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRFToken': csrf_token,
        },
        body: formdata,
    })
}

姜戈:

for k,file in request.FILES.items():
    sub_path = "recordings/audio.mp3"
    meta_data = {"ContentType":"audio/mp3"}
    s3.upload_fileobj(file, S3_BUCKET_NAME, sub_path,ExtraArgs=meta_data)
    ###then some code to save the s3 URL to my database for future retrieval

Javascript:

var audio_context = new AudioContext();

document.addEventListener("#play-audio","click", function(e) {
    var url = "https://docplat-bucket.s3.eu-west-3.amazonaws.com/recordings/audio.mp3"
    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';
    request.onload = function () {
        audio_context.decodeAudioData(request.response, function (buffer) {
            playSound(buffer)
        });
    }
    request.send();
})

结果: “编码错误:解码失败”

但是请注意,使用 w3 schools 演示 mp3 url 确实可以播放录音: https://docplat-bucket.s3.eu-west-3.amazonaws.com/recordings/t-rex-roar.mp3

规格: PC(用于上传录制):Windows11,Chrome版本98.0.4758.81(正式版)(64位) Django:版本:3.1.7 移动设备(用于播放录音):iPhone X,iOS(版本 14.7.1) 有问题 url:https://docplat-bucket.s3.eu-west-3.amazonaws.com/recordings/audio.mp3 工作 url:https://docplat-bucket.s3.eu-west-3.amazonaws.com/recordings/t-rex-roar.mp3

(这是我的第一个 post 所以如果我没有以理想的方式问这个问题,请原谅我:))

当您上传录制的 Blob 时,您将类型设置为 'audio/mp3'。但是除非您使用自定义库来修补 MediaRecorder,否则记录的 mimeType 将是浏览器最喜欢的内容。

目前在 Firefox 中是 'audio/opus',在 Chrome 中是 'audio/webm'

如果你像这样定义你的 Blob 它应该可以工作。

var blob = new Blob(
    chunks,
    {
        type: mediaRecorder.mimeType
    }
);

您还必须更改服务器端代码以不再使用 'audio/mp3'