Javascript 二进制字符串转 MP3

标签 javascript angularjs server mp3 multipart

我正在浏览器中开发一个项目,该项目从服务器接收多部分响应。

响应的第一部分是一些 JSON 元数据

响应的第二部分是一个二进制 MP3 文件。

我需要一种方法从多部分响应中提取 MP3 文件并在 HTML 5 音频元素中播放它。

有人遇到过这种情况或类似的情况吗?

最佳答案

我最终解决了我的问题。我正在向将来需要这样做的任何人提供该问题和我的解决方案。

背景信息:

当我发出这个 ajax 请求时,我使用的是 AngularJS,但是 jquery ajax 和常规 xhr 的想法是相同的。

代码:

//creating a form object and assigning everything
//to it is so that XHR can automatically
//generate proper multipart formatting
var form  = new FormData();
var data = {};

data['messageHeader'] = {};

var jsonData = JSON.stringify(data);
var jsonBlob = new Blob([jsonData],{type: "application/json"});

//assign json metadata blob and audio blob to the form
form.append("request", jsonData);
form.append("audio",response); //Response is the audio blob

//make the post request
//Notes:
//content-type set to undefined so angular can auto assign type
//transformRequest: angular.identity allows for angular to create multipart
//response: arraybuffer so untouched binary data can be received
$http({method:"POST",
  url: endpoint + path,
  headers: {
    'Authorization': 'Bearer ' + $cookies.get('token'),
    'Content-Type': undefined
  },
  transformRequest: angular.identity,
  data: form,
  responseType: "arraybuffer"
  })
  .success(function(data){
    //data: ArrayBuffer of multipart response
    //toss ArrayBuffer into Uint8Array
    //lets you iterate over the bytes
    var audioArray = new Uint8Array(data);
  
    //toss a UTF-8 version of the response into
    //a variable. Used to extract metadata
    var holder = "";
    for (var i = 0; i < audioArray.length; i++){
      holder += String.fromCharCode(audioArray[i]);
    }

    //get the boundary from the string. Eg contents of first line
    var boundary = holder.substr(0, holder.indexOf("\n"));
    //break response into array at each boundary string
    var temp = holder.split(boundary);
    var parts = [];
    //loop through array to remove empty parts
    for (var i = 0; i < temp.length; i++){
      if (temp[i] != ""){
          parts.push(temp[i]);
        }
    }

    //PARSE FIRST PART
    //get index of first squiggly, indicator of start of JSON
    var jsonStart = parts[0].indexOf('{');
    //string to JSON on { index to end of part substring
    var JSONResponse = JSON.parse(parts[0].substring(jsonStart));

    //PARSE SECOND PART
    var audioStart = holder.indexOf('mpeg') + 8;
    //get an ArrayBuffer from UInt8Buffer from the audio
    //start point to the end of the array
    var audio = audioArray.buffer.slice(audioStart);

    //hand off audio to AudioContext for automatic decoding
    audio_context.decodeAudioData(audio, function(buffer) {
      var audioBuffer = buffer;
      //create a sound source
      var source = audio_context.createBufferSource();
      //attach audioBuffer to sound source
      source.buffer = audioBuffer;
      //wire source to speakers
      source.connect(audio_context.destination);
       //on audio completion, re-enable mic button
      source.onended = function() {
        console.log("ended");
        $scope.$apply(function(){
          $scope.playing = false;
        });		
      }
      //start playing audio
      source.start(0);

      }, function (){
        //callback for when there is an error
        console.log("error decoding audio");
      });
    })

概述:

您需要接受纯二进制数据(ArrayBuffer)形式的响应。大多数库都会将其作为字符串提供给您,这对于正常请求来说很酷,但对于二进制数据来说却很糟糕。

然后您逐步浏览数据以找到多部分边界。

然后你们在边界处 split 。

获取已知的边界索引是二进制数据

然后从 ArrayBuffer 中检索原始二进制文件。

就我而言,我将该二进制文件发送到扬声器中,但是如果它是图像,您可以构建一个 blob,从 FileReader 获取一个 url,然后将其设置为图像源。

关于Javascript 二进制字符串转 MP3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31574033/

相关文章:

javascript - 如何更改 OpenLayers 5.3 的图 block 语言

javascript - php 的 $_POST 中的 angularJs POST 数据

javascript - 如何在angularjs中使用带有嵌套ng-repeat的复选框

html - 当人们说静态文件是 .html、.js 等时,他们是不是犯了一个错误?

c++ - 多线程 C++11 应用程序中的同步

javascript - 在 Leaflet.js 或非 Google map 库中使用 Fusion Tables 磁贴?

javascript - 每个 tr 的第一个 td 值

javascript - 使用 expo : ‘react-navigation does not exist in the haste module map’ react native

javascript - 如何使用混合 webapp(MPA 和 SPA 结合)

java - Keycloak 重定向 localhost 而不是重定向远程 url