Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将表示为numpy数组的音频数据从python发送到Javascript_Javascript_Python 3.x_Numpy_Flask_Html5 Audio - Fatal编程技术网

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

将表示为numpy数组的音频数据从python发送到Javascript,javascript,python-3.x,numpy,flask,html5-audio,Javascript,Python 3.x,Numpy,Flask,Html5 Audio,我有一个TTS(文本到语音)系统,它以numpy数组形式生成音频,其数据类型为np.float32。这个系统在后端运行,我想将数据从后端传输到前端,以便在某个事件发生时播放 这个问题的明显解决方案是将音频数据作为wav文件写入磁盘,然后将路径传递到要播放的前端。这很好,但出于行政原因,我不想这样做。我只想将音频数据(numpy阵列)传输到前端 到目前为止,我所做的工作如下: 后端 text=“你好” wav,sr=tts_模型合成(文本) 数据={“snd”,wav.tolist()} flas

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

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

到目前为止,我所做的工作如下:

后端
text=“你好”
wav,sr=tts_模型合成(文本)
数据={“snd”,wav.tolist()}
flask\u response=app.response\u类(response=flask.json.dumps(数据),
状态=200,
mimetype='application/json')
#然后返回您的响应
前端
//从后端获取wav
设arrayData=new Float32Array(wav);
设blob=newblob([arrayData]);
让url=url.createObjectURL(blob);
让snd=新音频(url);
snd.play()
这就是我到目前为止所做的,但是JavaScript抛出以下错误:

Uncaught (in promise) DOMException: Failed to load because no supported source was found.
这就是我想做的要点。很抱歉,您不能减少错误,因为您没有TTS系统,因此这是由它生成的,您可以使用它来查看我做错了什么

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

我已经在这个问题上挣扎了这么久,所以任何帮助都是值得的

您的原样无法开箱即用。(不玩)

但是:

  • 好的。从
  • 您的样本编码为PCM16而不是PCM32:OK(检查wav元数据)
烧瓶

js

  • 使用
    scipy.io.wavfile
    将numpy数组写入临时wav文件:
  • 从tmp文件中读取字节:
  • 删除临时文件
将wav值数组转换为字节 在合成之后,您可以将wav的numpy数组转换为byte对象,然后通过base64进行编码

导入io
从scipy.io.wavfile导入写入
字节\u wav=字节()
字节io=io.BytesIO(字节波形)
写入(字节io、sr、wav)
wav_bytes=byte_io.read()
音频数据=base64.b64编码(wav字节)。解码('UTF-8')
这可以直接用于创建html音频标记作为源(使用flask):


因此,您只需将
wav
sr
转换为表示原始
.wav
文件的
音频数据。并将其用作flask应用程序的
render_模板的参数。(解决方案不发送)

或者,如果您发送
音频数据
,在接受响应的
.js
文件中,使用
音频数据
构建url(将作为
src
属性放置在html中):

//从响应中获取音频数据
设snd=新音频(“数据:音频/wav;base64,”+音频数据);
snd.play()
因为:

音频(url)
返回值: 新的HtmlLaudioElement对象,配置为用于播放url指定的文件中的音频。新对象的预加载属性设置为自动,并且其src属性设置为指定的url,如果未提供url,则设置为null。如果指定了URL,浏览器将在返回新对象之前开始异步加载媒体资源


从tts中我记得,他们发送了一个base64 buf,你试过了吗?没有,数据是在
numpy
中返回的,所以你知道如何将numpy转换为base64缓冲区。。。我会用谷歌搜索一下,但也许你有一个更快的答案。我用
base64.b64encode(wav)
试过了。在前端,我使用了
让snd=newaudio(“data:base64,+path;)但它不起作用。我尝试了
数据:音频/ogg;base64,“+path;
数据:音频/wav;base64,”+path并且它们也不起作用。
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)

  <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>
wav = (wav * np.iinfo(np.int16).max).astype(np.int16)
from scipy.io import wavfile
wavfile.write(".tmp.wav", sr, wav)
# read the bytes
with open(".tmp.wav", "rb") as fin:
    wav = fin.read()
import os
os.remove(".tmp.wav")