if (!window.console) console = {
log: function() {}
};
var lowLag = new function() {
this.someVariable = undefined;
this.showNeedInit = function() {
lowLag.msg("lowLag: you must call lowLag.init() first!");
}
this.load = this.showNeedInit;
this.play = this.showNeedInit;
this.pause = this.showNeedInit;
this.stop = this.showNeedInit;
this.switch = this.showNeedInit;
this.change = this.showNeedInit;
this.audioContext = undefined;
this.audioContextPendingRequest = {};
this.audioBuffers = {};
this.audioBufferSources = {};
this.currentTag = undefined;
this.currentPlayingTag = undefined;
this.init = function() {
this.msg("init audioContext");
this.load = this.loadSoundAudioContext;
this.play = this.playSoundAudioContext;
this.pause = this.pauseSoundAudioContext;
this.stop = this.stopSoundAudioContext;
this.switch = this.switchSoundAudioContext;
this.change = this.changeSoundAudioContext;
if (!this.audioContext) {
this.audioContext = new(window.AudioContext || window.webkitAudioContext)();
}
}
this.getTagFromURL = function(url, tag) {
if (tag != undefined) return tag;
return lowLag.getSingleURL(url);
}
this.getSingleURL = function(urls) {
if (typeof(urls) == "string") return urls;
return urls[0];
}
this.getURLArray = function(urls) {
if (typeof(urls) == "string") return [urls];
return urls;
}
this.loadSoundAudioContext = function(urls, tag) {
var url = lowLag.getSingleURL(urls);
tag = lowLag.getTagFromURL(urls, tag);
lowLag.msg('webkit/chrome audio loading ' + url + ' as tag ' + tag);
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
var retVal = lowLag.audioContext.decodeAudioData(request.response, successLoadAudioFile, errorLoadAudioFile);
if (retVal && typeof retVal.then == 'function') {
retVal.then(successLoadAudioFile).catch(function(e) {
errorLoadAudioFile(e);
urls.shift();
if (urls.length > 0) {
lowLag.loadSoundAudioContext(urls, tag);
}
});
}
};
request.send();
function successLoadAudioFile(buffer) {
lowLag.audioBuffers[tag] = buffer;
if (lowLag.audioContextPendingRequest[tag]) {
lowLag.playSoundAudioContext(tag);
}
}
function errorLoadAudioFile(e) {
lowLag.msg("Error loading webkit/chrome audio: " + e);
}
}
this.playSoundAudioContext = function(tag) {
var context = lowLag.audioContext;
if ((lowLag.currentPlayingTag && lowLag.currentTag && lowLag.currentPlayingTag === lowLag.currentTag) || (tag && lowLag.currentPlayingTag && lowLag.currentPlayingTag === tag)) {
if (context !== undefined) {
if (context.state === 'suspended') {
context.resume().then(function() {
lowLag.msg("playSoundAudioContext resume " + lowLag.currentPlayingTag);
return;
}).catch(function(e) {
lowLag.msg("playSoundAudioContext resume error for " + lowLag.currentPlayingTag + ". Error: " + e);
});
return;
}
}
}
if (tag === undefined) {
tag = lowLag.currentTag;
}
if (lowLag.currentPlayingTag && lowLag.currentPlayingTag === tag) {
lowLag.msg("playSoundAudioContext already playing " + tag);
return;
} else {
lowLag.msg("playSoundAudioContext " + tag);
}
var buffer = lowLag.audioBuffers[tag];
if (buffer === undefined) {
lowLag.audioContextPendingRequest[tag] = true;
lowLag.msg("playSoundAudioContext pending request " + tag);
return;
}
var source;
source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.loop = true;
lowLag.audioBufferSources[tag] = source;
var sourceOld = lowLag.currentPlayingTag ? lowLag.audioBufferSources[lowLag.currentPlayingTag] : undefined;
if (sourceOld !== undefined) {
if (typeof(sourceOld.noteOff) == "function") {
sourceOld.noteOff(0);
} else {
sourceOld.stop();
}
lowLag.msg("playSoundAudioContext stopped " + lowLag.currentPlayingTag);
lowLag.audioBufferSources[lowLag.currentPlayingTag] = undefined;
lowLag.currentPlayingTag = undefined;
}
if (typeof(source.noteOn) == "function") {
source.noteOn(0);
} else {
source.start();
}
lowLag.currentTag = tag;
lowLag.currentPlayingTag = tag;
if (context.state === 'running') {
lowLag.msg("playSoundAudioContext started " + tag);
} else if (context.state === 'suspended') {
context.resume().then(function() {
lowLag.msg("playSoundAudioContext started and then resumed " + tag);
}).catch(function(e) {
lowLag.msg("playSoundAudioContext started and then had a resuming error for " + tag + ". Error: " + e);
});
} else if (context.state === 'closed') {
lowLag.msg("playSoundAudioContext failed to start, context closed for " + tag);
} else {
lowLag.msg("playSoundAudioContext unknown AudioContext.state for " + tag + ". State: " + context.state);
}
}
this.pauseSoundAudioContext = function() {
var tag = lowLag.currentPlayingTag;
var context = lowLag.audioContext;
if (tag === undefined) {
lowLag.msg("pauseSoundAudioContext nothing to pause");
return;
}
if (context !== undefined) {
if (context.state === 'running') {
lowLag.msg("pauseSoundAudioContext " + tag);
context.suspend().then(function() {
lowLag.msg("pauseSoundAudioContext suspended " + tag);
}).catch(function(e) {
lowLag.msg("pauseSoundAudioContext suspend error for " + tag + ". Error: " + e);
});
} else if (context.state === 'suspended') {
lowLag.msg("pauseSoundAudioContext already suspended " + tag);
} else if (context.state === 'closed') {
lowLag.msg("pauseSoundAudioContext already closed " + tag);
} else {
lowLag.msg("pauseSoundAudioContext unknown AudioContext.state for " + tag + ". State: " + context.state);
}
}
}
this.stopSoundAudioContext = function() {
var tag = lowLag.currentPlayingTag;
if (tag === undefined) {
lowLag.msg("stopSoundAudioContext nothing to stop");
return;
} else {
lowLag.msg("stopSoundAudioContext " + tag);
}
var source = lowLag.audioBufferSources[tag];
if (source !== undefined) {
if (typeof(source.noteOff) == "function") {
source.noteOff(0);
} else {
source.stop();
}
lowLag.msg("stopSoundAudioContext stopped " + tag);
lowLag.audioBufferSources[tag] = undefined;
lowLag.currentPlayingTag = undefined;
}
}
this.switchSoundAudioContext = function(autoplay) {
lowLag.msg("switchSoundAudioContext " + (autoplay ? 'and autoplay' : 'and do not autoplay'));
if (lowLag.currentTag && lowLag.currentTag == 'audio1') {
lowLag.currentTag = 'audio2';
} else {
lowLag.currentTag = 'audio1';
}
if (autoplay) {
lowLag.playSoundAudioContext();
}
}
this.changeSoundAudioContext = function(tag, autoplay) {
lowLag.msg("changeSoundAudioContext to tag " + tag + " " + (autoplay ? 'and autoplay' : 'and do not autoplay'));
if(tag === undefined) {
lowLag.msg("changeSoundAudioContext tag is undefined");
return;
}
lowLag.currentTag = tag;
if (autoplay) {
lowLag.playSoundAudioContext();
}
}
this.msg = function(m) {
m = "-- lowLag " + m;
console.log(m);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
lowLag.init();
lowLag.load(['https://coubsecure-s.akamaihd.net/get/b86/p/coub/simple/cw_looped_audio/f0dab49f867/083bf409a75db824122cf/med_1550250381_med.mp3'], 'audio1');
lowLag.load(['https://coubsecure-s.akamaihd.net/get/b173/p/coub/simple/cw_looped_audio/0d5adfff2ee/80432a356484068bb0e15/med_1550254045_med.mp3'], 'audio2');
lowLag.changeSoundAudioContext('audio1', false);
});
$(document).ready(function() {
var $audioElement = $('#audioElement');
var audioEl = $audioElement[0];
var audioSources = {
"audio1": "https://coubsecure-s.akamaihd.net/get/b86/p/coub/simple/cw_looped_audio/f0dab49f867/083bf409a75db824122cf/med_1550250381_med.mp3",
"audio2": "https://coubsecure-s.akamaihd.net/get/b173/p/coub/simple/cw_looped_audio/0d5adfff2ee/80432a356484068bb0e15/med_1550254045_med.mp3"
};
playAudioElement = function() {
audioEl.play();
}
pauseAudioElement = function() {
audioEl.pause();
}
stopAudioElement = function() {
audioEl.pause();
audioEl.currentTime = 0;
}
switchAudioElement = function(autoplay) {
var source = $audioElement.attr('data-source');
if (source && source == 'audio1') {
$audioElement.attr('src', audioSources.audio2);
$audioElement.attr('data-source', 'audio2');
} else {
$audioElement.attr('src', audioSources.audio1);
$audioElement.attr('data-source', 'audio1');
}
if (autoplay) {
audioEl.play();
}
}
changeAudioElement = function(tag, autoplay) {
var source = $audioElement.attr('data-source');
if(tag === undefined || audioSources[tag] === undefined) {
return;
}
$audioElement.attr('src', audioSources[tag]);
$audioElement.attr('data-source', tag);
if (autoplay) {
audioEl.play();
}
}
changeAudioElement('audio1', false);
});
</script>
<h1>
AudioContext (<a href="https://developer.mozilla.org/en-US/docs/Web/API/AudioContext" target="blank">api</a>)
</h1>
<button onClick="lowLag.play();">Play</button>
<button onClick="lowLag.pause();">Pause</button>
<button onClick="lowLag.stop();">Stop</button>
<button onClick="lowLag.switch(true);">Swtich</button>
<button onClick="lowLag.change('audio1', true);">Play 1</button>
<button onClick="lowLag.change('audio2', true);">Play 2</button>
<hr>
<h1>
Audio Element (<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio" target="blank">api</a>)
</h1>
<audio id="audioElement" controls loop preload="auto" src="">
</audio>
<br>
<button onClick="playAudioElement();">Play</button>
<button onClick="pauseAudioElement();">Pause</button>
<button onClick="stopAudioElement();">Stop</button>
<button onClick="switchAudioElement(true);">Switch</button>
<button onClick="changeAudioElement('audio1', true);">Play 1</button>
<button onClick="changeAudioElement('audio2', true);">Play 2</button>