如何使用node.js 和socket.io 通过WebSockets 传输MP3 数据?
我在使用 Node.js 和 socket.io 通过 WebSocket 传输 MP3 数据时遇到问题。一切似乎都正常,但解码音频数据对我来说不公平。
这是我的玩具服务器:
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>
I have problems streaming MP3 data via WebSocket with node.js and socket.io. Everything seems to work but decodeAudioData doesn't play fair with me.
This is my toy server:
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/');
The client receives the data as type string but I want to feed the data to decodeAudioData and it seems it doesn't like strings. The call to decodeAudioData results in the following error message:
Uncaught Error: SYNTAX_ERR: DOM Exception 12
I think decodeAudioData needs the data stored in an ArrayBuffer. Is there a way to convert the data?
This is the client code:
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我自己找到了一种通过 Websockets 传输 MP3 数据的方法。
问题之一是 MP3 数据的块大小。看来 Web Audio API 需要提供有效的 MP3 块才能解码数据。也许并不奇怪。在我的演示应用程序中,我提供了一组 MP3 块文件。
此外,音频质量并不完美。我有一些微妙的故障。我可以通过发送更大的 MP3 数据块来改进这一点,但仍然有微小的裂纹。
编辑:我设法提高了音频质量。看来 Web Audio 方法decodeAudioData 并不是真正设计用于解码 MP3 数据的连续块。
I've found a way to stream MP3 data via Websockets myself.
One problem was the chunk size of the MP3 data. It seems that the Web Audio API needs to be fed with valid MP3 chunks to be able to decode the data. Probably not surprising. In my demo app I provide a set of MP3 chunk files.
Also the quality of the audio is not perfect. I have some subtle glitches. I was able to improve that by sending larger chunks of MP3 data but there are still tiny crackles.
EDIT: I managed to improve the audio quality. It seems the Web Audio method decodeAudioData isn't really designed to decode continuos chunks of MP3 data.
在您的情况下, context.decodeAudioData 需要二进制数据的 ArrayBuffer ,我建议将您的块转换为 base64 字符串,然后转换为 ArrayBuffer 客户端以获得最可预测的结果。 此脚本应该是一个很好的起点客户端对分块数据进行 Base64 解码。
在获取数据(base-64 编码字符串)后立即添加一行
data = Base64Binary.decodeArrayBuffer(data);
即可解决问题...In your case context.decodeAudioData expects an ArrayBuffer of the binary data, I would suggest converting your chunk to a base64 string, then to an ArrayBuffer client-side for the most predictable results. This script should be a good starting point for the client-side decode from base64 of the chunked data.
Adding a line with
data = Base64Binary.decodeArrayBuffer(data);
right after getting your data (base-64 encoded string) would do the trick...看来socket.io仍然不支持二进制传输。所以这里可以使用 websocket.io 。
It seems that socket.io still doesn't support Binary transfer. So websocket.io can be used here.