Я пытаюсь написать небольшую библиотеку аудио для конкретного веб-приложения, чтобы решить проблему источников аудио-буфера Web, требующих длительного времени загрузки, я пытаюсь переключить источник звука HTML5 (через MediaElementSourceNode) с помощью буфераИсточник, как только Источник буфера готов к игре.с 20-минутным треком для декодирования и начала воспроизведения требуется источник буфера Web Audio примерно 5 секунд.
с использованием MediaElementSourceNode требуется для использования PanNode в Web Audio
Сначала я подумал, что этопроблема латентности основного потока JS, которая выбрасывала «время начала».Я подумал, что смогу решить, убедившись, что код, который отключает MediaElementSource и позволяет BufferSourceNode, как можно ближе к выполнению.
Затем, хотя я должен быть, HTML имеет небольшую задержку при запуске, вызывая записьЧтобы отключить startTime, я использовал обработчик событий, слушающий «play».
Я искал и обнаружил, что 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 щелчка.