Last active
February 21, 2022 02:06
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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