J'utilise getUserMedia()
y un mediaRecorder
pour enregistrer de l'audio, que je stocke ensuite sous forme de texte encodé en base64 sur un serveur. Plus tard, il est récupéré sur le serveur, stocké côté client, puis, lorsque l'utilisateur clique sur un bouton de lecture, il est désencodé et lu. La lecture fonctionne correctement sur Chrome, mais sur Safari decodeAudioData
jette un null
err dans la fonction catch. J'ai fait des recherches approfondies, mais je ne vois pas ce qui pourrait provoquer l'exception.
Le code d'enregistrement est le suivant :
navigator.getUserMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
if (navigator.getUserMedia) {
//console.log('getUserMedia supported.');
navigator.getUserMedia (
{ // constraints - only audio needed for this app
audio: true
},
// Success callback
function(stream) {
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = audio.saveRecordedAudio;
});
}
Le code de lecture est le suivant :
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const source = audioCtx.createBufferSource();
const binaryAudioBlob = audio.b64toBlob(b64String);
const reader = new FileReader();
reader.addEventListener("loadend", function() {
const bufferArray = reader.result;
audioCtx.decodeAudioData(bufferArray, (buffer) => {
source.buffer = buffer;
source.connect(audioCtx.destination);
source.start(0);
console.log('started audio from blob');
}, function(e){
console.log("Error with decoding audio data" + e); // e is null
});
});
reader.readAsArrayBuffer(binaryAudioBlob);
où les b64toBlob
est :
b64toBlob: (b64Data, contentType, sliceSize) => {
contentType = contentType || '';
sliceSize = sliceSize || 512;
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
L'audio a été enregistré avec Chrome. Est-il possible que Chrome encode l'audio dans un format que Safari ne peut pas lire ? D'après ce que je sais, le format par défaut est le WAV, donc je pense que Safari peut lire ce format (par opposition à Ogg).
Tous les conseils sont les bienvenus.