Skip to content

Instantly share code, notes, and snippets.

@neilvoss
Last active May 26, 2016 08:55
Show Gist options
  • Save neilvoss/eb276435837d3e8a4cf52d5f57cd1a21 to your computer and use it in GitHub Desktop.
Save neilvoss/eb276435837d3e8a4cf52d5f57cd1a21 to your computer and use it in GitHub Desktop.
Workaround to iOS WebAudio default lock – fix for WebAudio MOD/XM/S3M Player
// Fix for https://github.com/jhalme/webaudio-mod-player
// WebAudio is suspended on iOS by default, until an attempt to
// play audio immediately follows a user interaction.
// A simple workaround is to pre-initialize the context
// and bind a user interaction that plays an empty
// buffer once. Doing so unlocks the suspended state for the
// remainder of the session.
// I fixed it by adding this unlock method to player.js:
// (matching syntax... old-skool!)
Modplayer.prototype.unlock = function()
{
if (this.context==null) this.createContext();
// make an empty buffer
var tempbuffer = this.context.createBuffer(1, 1, 22050);
var tempsource = this.context.createBufferSource();
tempsource.buffer = tempbuffer;
// connect it to the context's output
tempsource.connect(this.context.destination);
// play that silence!
tempsource.noteOn(0);
}
// Then using it in a small demo app as follows.
// Could be any main app really... the point is it just
// has to make use of the unlock for iOS.
class ModplayerDemo {
// create demo
constructor() {
// create the player instance
this.modPlayer = new Modplayer();
// set whether the web audio session is assumed to be locked based on env
this.unlocked = ( ModplayerDemo.iOS ) ? false : true;
}
// @return whether environment is iOS
static get iOS() {
return ( navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) );
}
// initialize demo
init() {
// for iOS, bind touchstart to unlock the audio context
if ( ModplayerDemo.iOS ) {
window.addEventListener( 'touchstart', this.unlock.bind( this ) );
}
// assign Modplayer onReady delegate for when loading completes
var that = this;
this.modPlayer.onReady = function() {
that.onReady();
};
}
unlock() {
if ( !this.unlocked ) {
this.unlocked = true;
// call unlock() to resume the suspended audio session
this.modPlayer.unlock();
}
}
load(musicUrl) {
this.modPlayer.load( musicUrl );
}
onReady() {
// start playback following load/parse completion
if ( !this.unlocked ) {
// keep trying every 100ms until unlocked
setTimeout( this.onReady.bind( this ), 100 );
}
else {
this.modPlayer.play();
}
}
}
var demo = new ModplayerDemo();
demo.init();
demo.load( 'mods/Mantronix_and_Tip/mod.overload' );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment