【问题标题】:Convert audio data uri string to file将音频数据uri字符串转换为文件
【发布时间】:2015-12-09 02:28:08
【问题描述】:

服务器将音频数据保存为 base64 数据字符串。移动 Web 客户端获取数据并播放音频。

但在 iOS 和 android 的移动 Chrome 中发现无法播放带有数据 uri 的音频的问题 (issue)。

为了让它工作,我想知道客户端是否有办法将数据字符串转换为音频文件(如 .m4a)并将音频 src 链接到文件?

【问题讨论】:

    标签: javascript html audio html5-audio


    【解决方案1】:

    发现直接使用网络音频 api 在 iOS 和 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);
    });
    

    它适用于 iOS safari、Chrome 和 Android 默认浏览器和 Chrome。

    【讨论】:

      【解决方案2】:

      有一种方法可以做你想做的事,它适用于桌面,但我不能保证它适用于移动设备。这个想法是将 dataURI 转换为 ArrayBuffer,从中构造一个 Blob,然后用它创建一个 ObjectURL,以传递给音频元素。这是代码(我在Linux下的Chrome/Firefox中测试过,它可以工作):

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

      希望对你有所帮助;)

      【讨论】:

      • 谢谢,点赞。它使 iOS 8 中的 Chrome 正常工作。但是,Chrome 和 Android 4.4.2 中的默认浏览器都不起作用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 2013-06-25
      • 2011-03-30
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多