将音频数据表示为从python到Javascript的numpy数组

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

我有一个TTS(文本到语音)系统,它以numpy数组形式产生音频,其数据类型为np.float32。该系统在后端运行,我想将数据从后端传输到前端,以便在发生特定事件时进行播放。

解决此问题的明显方法是将音频数据作为wav文件写入磁盘,然后将路径传递到要播放的前端。这很好,但出于管理原因,我不想这样做。我只想只将音频数据(numpy数组)传输到前端。

到目前为止,我所做的是:

后端

text = "Hello"
wav, sr = tts_model.synthesize(text)
data = {"snd", wav.tolist()}
flask_response = app.response_class(response=flask.json.dumps(data),
                                    status=200,
                                    mimetype='application/json' )
# then return flask_response

前端

// gets wav from backend
let arrayData = new Float32Array(wav);
let blob = new Blob([ arrayData ]);
let url = URL.createObjectURL(blob);
let snd = new Audio(url);
snd.play()

这是我到目前为止所做的,但是JavaScript引发以下错误:

Uncaught (in promise) DOMException: Failed to load because no supported source was found.

这是我要做的要点。很抱歉,您没有TTS系统,因此无法减少错误,因此这是它生成的audio file,可用于查看我在做什么错。

我尝试过的其他事情:

  • 将音频数据类型分别更改为np.int8np.int16在JavaScript中强制转换的Int8Array()int16Array()
  • 创建blob时尝试了不同的类型,例如{"type": "application/text;charset=utf-8;"}{"type": "audio/ogg; codecs=opus;"}

我已经在这个问题上苦苦挣扎了很长时间,所以请大家帮忙!!

javascript python-3.x numpy flask html5-audio
1个回答
0
投票

您的样品原样无法使用。 (不播放)

但是使用:

  • StarWars3.wav:好。从cs.uic.edu中检索]
  • 您的样本是用PCM16而不是PCM32编码的:确定(检查wav元数据)
  • 烧瓶

from flask import Flask, render_template, json
import base64

app = Flask(__name__)

with open("sample_16.wav", "rb") as binary_file:
    # Read the whole file at once
    data = binary_file.read()
    wav_file = base64.b64encode(data).decode('UTF-8')

@app.route('/wav')
def hello_world():
    data = {"snd": wav_file}
    res = app.response_class(response=json.dumps(data),
        status=200,
        mimetype='application/json')
    return res

@app.route('/')
def stat():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug = True)

js


  <audio controls></audio>
  <script>
    ;(async _ => {
      const res = await fetch('/wav')
      let {snd: b64buf} = await res.json()
      document.querySelector('audio').src="data:audio/wav;base64, "+b64buf;
    })()
  </script>

原始海报编辑

因此,在解决我的问题之前,我最终(使用此解决方案)要做的是:

  • 首先,将数据类型从np.float32更改为np.int16
wav = (wav * np.iinfo(np.int16).max).astype(np.int16)
  • 使用scipy.io.wavfile将numpy数组写入临时的wav文件:
from scipy.io import wavfile
wavfile.write(".tmp.wav", sr, wav)
  • 读取tmp文件中的字节:
# read the bytes
with open(".tmp.wav", "rb") as fin:
    wav = fin.read()
  • 删除临时文件
import os
os.remove(".tmp.wav")
© www.soinside.com 2019 - 2024. All rights reserved.