Last active
May 26, 2016 08:55
-
-
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
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
// 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