Audio from archive.org:
HTML for "Cannot spam":
JS for "Cannot spam": const AUDIOS = document.querySelectorAll('#image_sounds audio'); function play(audio) { audio.currentTime = 0; audio.play(); } function toggleAudio(el,i) { i = isNaN(i) ? 0 : i; el.disabled = true; el.onclick = () => { toggleAudio(el, (i+1) % AUDIOS.length ); } const audio = AUDIOS[i]; audio.onended = () => { el.disabled = false; } play(audio); }
HTML for "Can spam":
JS for "Can spam": let toggleAudio = () => {}; if (typeof AudioContext === 'undefined' || typeof AudioContext.prototype.createBufferSource === 'undefined') { AUDIOS.forEach(a=>{ a.load(); }); function play(audio) { audio.currentTime = 0; audio.play(); } toggleAudio = (el,i) => { i = isNaN(i) ? 0 : i; el.onclick = () => { toggleAudio_Overlap(el, (i+1) % AUDIOS.length ); } const audio = AUDIOS[i]; if (audio.playing) { audio.onended = () => { play(audio); audio.onended = null; } } else play(audio); }; } else { const URLS = []; let urlCount = 0; const ctx = new AudioContext(); const buffers = []; for (let i=0; i { URLS[i] = a.currentSrc; ++urlCount; if (urlCount === AUDIOS.length) loadContext(); } } function loadContext() { let bufferCount = 0; for (let i = 0; i < URLS.length; i++) { const url = URLS[i]; window.fetch(url) .then(res => res.arrayBuffer()) .then(arrBuffer => ctx.decodeAudioData(arrBuffer)) .then(audioBuffer => { buffers[i] = audioBuffer; ++bufferCount; if (bufferCount = AUDIOS.length) { toggleAudio = toggleAudio_Buffer; } }); } } function playBuffer(buffer) { const src = ctx.createBufferSource(); src.buffer = buffer; src.connect(ctx.destination); src.start(); } function toggleAudio_Buffer(el,i) { i = isNaN(i) ? 0 : i; el.onclick = () => { toggleAudio_Buffer(el, (i+1) % buffers.length ); } playBuffer(buffers[i]); } }