如何在不单击的情况下切换Web音频源节点?

时间:2018-12-23 04:10:37

标签: javascript audio

我正在尝试为特定的Web应用程序编写一个小型音频库,以解决需要较长加载时间的Web音频缓冲源的问题,我正在尝试通过Buffer切换HTML5音频源(通过MediaElementSourceNode)一旦缓冲区源准备好播放,就源。只需20分钟的音轨,Web Audio的缓冲源大约需要5秒钟才能解码并开始播放。

要在Web Audio中使用PanNode,必须使用MediaElementSourceNode

首先,我认为这是JS主线程延迟问题,该问题使“开始时间”不合时宜。我认为我可以通过确保禁用MediaElementSource并启用BufferSourceNode的代码尽可能接近执行来解决。

然后,尽管我一定是启动时延迟很小的HTML,导致关闭了记录的startTime,但是为了解决这个问题,我使用了事件处理程序来监听“播放”。

我四处搜寻,发现Gapless 5显然没有问题,看着它的源代码,我找不到它如何无缝切换源代码

 play(offset) {
        this.createNodes();
        this.connectNodes();
        //if webAudio's buffer source is not ready, starting playing with HTML5
    if (!this.audioClip.isWebAudioReady() &&
        this.audioClip.playType > 0) {
        this.playHTML5();
    }
    //returns true if buffer != null
    if (!this.audioClip.isWebAudioReady()) {
        this.audioClip.addDecodeListener(this.play.bind(this));
    }

    if (this.audioClip.isWebAudioReady()) {
        this.playBufferSource();

    }
 playHTML5() {
    var context = AudioManager.context();
    if (this.audioClip.isHTML5Ready()) {
        this.createHTMLSourceNode();
        console.log("playing HTML5");
        this.mediaElementSourceNode.connect(this.gainNode);
        this.mediaElementSourceNode.source.play();
        this.startTime = context.currentTime;


    }
    else {
        console.log('not ready yet');
        this.audioClip.addLoadListener(this.playHTML5.bind(this));
    }
}
playBufferSource() {
    var context = AudioManager.context();
    var offset = context.currentTime - this.startTime;
    if (!this.bufferSourceNode) {
        this.createBufferSourceNode();
    }
    this.bufferSourceNode.connect(this.gainNode);
    //hoplessly attempt to make up for Thread latencey
    offset = context.currentTime - this.startTime;

    if (this.audioClip.playType > 0) {
        this.mediaElementSourceNode.disconnect();
        this.mediaElementSourceNode = null;
    }
    if (this.audioClip.playType == 0) {
        offset = 0;
        this.bufferSourceNode.start(0, offset);
    }
    else {
        offset = context.currentTime - this.startTime;
        this.bufferSourceNode.start(0, offset);
    }

    // console.log("starting web audio at" + offset);
}
createBufferSourceNode() {
    var context = AudioManager.context();
    if (!this.audioClip.webAudioReady) {
        console.log('Web Audio not ready!, Sometihng went wrong!');
        return;

    }
    var buffer = this.audioClip.buffer;
    this.bufferSourceNode = context.createBufferSource();
    //When using anything other than Buffer, 
    //we want to disable pitching.
    if (this.audioClip.playType == NS.PlayTypes.Buffer) {
        this.bufferSourceNode.playbackRate.setValueAtTime(this._pitch,
            context.currentTime);

    }
    this.bufferSourceNode.buffer = buffer;
}


createHTMLSourceNode() {
    var context = AudioManager.context();
    var HTMLAudio = this.audioClip.mediaElement.cloneNode(false);

    //HTMLAudio.addEventListener('ended', onHTML5Ended.bind(this), false);
    HTMLAudio.addEventListener('play', this.onHTML5Play.bind(this), false);

    var sourceNode = context.createMediaElementSource(HTMLAudio);

    sourceNode.source = HTMLAudio;
    this.mediaElementSourceNode = sourceNode;

}
/**
 * 
 */
onHTML5Play() {
    this.startTime = AudioManager.context().currentTime;
    console.log("HTML5 started playing");
}

由于我要在与第一信号源尽可能近的时间启动第二信号源,因此从技术上讲,如果波形线足够接近,我应该不会听到任何滴答声,但是听到的滴答声非常可听,有时可以听到2响。

0 个答案:

没有答案