Convert uri audio data to file

The server saves the audio data as a base64 data string. The mobile web client retrieves data and plays audio.

But I found a problem in mobile Chrome on iOS and Android that sound with uri data could not be played ( issue ).

To make it work, I was wondering if there is a way on the client side to convert the data string to an audio file (e.g. .m4a) and associate audio src with the file?

+6
source share
2 answers

Direct use of web audio api has better compatibility in mobile browsers in iOS and 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); }); 

It works in Safari iOS, Chrome and Android browser by default and Chrome.

+7
source

There is a way to do what you want, it works on the desktop, but I can not guarantee that it works on mobile devices. The idea is to convert the dataURI to an ArrayBuffer, build a Blob from it, and then make an ObjectURL with it to go to the audio element. Here is the code (I tested it on Chrome / Firefox under Linux, and it works):

 <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 /> 

I hope this helps;)

+5
source

All Articles