首页 > 解决方案 > 使用 node.js 流式传输 PCM 音频

问题描述

我想在 nodejs 服务器上生成特定的声音模式,然后使用 express.js 将音频流式传输到 http 客户端。

通过 WebAudio API https://github.com/mohayonao/web-audio-engine/的这种实现,我可以使用扬声器模块直接在服务器上播放一些生成的音频,如示例(https://github. com/mohayonao/web-audio-engine#example )

const Speaker = require("speaker");
const AudioContext = require("web-audio-engine").StreamAudioContext;

function audio(){
  const context = new AudioContext();

  const osc = context.createOscillator();
  osc.type = "sine";
  osc.frequency.setValueAtTime(220, 0);
  osc.frequency.setValueAtTime(440, 1);
  osc.start(0);
  osc.stop(2);
  osc.connect(context.destination);
  osc.onended = () => {
    console.log("finished")
    delete context
  };

  context.pipe(new Speaker());       
  context.resume();
}

audio()

现在我尝试将音频流通过管道传输到 express 的 http 响应:

const express = require("express")
const app = express();

app.get('/', function (req, res) {
  res.set('Content-Type', 'audio/wav');
  audio((context)=>{
    context.pipe(res)
  })
});

app.listen(3000)


const Speaker = require("speaker");
const AudioContext = require("web-audio-engine").StreamAudioContext;

function audio(callback){
  const context = new AudioContext();

  const osc = context.createOscillator();
  osc.type = "sine";
  osc.frequency.setValueAtTime(220, 0);
  osc.frequency.setValueAtTime(440, 1);
  osc.start(0);
  osc.stop(2);
  osc.connect(context.destination);
  osc.onended = () => {
    console.log("finished")
    delete context
  };

  callback(context);
  context.resume();
}

当我在浏览器中打开 localhost:3000 时,现在有一个音频播放器,因此可以识别内容类型,但它没有播放任何内容,只是显示加载动画。2 秒后,当音频流结束时,它会显示一个“损坏的文件”图标。
如何以正确的方式流式传输生成的 PCM 音频(以 wav 格式?)

标签: javascriptnode.jsexpressaudioweb-audio-api

解决方案


您是否尝试过在将其发送到扬声器之前使用 lame 进行解码?例子:

const decoder = require("lame").Decoder;
const Speaker = require("speaker");

context.pipe(decoder()).pipe(new Speaker());

链接到跛脚


推荐阅读