Skip to content

Instantly share code, notes, and snippets.

@RickeyWard
Last active February 21, 2022 02:06
Show Gist options
  • Save RickeyWard/9c5badf025d68ecce5db40f13fbd6651 to your computer and use it in GitHub Desktop.
Save RickeyWard/9c5badf025d68ecce5db40f13fbd6651 to your computer and use it in GitHub Desktop.
SimpleWav Cross-browser base64 encoded wav file player api aimed at supporting wav in IE
/*
* IE can't play wav files in the javascript audio api, or audio element.
* This is a cross browser base64 wav file player aimed at being very simple
* and small while still supporting IE.
* (C)2020 Rickey Ward
* MIT Licence
*/
(function () {
window.simpleWav = {
isAudioPlaying: false,
fallbackPlayer: null,
fallbackPlayerTimeout: null,
fallbackPlayerObjectURL: null,
audioPlayerLastCallaback: null,
canPlayWavs: true
}
try {
window.simpleWav.CanPlayWavs = new Audio().canPlayType('audio/wav') !== '';
} catch (e) {
window.simpleWav.CanPlayWavs = false;
}
window.simpleWav.PlayWav = function (b64Wav, endedCallback, durMs) {
try {
//stop if playing
window.simpleWav.StopWav(true);
window.simpleWav.audioPlayerLastCallaback = endedCallback;
if (!window.simpleWav.CanPlayWavs) { //ie
window.simpleWav.fallbackPlayer = document.createElement('bgsound');
window.simpleWav.fallbackPlayer.setAttribute('id', 'fallbackWavPlayer');
window.simpleWav.fallbackPlayerObjectURL = URL.createObjectURL(window.simpleWav.b64toBlob(b64Wav));
window.simpleWav.fallbackPlayer.setAttribute('src', window.simpleWav.fallbackPlayerObjectURL);
document.body.appendChild(window.simpleWav.fallbackPlayer);
window.simpleWav.fallbackPlayerTimeout = setTimeout(function () {
endedCallback && endedCallback();
}, durMs || 2000); //If you know the length of the audio, bgsound doesn't detect end of play
} else {
window.simpleWav.audioPlayer = new Audio("data:audio/wav;base64," + b64Wav);
window.simpleWav.audioPlayer.addEventListener("ended", function (event) {
endedCallback && endedCallback(event);
});
window.simpleWav.audioPlayer.addEventListener("canplaythrough", function () {
window.simpleWav.audioPlayer.play();
});
}
} catch (error) {
window.simpleWav.audioPlayerLastCallaback = null;
endedCallback && endedCallback();
}
}
window.simpleWav.StopWav = function (triggerCallback) {
if (!window.simpleWav.CanPlayWavs) {
window.simpleWav.fallbackPlayerTimeout && clearTimeout(window.simpleWav.fallbackPlayerTimeout);
if (window.simpleWav.fallbackPlayer != null) {
window.simpleWav.fallbackPlayer.setAttribute('src', '');
document.body.removeChild(window.simpleWav.fallbackPlayer);
window.simpleWav.fallbackPlayer = null;
} else if (document.querySelector('bgsound')) {
var cur = document.querySelector('bgsound');
cur.setAttribute('src', '');
document.body.removeChild(cur);
}
if (window.simpleWav.fallbackPlayerObjectURL) {
URL.revokeObjectURL(window.simpleWav.fallbackPlayerObjectURL);
window.simpleWav.fallbackPlayerObjectURL = null;
}
} else {
if (window.simpleWav.audioPlayer) {
//must have ended or be paused to be elligbile for garbage collection
window.simpleWav.audioPlayer.pause();
window.simpleWav.audioPlayer = null;
}
}
if (window.simpleWav.audioPlayerLastCallaback && !triggerCallback) {
window.simpleWav.audioPlayerLastCallaback();
window.simpleWav.audioPlayerLastCallaback = null;
}
}
/* This has been copied and pasted from different projects based on something from stack overflow years ago */
window.simpleWav.b64toBlob = function (b64Data, contentType = '', sliceSize = 512) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = window.atob(b64Data.trim());
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, {
type: contentType
});
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment