html - 在连续流上解码音频数据失败并出现空错误

标签 html node.js google-chrome ffmpeg web-audio-api

在我的以下代码中,ffmpeg 正在对输入流进行转码,并成功将 block 发送到客户端。在客户端,客户端正在解码来自 socket.io 的 Base64 响应,并将响应转换为数组缓冲区。从那时起,decodeAudioData 无法处理数组缓冲区并返回 null 错误。有谁知道为什么解码音频数据不起作用?

./webaudio_svr.js:

var express = require('/usr/local/lib/node_modules/express');
var http = require('http');
var spawn = require('child_process').spawn;
var util = require('util');
var fs = require('fs');

var app       = express();
var webServer = http.createServer(app);
var audServer = http.createServer(app);
var io        = require('/usr/local/lib/node_modules/socket.io').listen(webServer, {log: false, });

app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res){
    res.send(
    "<script src='/socket.io/socket.io.js'></script>\n"+
    "<script>var socket=io.connect('http://127.0.0.1:3000');</script>\n"+
    "<script src='/webaudio_cli.js'></script>"
    );
});
webServer.listen(3000);

var inputStream = spawn('/usr/bin/wget', ['-O','-','http://nprdmp.ic.llnwd.net/stream/nprdmp_live01_mp3']);

var ffmpeg = spawn('ffmpeg', [
    '-i', 'pipe:0', // Input on stdin
    '-ar', '44100', // Sampling rate
    '-ac', 2, // Stereo
    '-f', 'mp3',
    'pipe:1' // Output on stdout
]);

io.sockets.on('connection', function(webSocket) {
    var disconnect = '0';

    if (disconnect == '0') {
        inputStream.stdout.pipe(ffmpeg.stdin);
        ffmpeg.stdout.on('data', function(data) {
            var data64 = data.toString('base64');
            webSocket.emit('stream',data64);
        });
    }

    webSocket.on('disconnect', function() {
        disconnect=1;
    });
});

./public/webaudio_cli.js:

function str2ab(str) {
    var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
    var bufView = new Uint16Array(buf);
    for (var i=0, strLen=str.length; i<strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var source = context.createBufferSource();

socket.on('stream', function(data) {
        var data=str2ab(atob(data));
        context.decodeAudioData(data, function(buffer) {
            source.connect(context.destination);
            source.buffer = buffer;
            source.start(0);
        }, function(err) {
            console.log("err(decodeAudioData): "+err);
        });
});

最佳答案

如果您阅读了原始帖子的注释部分,您会发现我最终使用了binaryjs,但在Kevin的帮助下,我能够使用socket.io来使用它。请注意,这仍然是播放断断续续的一个巨大问题。如果有人可以提供一些帮助来清理音频,请这样做。除非音频按预期工作,否则这个解决方案实际上毫无意义,所以我需要弄清楚这一点。

该问题与浏览器如何编码/解码您的 Base64 字符串有关。在此更改之前,您必须提供 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding 中您自己的函数。 .

webaudio_svr.js:

var express = require('/usr/local/lib/node_modules/express');
var http = require('http');
var spawn = require('child_process').spawn;
var util = require('util');
var fs = require('fs');

var app       = express();
var webServer = http.createServer(app);
var io        = require('/usr/local/lib/node_modules/socket.io').listen(webServer, {log: false, });

app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res){
    res.send(
    "<script src='/socket.io/socket.io.js'></script>\n"+
    "<script>var socket=io.connect('http://127.0.0.1:3000');</script>\n"+
    "<script src='/base64.js'></script>\n"+
    "<script src='/webaudio_cli.js'></script>"
    );
});
webServer.listen(3000);

var inputStream = spawn('/usr/bin/wget', ['-O','-','http://nprdmp.ic.llnwd.net/stream/nprdmp_live01_mp3']);

var ffmpeg = spawn('ffmpeg', [
    '-i', 'pipe:0', // Input on stdin
    '-ar', '44100', // Sampling rate
    '-ac', 2, // Stereo
    '-f', 'mp3',
    'pipe:1' // Output on stdout
]);

io.sockets.on('connection', function(webSocket) {
    var disconnect = '0';

    if (disconnect == '0') {
        inputStream.stdout.pipe(ffmpeg.stdin);
        ffmpeg.stdout.on('data', function(data) {
            var data64 = data.toString('base64');
            webSocket.emit('stream',data64);
        });
    }

    webSocket.on('disconnect', function() {
        disconnect=1;
    });
});

public/webaudio_cli.js:

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var startTime = context.currentTime;

// buffer to arraybuffer
function toArrayBuffer(buffer) {
    var ab = new ArrayBuffer(buffer.length);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buffer.length; ++i) {
    view[i] = buffer[i];
    }
    return ab;
}
socket.on('stream', function(data) {
        var data=toArrayBuffer(base64DecToArr(data));
        context.decodeAudioData(data, function(buffer) {
            playBuffer(buffer);
        }, function(err) {
            console.log("decodeAudioData err: "+err);
        });
});

function playBuffer(buf) {
    var source    = context.createBufferSource();
    source.buffer = buf;
    source.connect(context.destination);
    source.start(startTime);
    startTime = startTime+source.buffer.duration;
}

公共(public)/base64.js:

关于html - 在连续流上解码音频数据失败并出现空错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20360375/

相关文章:

node.js - 我的后期操作不起作用

node.js - EJS和WebStorm,错误错误

css - 本地服务器和 Google Chrome 实时站点中的不同字体呈现

javascript - 根据外部高度值移动 Canvas (线)

html - 使用 img 的标题属性作为图像图例?

出现滚动条时 HTML 背景图像改变大小

javascript - 如何获取选择框的文本和值并将其存储到数据库中?

node.js - React-Native 停留在加载依赖图已完成。没有错误

java - Selenium 错误: "org.openqa.selenium.SessionNotCreatedException: session not created from tab crashed" after update electron engine to 9. 0.3

javascript - Google Chrome 忽略 Cache-Control header 的原因