IOS не может воспроизвести загруженное аудио: JS MediaRecorder -> Blob -> Django Server -> AWS s3 -> JS decodeAudioData --> "EncodingError: Decoding Failed"

Я использую 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,
    })
}

Django:

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();
})

Результаты: "EncodingError: Decoding Failed"

Обратите внимание, что при использовании w3 schools demo mp3 url запись воспроизводится: https://docplat-bucket.s3.eu-west-3.amazonaws.com/recordings/t-rex-roar.mp3

Спецификации: ПК (используется для загрузки перекодировки): Windows 11, Chrome Version 98.0.4758.81 (Official Build) (64-bit). 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

(Это мое первое сообщение, поэтому прошу простить меня, если я задал этот вопрос не самым лучшим образом :) )

Когда вы загружаете записанный Blob, вы устанавливаете тип 'audio/mp3'. Но если вы не используете пользовательскую библиотеку, которая исправляет MediaRecorder, mimeType запись будет такой, какая больше нравится браузеру.

На данный момент это 'audio/opus' в Firefox и 'audio/webm' в Chrome.

Если вы определите свой Blob таким образом, он должен работать.

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

Вам также придется изменить код на стороне сервера, чтобы больше не использовать 'audio/mp3'.

Вернуться на верх