使用节点同时从 soundcloud 源流式传输音频
Stream audio simultaneously from soundcloud source with node
我正在使用来自节点服务器的 Soundcloud api。我想将一个音轨同时流式传输给多个用户。
我试过类似的方法(使用这个问题 Streaming audio from a Node.js server to HTML5 <audio> tag 上的代码)但它不起作用。知道我该怎么做吗?
var radio = require("radio-stream");
var http = require('http');
var url = "http://api.soundcloud.com/tracks/79031167/stream?client_id=db10c5086fe237d1718f7a5184f33b51";
var stream = radio.createReadStream(url);
var clients = [];
stream.on("connect", function() {
console.error("Radio Stream connected!");
console.error(stream.headers);
});
stream.on("data", function (chunk) {
if (clients.length > 0){
for (client in clients){
clients[client].write(chunk);
};
}
});
stream.on("metadata", function(title) {
console.error(title);
});
var server = http.createServer(function(req, res){
res.writeHead(200,{
"Content-Type": "audio/mpeg",
'Transfer-Encoding': 'chunked'
});
clients.push(res);
console.log('Client connected; streaming');
});
server.listen("8000", "0.0.0.0");
console.log('Server running at http://127.0.0.1:8000');
有几个问题
关注重定向
您使用的 radio-stream
模块已经 4 年没有更新了。那是 Node.js API 时代的永恒。我建议 不要 使用它,因为毫无疑问 Node.js 当前和未来版本存在兼容性问题。至少,现在使用新流 API.
有更好的方法来处理这个问题
无论如何,该模块不遵循 HTTP 重定向。 SoundCloud API 正在将您重定向到实际的媒体文件。
此外,radio-stream
模块是为解复用 SHOUTcast/Icecast 风格的元数据而构建的,而不是 MP3 ID3 数据。帮不了你。
您只需要一个简单的 http.get()
。然后您可以自己跟随重定向,或使用 request
包。更多信息:
分块编码
许多流媒体客户端无法处理分块编码。 Node.js(正确)在您有流式输出时添加它。不过,为了我们的目的,让我们禁用它。
res.useChunkedEncodingByDefault = false;
构建一致的流
理论上,您可以在 MPEG 流之后附加 MPEG 流,一切都可以正常工作。实际上,这是行不通的。 ID3 标签会破坏流。一个文件的采样率可能与另一个文件不同,大多数软件将无法即时将硬件切换到新的采样率。基本上,您无法可靠地完成您想要做的事情。
您唯一能做的就是通过播放这些音频文件重新编码整个流,并从另一端获得稳定的流。这为您提供了额外的好处,您可以处理其他编解码器和格式,而不仅仅是 MP3。
要处理许多编解码器问题,您可以使用 FFmpeg。但是,您将需要一种方法将这些文件播放到 FFmpeg 进行编码。
速率限制
您必须以播放速率传输音频。 (你可以发送一个初始缓冲区让客户端快速启动,但你不能尽可能快地向它们发送数据。)如果你不这样做,你将 运行 服务器内存不足很快,因为客户端会将其 TCP window 大小降低到零并保持在那里,直到音频赶上足以缓冲更多数据。由于您没有使用 pipe
,您的流处于流动模式并且将无限期地在服务器上缓冲。现在,这在某些方面实际上是一件好事,因为这可以防止一个慢客户端拖慢其他客户端的速度。这是一件坏事,因为你的代码,你正在尽可能快地流式传输,而不是播放速度。
如果您将音频播放到另一个编码器,请使用 RTC 几秒钟作为时钟。它不一定是完美的,这就是客户端缓冲区的用途。如果您正在播放音频设备,它当然有自己的时钟,将被使用。
你实际上应该做什么
您无意中遇到了一个巨大的项目。我强烈建议您使用 Liquidsoap instead. There are ways you can control it from Node.js. From there, use a server like Icecast 进行直播。
我正在使用来自节点服务器的 Soundcloud api。我想将一个音轨同时流式传输给多个用户。
我试过类似的方法(使用这个问题 Streaming audio from a Node.js server to HTML5 <audio> tag 上的代码)但它不起作用。知道我该怎么做吗?
var radio = require("radio-stream");
var http = require('http');
var url = "http://api.soundcloud.com/tracks/79031167/stream?client_id=db10c5086fe237d1718f7a5184f33b51";
var stream = radio.createReadStream(url);
var clients = [];
stream.on("connect", function() {
console.error("Radio Stream connected!");
console.error(stream.headers);
});
stream.on("data", function (chunk) {
if (clients.length > 0){
for (client in clients){
clients[client].write(chunk);
};
}
});
stream.on("metadata", function(title) {
console.error(title);
});
var server = http.createServer(function(req, res){
res.writeHead(200,{
"Content-Type": "audio/mpeg",
'Transfer-Encoding': 'chunked'
});
clients.push(res);
console.log('Client connected; streaming');
});
server.listen("8000", "0.0.0.0");
console.log('Server running at http://127.0.0.1:8000');
有几个问题
关注重定向
您使用的 radio-stream
模块已经 4 年没有更新了。那是 Node.js API 时代的永恒。我建议 不要 使用它,因为毫无疑问 Node.js 当前和未来版本存在兼容性问题。至少,现在使用新流 API.
无论如何,该模块不遵循 HTTP 重定向。 SoundCloud API 正在将您重定向到实际的媒体文件。
此外,radio-stream
模块是为解复用 SHOUTcast/Icecast 风格的元数据而构建的,而不是 MP3 ID3 数据。帮不了你。
您只需要一个简单的 http.get()
。然后您可以自己跟随重定向,或使用 request
包。更多信息:
分块编码
许多流媒体客户端无法处理分块编码。 Node.js(正确)在您有流式输出时添加它。不过,为了我们的目的,让我们禁用它。
res.useChunkedEncodingByDefault = false;
构建一致的流
理论上,您可以在 MPEG 流之后附加 MPEG 流,一切都可以正常工作。实际上,这是行不通的。 ID3 标签会破坏流。一个文件的采样率可能与另一个文件不同,大多数软件将无法即时将硬件切换到新的采样率。基本上,您无法可靠地完成您想要做的事情。
您唯一能做的就是通过播放这些音频文件重新编码整个流,并从另一端获得稳定的流。这为您提供了额外的好处,您可以处理其他编解码器和格式,而不仅仅是 MP3。
要处理许多编解码器问题,您可以使用 FFmpeg。但是,您将需要一种方法将这些文件播放到 FFmpeg 进行编码。
速率限制
您必须以播放速率传输音频。 (你可以发送一个初始缓冲区让客户端快速启动,但你不能尽可能快地向它们发送数据。)如果你不这样做,你将 运行 服务器内存不足很快,因为客户端会将其 TCP window 大小降低到零并保持在那里,直到音频赶上足以缓冲更多数据。由于您没有使用 pipe
,您的流处于流动模式并且将无限期地在服务器上缓冲。现在,这在某些方面实际上是一件好事,因为这可以防止一个慢客户端拖慢其他客户端的速度。这是一件坏事,因为你的代码,你正在尽可能快地流式传输,而不是播放速度。
如果您将音频播放到另一个编码器,请使用 RTC 几秒钟作为时钟。它不一定是完美的,这就是客户端缓冲区的用途。如果您正在播放音频设备,它当然有自己的时钟,将被使用。
你实际上应该做什么
您无意中遇到了一个巨大的项目。我强烈建议您使用 Liquidsoap instead. There are ways you can control it from Node.js. From there, use a server like Icecast 进行直播。