【问题标题】:node (socket) live audio stream / broadcast节点(套接字)实时音频流/广播
【发布时间】:2014-06-17 06:35:40
【问题描述】:

请问,是否有任何简单的方法可以通过 NODE.js 和可能的 SOCKET.IO 将媒体文件(ogg、mp3、spx..)从服务器流式传输(广播)到客户端(浏览器)?

我必须在服务器端录制音频输入,然后才能为许多客户端实时播放。 我一直在搞乱 binary.js 或 socket.io 流,但无法正确处理。

我尝试使用 speex、vorbis 或 lame 对音频输入进行编码,然后通过 FS 将其加载到客户端,但我没有成功。还是我必须捕获 PCM 然后在浏览器中解码?

对此的任何建议,我都没有找到任何帮助过我的建议。

非常感谢您提供的任何提示、链接和想法。

【问题讨论】:

  • 我对实时音频流也很感兴趣。我读的越多,节点流、背压、缓冲和所有你需要照顾的东西,我就越不知道如何解决这个问题。有一个nice post。我试图避免使用 SHOUTcast/Icecast,但也许这是最简单的方法。
  • 对我来说真正重要的是尽可能地消除延迟。我不在乎质量。到目前为止,我尝试过的所有主要浏览器中的音频/视频 html5 元素本身都会延迟。所以audiocontext和usermedia可能是这样的。但对我来说仍然没有成功。

标签: node.js sockets audio media


【解决方案1】:

您需要寻找适用于 Streams 的包,然后根据需要将流通过管道传输到输出。使用 Express 或仅使用内置 HTTP,您可以轻松完成此操作。这是一个围绕 osx-audio 构建的示例,它提供 PCM 流,lame 可以将流编码为 mp3,以及 Express:

var Webcast = function(options) {

  var lame = require('lame');
  var audio = require('osx-audio');
  var fs = require('fs');

  // create the Encoder instance
  var encoder = new lame.Encoder({
    // input
    channels: 2,        // 2 channels (left and right)
    bitDepth: 16,       // 16-bit samples
    sampleRate: 44100,  // 44,100 Hz sample rate

    // output
    bitRate: options.bitrate,
    outSampleRate: options.samplerate,
    mode: (options.mono ? lame.MONO : lame.STEREO) // STEREO (default), JOINTSTEREO, DUALCHANNEL or MONO
  });

  var input = new audio.Input();
  input.pipe(encoder);

  // set up an express app
  var express = require('express')
  var app = express()

  app.get('/stream.mp3', function (req, res) {
    res.set({
      'Content-Type': 'audio/mpeg3',
      'Transfer-Encoding': 'chunked'
    });
    encoder.pipe(res);
  });

  var server = app.listen(options.port);
}

module.exports = Webcast;

如何获取输入流可能是最有趣的部分,但这取决于您的实现。流行的 request 包也是围绕 Streams 构建的,所以它可能只是一个 HTTP 请求!

【讨论】:

  • 你有和 socket.io 的例子吗?你在 http: app.get('/stream.mp3', function (req, res) { res.set({ ' Content-Type': 'audio/mpeg3', 'Transfer-Encoding': 'chunked' }); encoder.pipe(res); });和 socket.io ?像这样的东西? socket.on('audio',function(data){ encoder.pipie(data); //发送或发送到客户端在哪里?});
  • 还没有尝试过这个解决方案,但看起来很有趣。我会让你知道这是怎么回事。
  • 谁能指出一些可以在 Flask/Flask-SocketIO 中实现这一目标的资源?
【解决方案2】:

在网络浏览器上,您有the HTML5 video element and the audio element。两者都有来源。 Each web browser supports different codecs natively. 因此,如果您尝试流式传输 mp3,请注意这一点。

你不需要socket.io,你只需要HTTP。您的应用程序正在读取一个文件 music.ogg,并且对于它读取的每个块,它将通过 http 服务器发送它。在文件传输之前,它将是一个保持打开状态的 HTTP 请求。

这是您的 html 的外观:

<audio src="http://example.com/music.ogg"></audio>

你的 nodejs 代码将是这样的(还没有测试过):

var http = require('http');
var fs = require('fs');

http.on('request', function(request, response) {
    var inputStream = fs.open('/path/to/music_file.ogg');
    inputStream.pipe(response);
})

我只在inputStream 上使用ReadableStream.pipe 方法以及上述代码的http 和fs 模块。如果您想对音频文件进行转码(例如,从 mp3 转码为 ogg),您需要找到一个模块来执行此操作,然后将文件中的数据通过管道传输到转码器,然后传输到 response

// using some magical transcoder
inputStream.pipe(transcoder).pipe(response);

该方法将在完成写入时在流上调用end,以便在文件完成读取(和转码)后立即完成 HTTP 请求。

【讨论】:

  • 非常感谢您的回答,但我真正的意思是让“实时流”同步到所有客户端,所以您认为有什么方法可以例如将音频源切到零件(或使用记录的 pcms 作为来源)并将这些零件提供给客户?毕竟,WebRTC 方式取得了非常好的结果,但对于连接的更多客户端来说是不可持续的。
  • 您需要使用createReadStream 而不是open 来管道。
【解决方案3】:

您可以使用节点和 RTC 做到这一点。有一些工具可供使用,例如SimpleWebRTCEasyRTC。对于我已经测试过的内容,视频仍然很麻烦,但音频效果很好。

【讨论】:

    猜你喜欢
    • 2013-01-08
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 2018-08-25
    • 2011-10-20
    • 2020-09-23
    相关资源
    最近更新 更多