通过echo框架将字节数组传输到JS blob

问题描述 投票:0回答:1

我正在尝试通过 echo 框架(golang)将谷歌文本到语音 api SynthesizeSpeech.audio_content 的结果传递到前端。

resp, err := client.SynthesizeSpeech(c.ctx, &req)
if err != nil {
    return nil, err
}
c.Blob(http.StatusOK, "audio/mp3", resp.AudioContent)

音频本身正常生成(我尝试将其保存为服务器上的mp3并收听)。但是当我尝试以这种方式获取客户端数据时:

var options = {
  url: "/tts",
  method: "POST",
  contentType: 'application/json',
  responseType: 'audio/mp3',
  data: JSON.stringify(data),
 
  success: function (response) {
     console.log(response.length)
    
     var blob = new Blob([response], { type: 'audio/mp3' });
     console.log(blob.size)
     var blobUrl = URL.createObjectURL(blob);
     var audio = new Audio(blobUrl);

     audio.addEventListener('loadeddata', function() {
        
        audio.play();
     });

     audio.addEventListener('error', function(event) {
        console.error('Audio error:', event.target.error.message);
     });

     audio.load(); 
                          
  },
  error: function (xhr, status, error) {
    console.log(status, error)
    
  }
 }

 $.ajax(options);

我收到错误:prime.js:221 音频错误:DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: 打开上下文失败

同样奇怪的是,在服务器端发送之前的字节数组的大小例如是5664,但是当我测量response.length的大小时,除了blob.size之外,我看到5375是10591。

我还查看了wireshark中的分析,发现客户端的响应非常好。这是:

即使在浏览器应该是5664之前,我们如何才能在wireshark级别看到接收到的数据的大小。

在浏览器调试器中我看到以下数据:

数组似乎被浏览器以某种方式损坏或修改了。大家觉得怎么样?

javascript go blob google-text-to-speech go-echo
1个回答
0
投票

使用 AJAX 将音频数据从 Golang 中的 Echo 服务器传输到前端时遇到的问题似乎与浏览器解释数据的方式有关。您可能会考虑一些潜在的问题和解决方案。

问题1:数据解释和转换 当您从服务器发送二进制数据(如音频)时,必须在服务器和客户端上正确处理它,以确保数据不会损坏或更改。

服务器端(Golang 中的 Echo):确保发送的数据格式正确且 header 设置正确。看来您正在使用 c.Blob(http.StatusOK, "audio/mp3", resp.AudioContent) 正确完成这部分。

客户端(JavaScript):数据需要被视为二进制。问题可能是 jQuery(或浏览器)在解释 AJAX 响应时默认无法正确处理二进制数据。

解决方案:使用 XMLHttpRequest 处理二进制数据 使用本机 XMLHttpRequest 可能更可靠,而不是使用 jQuery 来处理二进制响应,它可以更好地控制响应的处理方式,特别是对于二进制数据。具体方法如下:

   var xhr = new XMLHttpRequest();

    xhr.open('POST', '/tts', true);
  
   xhr.responseType = 'blob'; // Important: Treat the response as a blob

    xhr.onload = function() {
   if (this.status === 200) {
   var blob = new Blob([this.response], { type: 'audio/mp3' });
   var blobUrl = URL.createObjectURL(blob);
   var audio = new Audio(blobUrl);
   audio.play();

   audio.addEventListener('error', function(event) {
    console.error('Audio error:', event.target.error.message);
       });
      }
     };

       xhr.onerror = function() {
       console.error('Request failed');
        };

        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send(JSON.stringify(data));

额外检查 Content-Type:确保客户端请求上的 Content-Type 设置正确。如果您要发送 JSON 数据,则应为“application/json”,但请确保您发送的内容符合服务器端的期望。

错误处理:音频元素中的错误事件处理是一个很好的做法。这可以帮助诊断浏览器是否发现该 blob 在某种程度上不可接受。

控制台日志记录:使用 console.log(blob.size) 进行调试很好。您还可以直接在 xhr.onload 函数中记录 this.response,以查看响应在转换为 blob 之前是否符合您的预期。

通过切换到 XMLHttpRequest 并显式地将 responseType 设置为“blob”,您可以避免 jQuery 处理二进制数据时出现的潜在问题,这可能会导致您观察到的转换或损坏。

© www.soinside.com 2019 - 2024. All rights reserved.