未捕获(承诺)DOMException:无法将音频数据从 pyAudio 解码到 JavaScript

Uncaught (in promise) DOMException: Unable to decode audio data from pyAudio to JavaScript

我有一个 python 应用程序可以从麦克风获取音频,将其发送到服务器,服务器再将其发送到 javascript 应用程序。

我已经检查过 python 应用程序发送的数据与 javascript 应用程序收到的数据相同。

在控制台中,在 javascript 应用程序中,出现以下消息:Uncaught (in promise) DOMException: Unable to decode audio data

我认为问题是因为发送的数据是原始数据,没有'.wav'headers,但我也尝试使用wave将数据写入文件并读取它,同样的错误出现。

使用 websockets 将数据作为二进制数据发送/接收。

Python代码:

# self data in init
self.sampleRate = 44100
self.duration = 1 / 30
self.channels = 2
self.chunk = 1024
self.format = pyaudio.paInt16

# code
pyAudio = pyaudio.PyAudio()
frames = []
stream = pyAudio.open(
    format=self.format,
    channels=self.channels,
    rate=self.sampleRate,
    input=True,
    output=True,
    frames_per_buffer=self.chunk
)

data = stream.read(int(44100 / self.chunk * self.duration))
frames.append(data)
recording = data

stream.stop_stream()
stream.close()
pyAudio.terminate()
  1. 录音数据是发送到javascript应用程序的数据。
  2. 我知道我应该记录多帧,但我这样做是因为它更容易测试。

JavaScript代码:

function playByteArray(byteArray) {
    var arrayBuffer = new ArrayBuffer(byteArray.length);
    var bufferView = new Uint8Array(arrayBuffer);
    for (i = 0; i < byteArray.length; i++) {
      bufferView[i] = byteArray[i];
    }
    context.decodeAudioData(arrayBuffer, function(buffer) {
        buf = buffer;
        play();
    });
}

function play() {
    var source = context.createBufferSource();
    source.buffer = buf;
    source.connect(context.destination);
    source.start(0);
}

我也用 sounddevice python 模块试过了,但我得到了同样的错误(正常方法,我无法让 Stream 回调方法工作)。

谢谢。

我解决了它,将 playByteArray 更改为以下函数:

function playByteArray(byteArray) {
    audio = new Audio();
    var blob = new Blob([byteArray], { type: 'audio/wav; codecs=0' });
    var url = window.URL.createObjectURL(blob);     
    audio.src = url;
    audio.oncanplaythrough = (event) => {
        var playedPromise = audio.play();
        if (playedPromise) {
            playedPromise.catch((e) => {
                console.log(e);
                if (e.name === 'NotAllowedError' || e.name === 'NotSupportedError') {
                    console.log(e.name);
                }
            }).then(() => {

            });
        }
    };
}