如何使用 node.js 和 socket.io 通过 WebSockets 流式传输 MP3 数据?
Posted
技术标签:
【中文标题】如何使用 node.js 和 socket.io 通过 WebSockets 流式传输 MP3 数据?【英文标题】:How to stream MP3 data via WebSockets with node.js and socket.io? 【发布时间】:2012-02-04 07:13:22 【问题描述】:我在使用 node.js 和 socket.io 通过 WebSocket 传输 MP3 数据时遇到问题。一切似乎都正常,但 decodeAudioData 对我不公平。
这是我的玩具服务器:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8081);
function handler (req, res)
res.writeHead(200,
'Content-Type': 'text/html',
);
res.end('Hello, world!');
io.configure('development', function()
io.set('log level', 1);
io.set('transports', [ 'websocket' ]);
);
io.sockets.on('connection', function (socket)
console.log('connection established');
var readStream = fs.createReadStream("test.mp3",
'flags': 'r',
'encoding': 'binary',
'mode': 0666,
'bufferSize': 64 * 1024);
readStream.on('data', function(data)
console.log(typeof data);
console.log('sending chunk of data')
socket.send(data);
);
socket.on('disconnect', function ()
console.log('connection droped');
);
);
console.log('Server running at http://127.0.0.1:8081/');
客户端以字符串类型接收数据,但我想将数据提供给 decodeAudioData,它似乎不喜欢字符串。对 decodeAudioData 的调用导致以下错误消息:
Uncaught Error: SYNTAX_ERR: DOM Exception 12
我认为 decodeAudioData 需要存储在 ArrayBuffer 中的数据。有没有办法转换数据?
这是客户端代码:
<script src="http://127.0.0.1:8081/socket.io/socket.io.js"></script>
<script>
var audioBuffer = null;
var context = null;
window.addEventListener('load', init, false);
function init()
try
context = new webkitAudioContext();
catch(e)
alert('Web Audio API is not supported in this browser');
function decodeHandler(buffer)
console.log(data);
var socket = io.connect('http://127.0.0.1:8081');
socket.on('message', function (data)
// HERE IS THE PROBLEM
context.decodeAudioData(data, decodeHandler, function(e) console.log(e); );
);
</script>
【问题讨论】:
你找到解决这个问题的方法了吗? 我还没有找到使用 socket.io 的解决方案。请参阅我自己的答案以获得没有 socket.io 的解决方案。 Socket.io 1.0 支持二进制,我试过了,但是不行。我也尝试使用 websocket,但错误完全相同。你有一个如何解决这个问题的例子吗?。 @cmarrero01 我当时的解决方案是使用ws而不是Socket.io。但我知道它适用于当前的 Socket.io 版本。在服务器端,我必须明确告诉 ws 发送二进制数据,如ws.send(array, binary: true, mask: true );
不确定我是否将掩码设置为 true 或 false。 HTH
尝试从createReadStream
中删除'encoding': 'binary',
【参考方案1】:
我自己找到了一种通过 Websocket 流式传输 MP3 数据的方法。
一个问题是 MP3 数据的块大小。似乎需要为 Web Audio API 提供有效的 MP3 块才能解码数据。可能并不奇怪。在我的演示应用程序中,我提供了一组 MP3 块文件。
此外,音频的质量并不完美。我有一些微妙的故障。我可以通过发送更大的 MP3 数据块来改善这一点,但仍然有微小的裂纹。
编辑:我设法提高了音频质量。似乎 Web 音频方法 decodeAudioData 并不是真正设计用于解码连续的 MP3 数据块。
【讨论】:
您能发布您的解决方案吗?我也在尝试将 MP3 数据流式传输到 websocket。 请提供您的解决方案。 对于仍在寻找的人,解决方案在他的 Github 页面上:github.com/polaris/audio-demo @digitxp github 项目没有任何与流媒体相关的内容 你是怎么解决这个问题的?我们正在这样做,但音频声音是失真/静态噪音。【参考方案2】:在您的情况下 context.decodeAudioData 需要二进制数据的 ArrayBuffer,我建议将您的块转换为 base64 字符串,然后转换为 ArrayBuffer 客户端以获得最可预测的结果。 This script 应该是从分块数据的 base64 进行客户端解码的良好起点。
在获取数据(base-64 编码的字符串)后立即添加一行 data = Base64Binary.decodeArrayBuffer(data);
就可以了...
【讨论】:
感谢您的回答,但我无法使用脚本。结果 ArrayBuffer 比它应该的长。无论如何,我想避免使用 Base64,因为它是开销。我想我自己找到了解决方案。我很快就会在这里发布。 @Fair Dinkum Thinkum 我想知道您的解决方案。 @fyasar 我的解决方案是使用ws
模块而不是socket.io。当时 socket.io 无法处理二进制数据。不确定是否仍然如此。
@Fair Dinkum Thinkum 你能发布你的解决方案吗?
@FairDinkumThinkum Socket.io 1.0 支持二进制数据,但我仍然无法使其工作。socket.io/blog/introducing-socket-io-1-0/#binary 你可以分享你的解决方案吗?【参考方案3】:
socket.io 似乎还不支持二进制传输。所以这里可以使用websocket.io。
-
https://github.com/LearnBoost/socket.io/issues/511#issuecomment-2370129
https://github.com/LearnBoost/socket.io/issues/680#issuecomment-3083490
【讨论】:
以上是关于如何使用 node.js 和 socket.io 通过 WebSockets 流式传输 MP3 数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何实现 Laravel、node.js、socket.io 和 redis 以使用数据库创建实时聊天/通知
如何使用 node.js 和 socket.io 通过 WebSockets 流式传输 MP3 数据?
如何使用 node.js 和 socket.io 将文件从 iPhone 发送到另一台 iPhone?
如何使用 Socket.io 和 Node.js 开发大型聊天应用程序 [关闭]