Code Monkey home page Code Monkey logo

Comments (19)

zohararad avatar zohararad commented on September 25, 2024

@franz976 I think the obstacle here is that interacting with the Audio element on mobile requires explicit user interaction.

Maybe the solution is to stream your playlist using something like Shoutcast rather than try to load new files on end. I realise its annoying but it's a limitation of the mobile platforms rather than Audio5js.

Just as a side-note, Audio5 works nicely with Shoutcast (was one of the original purposes for which I built the library)

from audio5js.

franz976 avatar franz976 commented on September 25, 2024

Thanks @zohararad. I wonder what kind of player use the folks at http://www.indieshuffle.com, cause it's pretty the same thing I want to reach...

from audio5js.

zohararad avatar zohararad commented on September 25, 2024

From a quick peak at their code, they have their own HTML5 player (I think). Maybe they found a way around the auto-play issue on mobile

from audio5js.

pteich avatar pteich commented on September 25, 2024

Indie Shuffle uses SoundManager 2 (http://www.schillmania.com/projects/soundmanager2/)
The problem with Audio5js probably is that on every load of a new file it destroys an existing audio object and creates an new one. This is necessary for playing streaming media (Icecast/Shoutcast) otherwise some browsers won't stop loading data of the old stream if you switch to a new one. (I use Audio5js just like @zohararad to play Icecast mp3 streams and ran into this.)
But this recreation of audio objects seems to trigger iOS to request user interaction on every new file load. Sound Manager 2 maybe re-uses an existing audio object.

from audio5js.

zohararad avatar zohararad commented on September 25, 2024

@pteich that might be a very valid insight. I'll try and see if I can re-use the audio object

from audio5js.

ErikAGriffin avatar ErikAGriffin commented on September 25, 2024

@zohararad , @pteich
Yes I'm very glad you fixed this with Audio5js. Playing through a playlist on mobile browsers is possible by swapping out the source of the audio after a click event has initiated play() (as described in this stack answer). It works amazing.

However I have run into a new problem, which can hopefully be solved. I am not yet familiar enough with Audio5 to investigate on my own. If one of the song steam url's fails to load, thus triggering the 'error' event, the auto / continuous play stops working. Are you destroying the audio object on error? Here is my app's current flow:

Click play event -> song ended -> load(newUrl) -> play() ...
load(newUrl) -> fails -> errorEvent -> load(newUrl) -> play()...

Again, after the error event the audio does not play on mobile, but works fine in the browser. Furthermore (not sure how related this is) my object.playing reports true (even though no sound is playing), and calling object.pause() has absolutely not effect (the state of object.playing remains true).

from audio5js.

zohararad avatar zohararad commented on September 25, 2024

@ErikAGriffin looking at the code again, the audio object isn't destroyed on playback / load errors. The behaviour is to escalate the error to the implementation where it should be handled.

There is a config setting that controls whether the error is thrown or not ( see L994 )

I'd try to first check whether an error is thrown and not caught, which might explain the breakage. I'm not familiar enough with mobile browsers internals to confirm if an audio load error might break the "legitimate click event cycle", but perhaps the solution would be to simply display a notification to the user that the audio cannot be loaded and that they should click to continue

from audio5js.

ErikAGriffin avatar ErikAGriffin commented on September 25, 2024

Hm my throw_errorsproperty is false, so I just have the object.on('error') function I am working with. Is there something specific I may need to be doing within that function?

Unfortunately the whole purpose of my application is that someone would be far away from their phone, so having to go and click play again at unknown intervals is not a real option. One fix I have considered is having a separate player object that attempts to load all songs before they are actually loaded into the player which receives the click event. If the secondary player object gets an error, it sets a boolean that causes the active player to not attempt to load that song.

Not perfect and may not work, but just my thoughts. Also thank you for the prompt reply, really liking this library so far

from audio5js.

ErikAGriffin avatar ErikAGriffin commented on September 25, 2024

So tinkering around today with raw HTML5 audio, when an error event was triggered I was able to load and continue autoplay on mobile Safari no problem, so it is something within Audio5js that is causing this to break. I'll continue investigating @zohararad

from audio5js.

zohararad avatar zohararad commented on September 25, 2024

@ErikAGriffin thanks. I'll look forward to hearing if you found anything

from audio5js.

pteich avatar pteich commented on September 25, 2024

I know that it's really a pain to get that audio thing right on mobile devices. I had to put a lot of afford in this. What works for me for your specific issue is something like this (stripped down to only interesting parts):


        var audio5js;

         audio5js = new Audio5js({
                throw_errors: false,
                ready: function () {
                    this.on('error', function(err) {
                        console.log(er.message);
                        playFile(url);
                    });
                }
            });


        function playFile(url) {

            audio5js.one('canplay', function () {
                audio5js.play();
            });

            if (audio5js.playing) {
                audio5js.one('pause', function () {
                    audio5js.load(url);
                });
                audio5js.pause();
            } else {
                audio5js.load(url);
            }

        }

First play is of course triggered by e.g. a button that executes playFile(). But if an error occurs after this, it plays a new url without forcing the user to interact again. Not sure, if this helps you.

from audio5js.

ErikAGriffin avatar ErikAGriffin commented on September 25, 2024

Although I do not fully understand the structure of Audio5js, through an extensive amount of logging I was able to return the functionality desired above on mobile safari after adding just a single line of a code to the audio5.js source. However before I submit a pull request, I have a question:

Why do events trigger for both the html5 player object in the Audio5js object (aka myAudio5obj.audio) AND the Audio5js object itself? Why two whole sets of event listeners? Secondly, and this is more curiosity, why do both objects have a .playing property? It seems to me that only the Audio5js object's .playing property gets used.

@zohararad

EDIT: Furthermore how do I go about submitting a pull request? Do I just edit the file in src/ and then you will update the build and minified build in the home directory?

from audio5js.

zohararad avatar zohararad commented on September 25, 2024

@ErikAGriffin

Thanks for digging through the code. The idea behind events in Audio5 is that the escalate from the Audio engines (HTML5 / Flash) to the Audio5 object which you instantiate. That's why there's a chain of events.

If you want to submit a PR, please fork the repo, add your code, push to your GH account and then send a PR via Github. Please make sure the tests pass if you can.

from audio5js.

ErikAGriffin avatar ErikAGriffin commented on September 25, 2024

Hmm I was unable to run grunt as the uglify build task threw a warning: Warning: Cannot assign to read only property 'subarray' of ... then shows the entire minified code. However trying the same on a cloned repo of the original achieved the same result, so perhaps I have not set something up correctly.

However I did run Mocha tests by opening the tests.html and everything passed. Submitting the pull request now

IMPORTANT EDIT:
@zohararad Actually don't merge my pull request yet. I came to my solution by noticing on successful song ends that the html5 onPause is triggered before even onEnded. Therefore I simply trigger('pause') from there onError function and it worked. However now I noticed that when trying to employ a skip functionality I was running into the exact same issue as the mobile error issue. Loading a new song while one is playing, even if you call myAudio5object.pause() before causes this issue to occur. Therefore I've moved the trigger('pause') to the html5 load(url) function thus solving both issues.

But where is the initial onPause being triggered from when a song ends without error or interruption? Perhaps that is a more suitable location to solve this problem than from within the html5 object load(url) function. Or perhaps best is the Audio5js object load(url) function, I'm just not quite sure where best to put the trigger.

from audio5js.

zohararad avatar zohararad commented on September 25, 2024

@ErikAGriffin please delete irrelevant PRs and resend the latest PRs so there's no mixup

from audio5js.

ErikAGriffin avatar ErikAGriffin commented on September 25, 2024

@zohararad Done and done.

from audio5js.

zohararad avatar zohararad commented on September 25, 2024

Thanks. Merged

from audio5js.

ErikAGriffin avatar ErikAGriffin commented on September 25, 2024

This is still only merged in the /src and not on the root release and minified build @zohararad

from audio5js.

zohararad avatar zohararad commented on September 25, 2024

@ErikAGriffin sorry about that - built and pushed

from audio5js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.