在iOS上没有用户交互的情况下更改WebAudioAPI中的声音

时间:2017-02-22 23:37:01

标签: javascript ios web-audio

我正在使用此功能创建声音,这在桌面和Android上运行良好,并且当我使用touchevent启动它时,最初在iOS上工作。我需要稍后用另一个声音文件替换声音,但是在iOS上它没有启动 - 我假设因为它需要另一个用户交互来播放声音。

这是耳机中的VR应用程序,因此无法进行此类用户交互。有没有其他方法可以替换声音或其他非点击用户交互,我可以像运动一样使用?

我见过这个http://matt-harrison.com/perfect-web-audio-on-ios-devices-with-the-web-audio-api/

这似乎有另一个解决方案,但我不想预先加载所有文件(它们相当大,其中有10个)这似乎是一个要求 - 加上我使用暂停功能在我的代码中。这有什么简单的方法吗?

var AudioContext = AudioContext || webkitAudioContext, context = new AudioContext();

function createSound(filename) {
console.log('createSound()');

var url = cdnPrefix + '/' + filename;
var buffer;


context = new AudioContext();

var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';

// Decode asynchronously
request.onload = function() {
    context.decodeAudioData(request.response, function(b) {
        buffer = b;
        play();
    });
}
request.send();


var sourceNode = null,
    startedAt = 0,
    pausedAt = 0,
    playing = false,
    volume = context.createGain();

var play = function() {

    if(playing || !buffer)
        return;

    var offset = pausedAt;

    sourceNode = context.createBufferSource();
    sourceNode.connect(context.destination);
    sourceNode.connect(volume);
    volume.gain.value = 1;

    sourceNode.buffer = buffer;
    sourceNode.start(0, offset);
    sourceNode.onended = onEnded;

    sourceNode.onstatechange = onStateChange;
    sourceNode.onloaded = onLoaded;
    //sourceNode.loop = true;
    startedAt = context.currentTime - offset;
    pausedAt = 0;
    playing = true;
    $(document).trigger("voiceoverPlay");

    if(isPaused == true)
        pause();
};

function onEnded(event){
    $(document).trigger("voiceoverEnded");
    play();
}

function onStateChange(event){
    console.log('onStateChange',event);
}

function onLoaded(event){
    console.log('onLoaded',event);
}


var pause = function() {
    var elapsed = context.currentTime - startedAt;
    stop();
    pausedAt = elapsed;
    $(document).trigger("voiceoverPause");
};

var stop = function() {
    if (sourceNode) {
        sourceNode.disconnect();
        if(playing === true)
            sourceNode.stop(0);
        sourceNode = null;
    }
    pausedAt = 0;
    startedAt = 0;
    playing = false;
};

var getPlaying = function() {
    return playing;
};

var getCurrentTime = function() {
    if(pausedAt) {
        return pausedAt;
    }
    if(startedAt) {
        return context.currentTime - startedAt;
    }
    return 0;
};

var setCurrentTime = function(time) {
    pausedAt = time;
};

var getDuration = function() {
    return buffer.duration;
};

return {
    getCurrentTime: getCurrentTime,
    setCurrentTime: setCurrentTime,
    getDuration: getDuration,
    getPlaying: getPlaying,
    play: play,
    pause: pause,
    stop: stop
};

}

1 个答案:

答案 0 :(得分:0)

每个声音都需要触摸事件。

我最终使用的SoundJS要好得多。