2015-09-12 8 views
6

Der Server speichert die Audiodaten als Base64-Datenzeichenfolge. Der mobile Webclient ruft die Daten ab und spielt das Audio ab.Konvertieren Sie Audiodaten uri Zeichenfolge in Datei

Aber ein Problem in mobilen Chrome in iOS und Android gefunden, dass das Audio mit Daten-URI nicht wiedergeben kann (issue).

Um es funktionieren zu lassen, habe ich mich gefragt, ob es einen Weg auf der Client-Seite gibt, um den Datenstring in eine Audiodatei (wie .m4a) zu konvertieren und den Audio-Quellcode mit der Datei zu verknüpfen?

Antwort

7

Figured aus direkt auf das Web-Audio-API hat die beste Kompatibilität über die mobile Browser in iOS und Android.

function base64ToArrayBuffer(base64) { 
    var binaryString = window.atob(base64); 
    var len = binaryString.length; 
    var bytes = new Uint8Array(len); 
    for (var i = 0; i < len; i++)  { 
    bytes[i] = binaryString.charCodeAt(i); 
    } 
    return bytes.buffer; 
} 

var base64 = '<data string retrieved from server>'; 
var audioContext = new (window.AudioContext || window.webkitAudioContext)(); 
var source = audioContext.createBufferSource(); 
audioContext.decodeAudioData(base64ToArrayBuffer(base64), function(buffer) { 
    source.buffer = buffer; 
    source.connect(audioContext.destination); 
    source.start(0); 
}); 

Es funktioniert in iOS Safari, Chrome und Android Standard-Browser und Chrome.

5

Es gibt eine Möglichkeit, das zu tun, was Sie wollen, es funktioniert auf dem Desktop, aber ich kann nicht garantieren, dass es auf Mobilgeräten funktioniert. Die Idee besteht darin, das dataURI in ArrayBuffer umzuwandeln, daraus einen Blob zu konstruieren und dann eine ObjectURL zu erstellen, die an das Audioelement übergeben wird. Hier ist der Code (Getestet habe ich es in Chrome/Firefox unter Linux und es funktioniert):

<script> 
    var base64audio = "data:audio/ogg;base64,gibberish"; 

    function dataURItoBlob(dataURI) 
    { 
     // Split the input to get the mime-type and the data itself 
     dataURI = dataURI.split(','); 

     // First part contains data:audio/ogg;base64 from which we only need audio/ogg 
     var type = dataURI[ 0 ].split(':')[ 1 ].split(';')[ 0 ]; 

     // Second part is the data itself and we decode it 
     var byteString = atob(dataURI[ 1 ]); 
     var byteStringLen = byteString.length; 

     // Create ArrayBuffer with the byte string and set the length to it 
     var ab = new ArrayBuffer(byteStringLen); 

     // Create a typed array out of the array buffer representing each character from as a 8-bit unsigned integer 
     var intArray = new Uint8Array(ab); 
     for (var i = 0; i < byteStringLen; i++) 
     { 
      intArray[ i ] = byteString.charCodeAt(i); 
     } 

     return new Blob([ intArray ], {type: type}); 
    } 
    document.addEventListener('DOMContentLoaded', function() 
    { 
     // Construct an URL from the Blob. This URL will remain valid until user closes the tab or you revoke it 
     // Make sure at some point (when you don't need the audio anymore) to do URL.revokeObjectURL() with the constructed URL 
     var objectURL = URL.createObjectURL(dataURItoBlob(base64audio)); 

     // Pass the URL to the audio element and load it 
     var audio = document.getElementById('test'); 
     audio.src = objectURL; 
     audio.load(); 
    }); 
</script> 
... 
<audio id="test" controls /> 

Ich hoffe, das hilft;)

+0

Thx, upvoted. Es hat den Chrome in iOS 8 funktioniert. Allerdings funktioniert weder der Chrome- noch der Standard-Browser in Android 4.4.2 –