当前位置: 首页 > 面试题库 >

通过Web Audio API通过分块音频进行断断续续的/听不清的播放

司空海荣
2023-03-14
问题内容

我在上一篇文章中提到了这一点,但是由于它与原始问题不相关,因此我将其分开发布。我无法以与在媒体播放器中一样的方式通过Web
Audio播放传输的音频。我尝试了2种不同的传输协议,binaryjs和socketio,并且在尝试通过Web
Audio播放时都没有区别。为了排除音频数据的传输问题,我创建了一个示例,该示例在从客户端接收数据后将数据发送回服务器,并将返回的数据转储到stdout。将其插入VLC可带来您希望听到的聆听体验。

要在通过vlc播放时听到结果(听起来应该是这样),请使用以下命令在https://github.com/grkblood13/web-audio-
stream/tree/master/vlc上运行示例:

$ node webaudio_vlc_svr.js | vlc -

无论出于何种原因,当我尝试通过Web Audio播放相同的音频数据时,它都会失败。结果是随机噪声之间存在较大的静默间隙。

以下代码使播放声音变得如此糟糕,这是怎么回事?

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var delayTime = 0;
var init = 0;
var audioStack = [];

client.on('stream', function(stream, meta){
    stream.on('data', function(data) {
        context.decodeAudioData(data, function(buffer) {
            audioStack.push(buffer);
            if (audioStack.length > 10 && init == 0) { init++; playBuffer(); }
        }, function(err) {
            console.log("err(decodeAudioData): "+err);
        });
    });
});

function playBuffer() {
    var buffer = audioStack.shift();
    setTimeout( function() {
            var source    = context.createBufferSource();
            source.buffer = buffer;
            source.connect(context.destination);
            source.start(context.currentTime);
            delayTime=source.buffer.duration*1000; // Make the next buffer wait the length of the last buffer before being played
            playBuffer();
    }, delayTime);
}

全文:https : //github.com/grkblood13/web-audio-
stream/tree/master/binaryjs


问题答案:

您真的不能只这样调用source.start(audioContext.currentTime)。

setTimeout()的延迟时间长且不精确-
其他主线程可能会继续运行,因此setTimeout()调用可能会延迟几毫秒,甚至数十毫秒(通过垃圾回收,JS执行,布局…)。代码正试图在具有数十毫秒不精确度的计时器上立即播放音频-
该音频必须在大约0.02ms的精度内启动而不出现毛刺-。

Web音频系统的全部要点是音频调度程序在单独的高优先级线程中工作,并且您可以以非常高的精度预先调度音频(开始,停止和audioparam更改)。您应该将系统重写为:

1)跟踪在音频上下文时间安排第一个块的时间-不要立即安排第一个块,给它们一些延迟,以便您的网络有望跟上进度。

2)基于其“下一块”定时安排将来接收的每个连续块。

例如(请注意,我尚未测试此代码,这超出了我的头脑):

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var delayTime = 0;
var init = 0;
var audioStack = [];
var nextTime = 0;

client.on('stream', function(stream, meta){
    stream.on('data', function(data) {
        context.decodeAudioData(data, function(buffer) {
            audioStack.push(buffer);
            if ((init!=0) || (audioStack.length > 10)) { // make sure we put at least 10 chunks in the buffer before starting
                init++;
                scheduleBuffers();
            }
        }, function(err) {
            console.log("err(decodeAudioData): "+err);
        });
    });
});

function scheduleBuffers() {
    while ( audioStack.length) {
        var buffer = audioStack.shift();
        var source    = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
        if (nextTime == 0)
            nextTime = context.currentTime + 0.05;  /// add 50ms latency to work well across systems - tune this if you like
        source.start(nextTime);
        nextTime+=source.buffer.duration; // Make the next buffer wait the length of the last buffer before being played
    };
}


 类似资料:
  • 问题内容: 所以我有一个先前的问题,但意识到我发布了错误的违规代码。我在下面标记了令人反感的陈述。 我正在尝试使用该switch语句为每个运算符设置优先级。 也许有人可以指出我正确的方向。 请注意,我正在运行JAVA 7,因此String Switch可以工作。 码 opType.java Operator.java 问题答案: 如果您放置了,则该函数会在执行之前返回,因此将永远无法达到。 相反,

  • 我将来自用户的一条文本消息作为输入。根据文本消息中的字母,我正在维护一个数组(在代码中命名为持续时间),该数组存储必须播放Audio1的时间。 我或者在特定位置循环播放两个音频文件并停止它们。 第一音频文件播放到第一个字母的持续时间,然后第二音频文件用持续时间值设置位置值,并播放到持续时间2秒。每当该值适当增加时。 但当我播放时,它有时会停在正确的位置(比如前两次迭代),但有时会超过设置的位置,并

  • 本文向大家介绍Android通过HTTP协议实现断点续传下载实例,包括了Android通过HTTP协议实现断点续传下载实例的使用技巧和注意事项,需要的朋友参考一下 整理文档,搜刮出一个Android通过HTTP协议实现断点续传下载的代码,稍微整理精简一下做下分享。 FileDownloader.java                                                

  • 在某些Android设备中尝试在听筒上播放音频文件时似乎存在问题。预期的行为是它应该在听筒中播放音频文件,但在某些设备中,如三星Galaxy Note 2(Android版本4.4.2)和Sony Xperia XA(Android版本6.0),它通过扬声器播放它们。 然而,在摩托罗拉moto g(Android版本6.0)和nexus 5X(Android版本7.0)等设备中,它工作正常。 该应

  • 我想用插入式耳机通过扬声器播放音频文件。 但我得到了 IllegalStateException 有什么想法可以解决这个问题吗?

  • 一边说一边播放(比如实时听到自己唱的歌),使用如下代码实现,即使带着耳机,声音也是断断续续,时大时小,有没有方法解决呢?