节点(套接字)实时音频流/广播
Posted
技术标签:
【中文标题】节点(套接字)实时音频流/广播【英文标题】: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,但也许这是最简单的方法。 topic on MDN 对我来说真正重要的是尽可能地消除延迟。我不在乎质量。到目前为止,我尝试过的所有主要浏览器中的音频/视频 html5 元素本身都会延迟。所以audiocontext和usermedia可能是这样的。但对我来说仍然没有成功。 【参考方案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 做到这一点。有一些工具可供使用,例如SimpleWebRTC 或EasyRTC。对于我已经测试过的内容,视频仍然很麻烦,但音频效果很好。
【讨论】:
以上是关于节点(套接字)实时音频流/广播的主要内容,如果未能解决你的问题,请参考以下文章