KyleNau Posted September 22, 2015 Share Posted September 22, 2015 Just a heads up that if any of you are using the webAudio API (that includes Howler.js) you may need to check your games in Safari under iOS9. Basically, if you have your sound initiating on a touchStart event, it likely doesn't work anymore. Binding it to touchEnd fixes it. digitalmouse, InvisionUser and Gio 3 Quote Link to comment Share on other sites More sharing options...
alex_h Posted September 22, 2015 Share Posted September 22, 2015 Thanks for the warning. Damn that's broken all my games then!Nice one Apple... Quote Link to comment Share on other sites More sharing options...
digitalmouse Posted September 22, 2015 Share Posted September 22, 2015 About 2 weeks ago I had to add code under iOS 8+ to trigger audio on an initial touch event In Safari and Chrome on a modern iPad Air. Used this touch-test fiddle to see what was actually happening on touch events: http://jsfiddle.net/cpUsA/4/ Code worked just fine when reduced to just listening for touchstart on all touch devices (Android / iOS), but after upgrading to iOS9 even listening to 'touchEnd' no longer works for me. Using soundjs currently but, as mentioned above, even howler is affected. Anyone else continuing to have issues, even with KyleNau's fix? My event listener snippet:var domElem = js.Browser.document;if ( domElem.addEventListener ){ // at first I didn't really know *where* in time the touch event is registered, so I // just check 'em all. there is a window of 300-500 ms to listen to. -jimm 15.09 // looks like touchstart and click will do. checking all of them slows // the simulator down -jimm 16.09 // iOS 9 update: nothing triggers audio now -jimm 22.09 domElem.addEventListener( "touchstart", touch_me, false ); domElem.addEventListener( "touchend", touch_me, false ); domElem.addEventListener( "mousedown", touch_me, false ); domElem.addEventListener( "mouseup", touch_me, false ); domElem.addEventListener( "click", touch_me, false );} else { domElem.attachEvent( "onclick", touch_me, false );}!#$% Apple! tips4design 1 Quote Link to comment Share on other sites More sharing options...
AshleyScirra Posted September 22, 2015 Share Posted September 22, 2015 This is terrible. iOS 9 appears to basically break all existing content using Web Audio. I found an existing WebKit bug for this and posted more information in it including test cases: https://bugs.webkit.org/show_bug.cgi?id=149367 Please vote/comment on it to raise awareness! I found a workaround (which will be integrated in to the next Construct 2 release). Unblocking the Web Audio API has typically been done in touchstart like this:document.addEventListener("touchstart", function (){ if (had_touch) return; // play empty buffer to unmute audio var buffer = context.createBuffer(1, 1, 22050); var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(0); had_touch = true;});Now you need to do that in a touchend event instead, and it works again. However, all content ever published using this technique needs to be updated! Safari should definitely be fixed. Quote Link to comment Share on other sites More sharing options...
Raiper34 Posted September 22, 2015 Share Posted September 22, 2015 Sounds really great.... Quote Link to comment Share on other sites More sharing options...
Shoozes Posted September 24, 2015 Share Posted September 24, 2015 Found this out recently. For all those GameMaker Studio users out there, I went ahead and submitted a bug report.Add this code in your index.html - It belongs right before the script that runs your game.js file for a quick fix:<!-- Run the game code --><script type="text/javascript">window.addEventListener("touchend", ios_unlock_sound, false);function ios_unlock_sound(event) { var buffer = g_WebAudioContext.createBuffer(1, 1, 22050); var source = g_WebAudioContext.createBufferSource(); source.buffer = buffer; source.connect(g_WebAudioContext.destination); source.noteOn(0); window.removeEventListener("touchend", ios_unlock_sound, false);}</script> KyleNau and InvisionUser 2 Quote Link to comment Share on other sites More sharing options...
jsc Posted September 30, 2015 Share Posted September 30, 2015 Has anyone tried the 'touchend' solution with swipes or long touches rather than quick taps? Here: http://www.holovaty.com/writing/ios9-web-audio/ It's mentioned that the 'touchend' solution doesn't work in those cases. This is what I'm seeing as well. My current solution is to listen for the source 'onended' event to determine when the silent 'unlock' sound has actually played, and to keep trying to unlock on 'touchend' until the audio is actually unlocked. I'm curious as to whether other people have run into the problem of 'touchend' not always working and what solutions people are using. Does anyone have any suggestions on how to handle this in a reliable way? Quote Link to comment Share on other sites More sharing options...
digitalmouse Posted October 9, 2015 Share Posted October 9, 2015 The above workarounds mentioned above for Construct 2 and GameMaker Studio have made their way into the Howler.js library too. From their docs on GitHub: "The default behavior of howler.js is to attempt to silently unlock audio playback by playing an empty buffer on the first touchend event." https://github.com/goldfire/howler.js/ Seems to work as advertised on various Android/iOS tablets I have at hand. But do notice, under iOS 9.1 beta at least, that I still need to play an empty sound (in my case a 0.2 second silent mp3) *before* I play sounds elsewhere in the code just to trigger the touchend unblocking. If I do not do this, on a second touch event both the first and second touch triggered sounds play together. Afterwards it behaves as expected. Cheap work around, but I can live with it for now. Quote Link to comment Share on other sites More sharing options...
alex_h Posted October 9, 2015 Share Posted October 9, 2015 You can generate the silent sound dynamically rather than using an audio file// create empty buffervar buffer = this.context.createBuffer(1, 1, 22050);var source = this.context.createBufferSource();source.buffer = buffer;// connect to output (your speakers)source.connect(this.context.destination);// play the soundif(source.play){ source.play(0);} else if(source.noteOn){ source.noteOn(0);} digitalmouse 1 Quote Link to comment Share on other sites More sharing options...
digitalmouse Posted October 21, 2015 Share Posted October 21, 2015 Sweet, alex_h - have seen that elsewhere, but just getting around to do it programmatically now. Thanks. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.