scottschiller / SoundManager2

A JavaScript Sound API supporting MP3, MPEG4 and HTML5 audio + RTMP, providing reliable cross-browser/platform audio control in as little as 12 KB. BSD licensed.
http://www.schillmania.com/projects/soundmanager2/
Other
4.97k stars 772 forks source link

Problem playing a song, requested from the server, on IOS: dynamic audio tag creation using new Audio() to play song won't work on IOS #147

Open mhdSid opened 7 years ago

mhdSid commented 7 years ago

Mobile browsers have always had problem when it comes to playing audio files in the browser. Both Chrome & Safari state that a user interaction event - click event - must occur for an audio file to be in the playing state.

Any Http request should occur in the same 'stack frame' of the click event.

When using Chrome on Android, we tried to request a URL from the server, to give it to SoundManager 2 that creates an

What we thought of might solve this problem was to play a local blank mp3 file, and once we receive a response from the server, we switch with the new requested one.

This worked on Android but did not work on IOS.

mhdSid commented 7 years ago

what also worked updating soundManager2 APi to support writing the audio tag in HTML and feed it to soundManager instead of creating audio tag dynamically

mhdSid commented 7 years ago

Currently updating SoundManager2 to support creating html

scottschiller commented 7 years ago

This is interesting, thanks. Can you expand a bit on the difference in creating and inserting an <audio> element in the DOM? Does that somehow let mobile devices do auto-play, or what have you?

Additionally, I'm curious to know if there is a difference between the following:

var a = new Audio();
var a = document.createElement('audio');
var a = document.body.appendChild(document.createElement('audio'));

It would be preferable from my point of view, to avoid having an <audio> element attached to the DOM because user scripts might remove or mess with it.

marksalvatore commented 7 years ago

Please remove me from this list. The unsubscribe feature doesn’t appear to do the job. Thank you!

On Jan 29, 2017, at 12:50 PM, Scott Schiller notifications@github.com wrote:

This is interesting, thanks. Can you expand a bit on the difference in creating and inserting an

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/scottschiller/SoundManager2/issues/147#issuecomment-275931869, or mute the thread https://github.com/notifications/unsubscribe-auth/ABxtfhNIwOiPobEWwpDn00geh9ITm9d0ks5rXNFMgaJpZM4Li-NA.

scottschiller commented 7 years ago

@marksalvatore Sorry, I'm not sure if I can unsubscribe you - but on the web version of GitHub, I do see an option I can click to unsubscribe myself from this conversation.

I'd expect GitHub would provide an unsubscribe link in the email, but also on the web version where this conversation lives. Worth a look if you haven't already. Let me know if nothing else works.

marksalvatore commented 7 years ago

Will do. Thanks Scott!

On Jan 29, 2017, at 12:55 PM, Scott Schiller notifications@github.com wrote:

@marksalvatore https://github.com/marksalvatore Sorry, I'm not sure if I can unsubscribe you - but on the web version of GitHub, I do see an option I can click to unsubscribe myself from this conversation.

I'd expect GitHub would provide an unsubscribe link in the email, but also on the web version where this conversation lives. Worth a look if you haven't already. Let me know if nothing else works.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/scottschiller/SoundManager2/issues/147#issuecomment-275932256, or mute the thread https://github.com/notifications/unsubscribe-auth/ABxtflMFiYFKX39tU_3N4c18tye-FfG7ks5rXNKSgaJpZM4Li-NA.

mhdSid commented 7 years ago

Hello Scott, On mobile devices, browsers only play a song if it's initiated in a user gesture event.

Soundmanager creates the audio tag dynamically, mobile browsers, unfortunately, will throw an error playing the song: "failed playing audio, the call to play should be initiated from a user gesture event".

By creating the audio dynamically, the browser waits 100 ms for the song to be played, and once crossed, thinks it is being loaded out of the stack frame of the click event, and creates a vital obstacle that needs to be solved.

After a lot of trials and researching for a solution, I found that I can play a blank mp3 and once I get the HTTP response for the song URL, I can replace the blank mp3 URL with the new URL, but still the browser throws the same error.

Took one more week to think more about it, so I tried creating the audio in the DOM, a kind of browser hack, and the blank mp3 tried replacing the blank mp3 and the new song played on both android and ios. Without playing a local mp3, this won't work. The solution for this is to create ausio in the DOM, play a bpank mp3, and replace the soundobject URL with a URL from a server.

Plus autoplay and autoload both don't work on android and ios, so I had tocuse the soundobject.play() and load() methods.

Cheers On Jan 29, 2017 7:50 PM, "Scott Schiller" notifications@github.com wrote:

This is interesting, thanks. Can you expand a bit on the difference in creating and inserting an

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/scottschiller/SoundManager2/issues/147#issuecomment-275931869, or mute the thread https://github.com/notifications/unsubscribe-auth/ALV3zB1lHRoq14jjs4lcUkUWlsXSmXP1ks5rXNFPgaJpZM4Li-NA .

mhdSid commented 7 years ago

This article talks well about the state of HTML5 audio. ✌

mhdSid commented 7 years ago

http://pupunzi.open-lab.com/2013/03/13/making-html5-audio-actually-work-on-mobile/

scottschiller commented 7 years ago

@mhdSid: Thanks for the details - I've known about mobile playback restrictions and auto-play, but I have not seen the specifics of the user gesture event error before; that sounds like a new thing (and good, so developers know why the attempt failed.)

I am assuming in this case, a click is still required to load and begin playback of sound on mobile regardless of the technique used.

I'm not sure I understand the benefit of creating and appending <audio> to the DOM and the blank/local MP3, vs. what SM2 has presently. Maybe I'm missing something.

I'd expect, then,

document.onclick = function() {
  var a = document.createElement('audio');
  document.body.appendChild(a);
  a.src = 'local/blank.mp3'; // ??
  // what happens after this point?
  // is this any different than var a = new Audio();?
  a.play(); // this should work regardless, because it's in an onclick()
}

I would expect that if from within a click handler, I should be able to create an Audio() or <audio> or reference an existing instance of either object, and immediately be able to load or play an existing or new URL.

When responding to touch or click, you should be able to load or play any URL using SM2 as it is today because it tries to do this work immediately / within the same gesture/event / call stack. Am I missing something?

Your note about the 100msec bit is interesting, maybe that's the rub. As far as I have found, SM2 has no problem creating and playing a sound from a touch or click on mobile. If you can reliably reproduce an issue with one of the demos on the website, etc., do let me know (and what device / OS) it's happening on.

Provided that you assign .src and call play() within the click event handler, you should be allowed to play it. If you are using SM2 and calling load() -> onload() -> play(), that is not guaranteed to work in the mobile world given the asynchronous nature.

mhdSid commented 7 years ago

@scottschiller : After final trials today and reassuring the point of your example, SM2 was able to play any local mp3 file on both Android & IOS using just the createSound.

Loading a URL from a rest API then playing the desired song URL didn't work; so a workaround was to play a local blank.mp3 file to make the browser think it's playing a local file), and once the response is here, we pause, switch the blank.mp3 sound's URL with the new desired URL, and play again.

We have an angularPlayer service that initialises the HTML5 player where we set up the soundmanager default options, onLoad method, onReady, etc..

What we also need is to set up our SM2 default options and methods. Let's say we have to call the function that initialises our sm2 options and methods, we still have a problem with IOS... if we also call the function that initialises sm2 options from the click method, it also won't work, without any error such as the call to play should be initiated from a user gesture. It shows the loading in iphone bar, but it doesn't play the file. However, it plays on Android.

That's why I finally tried using an existing DOM audio element, and that solved the matter... The problem seem to be that if the audio is in the dom, the browser can link to it, but seems to be that the object created using new Audio() is being lost somehow...

pallavi1993 commented 5 years ago

Hi all,

I ran into a big trouble. I am using react-sound npm for creating a music player. it works fine with chrome but coming to safari it asks for user interaction. I am providing the user interaction thtough mouse but am still not able to resolve the issue. Also the music loads but goes to suspended state and i cannot listen to anything.

@scottschiller

Please check the following link in safari and help me . http://18.234.38.144

mhdSid commented 5 years ago

Dear Scott,

After having troubles with SoundManager I decided to create Galatic the company I work at Anghami. We still rely on SM2, however, soon, we're migrating to the new player. @scottschiller

scottschiller commented 5 years ago

@mhdSid Thanks for the note! Ideally, I'd like to see people move away from SM2 and over to raw JS and HTML5 for playback. I think we're getting closer to that, but mobile browsers and playback restrictions now coming to desktop mean that I think there's some value in HTML5 audio libraries in normalizing events, working around the occasional bug and so on.

Thanks for using SM2 and your occasional bug report and feedback in the meantime, I appreciate it.