javascript - 为什么添加音频分析仪后声音停止播放?网络音频API

标签 javascript web-audio-api

我正在关注这个tut关于使用声音数据来移动物体。

到目前为止它工作正常,它播放声音,这是代码:

/* Hoist some variables. */
var audio,
    context = new (window.AudioContext ||
                   window.webAudioContext ||
                   window.webkitAudioContext)(),
    /* Create a script processor node with a `bufferSize` of 1024. */
    processor = context.createScriptProcessor(1024),
    /* Create an analyser node */
    analyser = context.createAnalyser();

/* Wire the processor into our audio context. */
processor.connect(context.destination);
/* Wire the analyser into the processor */
analyser.connect(processor);

/* Define a Uint8Array to receive the analysers data. */
var data = new Uint8Array(analyser.frequencyBinCount);

/* Try instantiating a new AudioContext, throw an error if it fails. */
try {
    /* Setup an AudioContext. */
    context = new AudioContext();
} catch(e) {
    throw new Error('The Web Audio API is unavailable');
}

/* Define a `Sound` Class */
var Sound = {
    /* Give the sound an element property initially undefined. */
    element: undefined,
    /* Define a class method of play which instantiates a new Media Element
     * Source each time the file plays, once the file has completed disconnect 
     * and destroy the media element source. */
    play: function() { 
        var sound = context.createMediaElementSource(this.element);
        this.element.onended = function() {
            sound.disconnect();
            sound = null;
        }
        sound.connect(context.destination);

        /* Call `play` on the MediaElement. */
        this.element.play();
    }
};

/* Create an async function which returns a promise of a playable audio element. */
function loadAudioElement(url) {
    return new Promise(function(resolve, reject) {
        var audio = new Audio();
        audio.addEventListener('canplay', function() {
            /* Resolve the promise, passing through the element. */
            resolve(audio);
        });
        /* Reject the promise on an error. */
        audio.addEventListener('error', reject);
        audio.src = url;
    });
}

/* Let's load our file. */
loadAudioElement('/audio/shorter.mp3').then(function(elem) {
    /* Instantiate the Sound class into our hoisted variable. */
    audio = Object.create(Sound);
    /* Set the element of `audio` to our MediaElement. */
    audio.element = elem;
    /* Immediately play the file. */
    audio.play();
}, function(elem) {
    /* Let's throw an the error from the MediaElement if it fails. */
    throw elem.error;
});

但我想使用音频分析器数据来移动东西......

所以我必须修改声音类,而不是仅将音频的媒体元素源连接到音频上下文中,现在它也应该通过分析器连接。

但是当我添加此代码时,声音停止播放...

 /* Removed for brevity... */
    play: function() { 
        var sound = context.createMediaElementSource(this.element);
        this.element.onended = function() {
            sound.disconnect();
            sound = null;
            /* Noop the audioprocess handler when the file finishes. */
            processor.onaudioprocess = function() {};
        }
        /* Add the following line to wire into the analyser. */
        sound.connect(analyser);
        sound.connect(context.destination);

        processor.onaudioprocess = function() {
            /* Populate the data array with the frequency data. */
            analyser.getByteTimeDomainData(data);
        };
        /* Call `play` on the MediaElement. */
        this.element.play();
    }

这是停止工作的完整代码:

/* Hoist some variables. */
var audio,
    context = new (window.AudioContext ||
                   window.webAudioContext ||
                   window.webkitAudioContext)(),
    /* Create a script processor node with a `bufferSize` of 1024. */
    processor = context.createScriptProcessor(1024),
    /* Create an analyser node */
    analyser = context.createAnalyser();

/* Wire the processor into our audio context. */
processor.connect(context.destination);
/* Wire the analyser into the processor */
analyser.connect(processor);

/* Define a Uint8Array to receive the analysers data. */
var data = new Uint8Array(analyser.frequencyBinCount);

/* Try instantiating a new AudioContext, throw an error if it fails. */
try {
    /* Setup an AudioContext. */
    context = new AudioContext();
} catch(e) {
    throw new Error('The Web Audio API is unavailable');
}

/* Define a `Sound` Class */
var Sound = {
    /* Give the sound an element property initially undefined. */
    element: undefined,
    /* Define a class method of play which instantiates a new Media Element
     * Source each time the file plays, once the file has completed disconnect 
     * and destroy the media element source. */
    /* Removed for brevity... */
play: function() { 
    var sound = context.createMediaElementSource(this.element);
    this.element.onended = function() {
        sound.disconnect();
        sound = null;
        /* Noop the audioprocess handler when the file finishes. */
        processor.onaudioprocess = function() {};
    }
    /* Add the following line to wire into the analyser. */
    sound.connect(analyser);
    sound.connect(context.destination);

    processor.onaudioprocess = function() {
        /* Populate the data array with the frequency data. */
        analyser.getByteTimeDomainData(data);
    };
    /* Call `play` on the MediaElement. */
    this.element.play();
}

};

/* Create an async function which returns a promise of a playable audio element. */
function loadAudioElement(url) {
    return new Promise(function(resolve, reject) {
        var audio = new Audio();
        audio.addEventListener('canplay', function() {
            /* Resolve the promise, passing through the element. */
            resolve(audio);
        });
        /* Reject the promise on an error. */
        audio.addEventListener('error', reject);
        audio.src = url;
    });
}

/* Let's load our file. */
loadAudioElement('/audio/shorter.mp3').then(function(elem) {
    /* Instantiate the Sound class into our hoisted variable. */
    audio = Object.create(Sound);
    /* Set the element of `audio` to our MediaElement. */
    audio.element = elem;
    /* Immediately play the file. */
    audio.play();
}, function(elem) {
    /* Let's throw an the error from the MediaElement if it fails. */
    throw elem.error;
});

有什么想法吗?

最佳答案

您应该将分析器连接到目标以使其正常工作。

sound.connect(分析器); analyzer.connect(context.destination);

关于javascript - 为什么添加音频分析仪后声音停止播放?网络音频API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28159618/

相关文章:

javascript - 如何使用Javascript访问网站音频源?

javascript - 如何相交两个音频 channel ?

Javascript 绘制 Canvas 内存泄漏

javascript - 定期更新和渲染来自 Flask 的值

javascript - 从解码的音频流中清理内存的正确方法(移动)

javascript - Web Audio Api 在不同浏览器中的精确循环

javascript - 我使用 JavaScript 网络音频 API 开发了录音,但音质很差

javascript - 如何用多个事件处理程序触发一个函数(更改)

javascript - Angular JS ng 表错误 TypeError : newParams reload is not a function and 10 digest iterations reached, ABort

javascript - XHR 抛出无法捕获的错误