gpt4 book ai didi

javascript - Web Audio API - 多个同步轨道 - 在新轨道开始时停止上一轨道

转载 作者:行者123 更新时间:2023-11-29 18:48:09 25 4
gpt4 key购买 nike

我正在尝试模仿“Mozilla Web Audio API for games”Web 文档中的 Web Audio API 多轨演示。

https://developer.mozilla.org/en-US/docs/Games/Techniques/Audio_for_Web_Games#Web_Audio_API_for_games

我唯一要注意的是,我希望在单击新轨道后停止之前的轨道(而不是在彼此之上分层播放)。

例如,点击鼓,鼓开始演奏,然后点击吉他,鼓停止,吉他从鼓停止的地方开始演奏。

有什么想法吗?是否有更好的工具/库来处理网络音频?

http://jsfiddle.net/c87z11jj/1/

<ul>
<li><a class="track" href="http://jPlayer.org/audio/mp3/gbreggae-leadguitar.mp3">Lead Guitar</a></li>
<li><a class="track" href="http://jPlayer.org/audio/mp3/gbreggae-drums.mp3">Drums</a></li>
<li><a class="track" href="http://jPlayer.org/audio/mp3/gbreggae-bassguitar.mp3">Bass Guitar</a></li>
<li><a class="track" href="http://jPlayer.org/audio/mp3/gbreggae-horns.mp3">Horns</a></li>
<li><a class="track" href="http://jPlayer.org/audio/mp3/gbreggae-clav.mp3">Clavi</a></li>
</ul>

window.AudioContext = window.AudioContext || window.webkitAudioContext;

var offset = 0;
var context = new AudioContext();

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

var audiobuffer;

// Decode asynchronously
request.onload = function() {

if (request.status == 200) {

context.decodeAudioData(request.response, function(buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
console.log('context.currentTime '+context.currentTime);

if (offset == 0) {
source.start();
offset = context.currentTime;
} else {
source.start(0,context.currentTime - offset);
}

}, function(e) {
console.log('Error decoding audio data:' + e);
});
} else {


console.log('Audio didn\'t load successfully; error code:' + request.statusText);
}
}
request.send();
}

var tracks = document.getElementsByClassName('track');

for (var i = 0, len = tracks.length; i < len; i++) {
tracks[i].addEventListener('click', function(e){
console.log(this.href);
playTrack(this.href);
e.preventDefault();
});
}

最佳答案

只需将 BufferSources 存储在外部作用域的某处,然后调用它们的 stop() 方法。

我冒昧地重写了一点你的加载逻辑,你不应该在每次开始新轨道时都创建一个新请求,在这种情况下你失去了 AudioBuffers 相对于 Audio 元素的主要优势:它们真的很快实例化。

var active_source = null;

function stopActiveSource() {
if (active_source) {
active_source.onended = null; // manual stop, no event
active_source.stop(0);
}
}
// instead of requesting a new ArrayBuffer every time
// store them in a dictionnary
var buffers = {};
var context = new(window.AudioContext || window.webkitAudioContext)();

function playTrack(url) {
// get fom our dictionnary
var buffer = buffers[url];
// stop the active one if any
stopActiveSource();
// create a new BufferSource
var source = context.createBufferSource();
// it is now the active one
active_source = source;
source.onended = function() {
active_source = null;
};

source.buffer = buffer;
source.connect(context.destination);

source.start(0);
}

// start by getting all AudioBuffers
var tracks = document.getElementsByClassName('track');

for (var i = 0, len = tracks.length; i < len; i++) {
tracks[i].addEventListener('click', function(e) {
playTrack(this.href);
e.preventDefault();
});
getBuffer(tracks[i].href);
}


function getBuffer(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function(evt) {
context.decodeAudioData(request.response, store);
};
request.send();

function store(buffer) {
buffers[url] = buffer;
}
}
<base href="https://dl.dropboxusercontent.com/s/">
<ul>
<li><a class="track" href="kbgd2jm7ezk3u3x/hihat.mp3">HiHat</a></li>
<li><a class="track" href="h2j6vm17r07jf03/snare.mp3">Snare</a></li>
<li><a class="track" href="1cdwpm3gca9mlo0/kick.mp3">Kick</a></li>
<li><a class="track" href="h8pvqqol3ovyle8/tom.mp3">Tom</a></li>
</ul>

关于javascript - Web Audio API - 多个同步轨道 - 在新轨道开始时停止上一轨道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52436015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com