goldfire / howler.js

Javascript audio library for the modern web.
https://howlerjs.com
MIT License
23.36k stars 2.21k forks source link

Does not work on iPhone #1093

Closed felinius closed 5 years ago

felinius commented 5 years ago

Hi, I'm not a particularily experienced developed but I've just burned 2 evenings trying to make this work. I could make it play an MP3 file on the latest Safari and Chrome browsers on my Mac triggered by an onclick event - no problem.

But it did not work at all on my iPhone but gave no errors so I guess it never falls back from Web Audio API to HTML5.

I had to use the html5:true option to make it play in the end but I thought the whole reason to use Howler was to not have to worry about these things too much. Or have I confused myself somewhere? I'm surprised no one else has had this issue. Have there been some recent changes to Safari iOS or something? Initially I thought it was due to Apple's strict policy that it must be trigger by a click even but I have no problem with that and was exactly what I was trying to do.

Intrigued to hear other people's responses. Thanks - Chris

goldfire commented 5 years ago

Without seeing a test case of the issue you are having there isn't any way to know what the issue might be. Howler definitely works on iOS, Android, etc, so it would have to be something specific to how you are using it.

felinius commented 5 years ago

No worries. I just set up what I would have imagined would work.

This is uploaded to a https hosting and works on Safari on a MacBook Pro.

It does not work on an iPhone 6S nor an iPhone 8 nor an iPhone XR in Safari with whatever the latest iOS version is right now.

It's very likely I'm doing something completely ludicrous which is why it's not working however I can't quite see it. Thanks!


<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.0.15/howler.core.min.js"></script>
    <script>
        var sound = new Howl({
          src: ['music.mp3']
        });
    </script>
</head>
<body>
    <p><input type="submit" onclick="sound.play()" value="Play" /></p>
</body>
</html>
felinius commented 5 years ago

Hello guys. I was looking at some players that support .mp3 playback on iPhones and came across your app. Tried to test it out using your demo player (1st one with 3 songs in it), but here is the problem I am seeing - 1st song plays fine, iPhone's screen goes to sleep (and lock I assume). Song finishes playing to the end, but 2nd song never starts unless user manually "wakes" the phone and press Play again. Is this expected? I need a solution that allow songs to play non-stop until user taps "Stop" or closes Safari. Could you please advise... Thank You.

You need to open your own thread or contact the developer some other way. I will speculate that what you're seeing is absolutely nothing to do with Howler and is due to the strict rules that Safari imposes i.e. no sound can be played unless initiated by a user action - so that when the first song ends there is no way Safari will play anything else after sleeping until a user action is performed again.

felinius commented 5 years ago

...and to be clear this DOES work on iPhone i.e. forcing HTML5 audio:


<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.0.15/howler.core.min.js"></script>
    <script>
        var sound = new Howl({
          src: ['music.mp3'],
          html5: true
        });
    </script>
</head>
<body>
    <p><input type="submit" onclick="sound.play()" value="Play" /></p>
</body>
</html>
felinius commented 5 years ago

... and yes, we did enable html5: true but it is still stopping after one song playback.

Like I say, I strongly suspect that is enforced by the device.

felinius commented 5 years ago

Thanks Tesdaburys.

So that Demo player that is on the Howler main site is not forcing HTML5?

Pardon the bluntness but do you mind starting your own thread and deleting these replies? Makes no sense to mix this one up. Thanks!

goldfire commented 5 years ago

How large is the audio file?

felinius commented 5 years ago

How large is the audio file?

It's around 800Kb.

goldfire commented 5 years ago

Unfortunately, I'm still unable to replicate the issue you are seeing. Is it still happening with 2.1.0?

felinius commented 5 years ago

Hi James, This [redacted] works on my MacBook Pro. It does not work on any iPhone I've tried unless I forced HTML5 mode.

I would have tried 2.1.0 but the CloudFlare links don't seem to be working.

https://cdnjs.cloudflare.com/ajax/libs/howler/2.0.15/howler.core.min.js works https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.1/howler.core.min.js 404 Not Found nginx

Am I going crazy? Why would the CDN hosted file be down?

Arxi commented 5 years ago

@tesdaburys, I suggest you try to use all the callbacks that Howler offers - e.g. onload, onloaderror, onplayerror, onplay, onend, onunlock - just add them to the config object you pass to new Howl() and write some debug messages directly on the screen, so that you can see what happens. The correct sequence should be something like onload -> onunlock -> onplay -> onend. With this debugging method, I found out my mistake.

Please disregard the rest of my comment. I found out I had my iPhone muted manually with the mute button :). Sorry for that!

~~I have the same problem - a simple demo works in Chromium (Ubuntu) and in Chrome on Android, but not in Safari on iPhone. I use Howler 2.1.1, with Vue, on (admittedly older) iOS 11.4.1. My samples are 114kB .mp3 and 98kB .ogg. (edit: I found out that the .ogg cannot be loaded on iOS as it's not among supported formats)~~ The demo provided by @tesdaburys doesn't work on my iPhone either. I see it's already using Howler 2.1.1 as well. Is there anything I can do to debug the problem?

Arxi commented 5 years ago

Today I found that certain .mp3 files still cannot be played on iPhone. I'd get onloaderror with message Decoding audio data failed.

I used mp3check to check what's wrong with the mp3 and fix it and it now works: mp3check gun.mp3 --error-check - returned "1044 bytes of junk before first frame header" mp3check gun.mp3 --cut-junk-start - fixes the problem

themoonrat commented 5 years ago

@goldfire I wonder if the readme or something could have a link to that mp3check website @Arxi has linked to. A lot of reported issues here end up being issues with encoding! Or maybe / additionally link to the example 'reference' mp3 files; so if there are any problems, devs can check using one of those that we know definitely works!

luckydonald commented 5 years ago

@arxi "Junk at the start" could be something be produced by too big / broken cover art.

emilaron commented 5 years ago

Today I found that certain .mp3 files still cannot be played on iPhone. I'd get onloaderror with message Decoding audio data failed.

I used mp3check to check what's wrong with the mp3 and fix it and it now works: mp3check gun.mp3 --error-check - returned "1044 bytes of junk before first frame header" mp3check gun.mp3 --cut-junk-start - fixes the problem

This is what worked for me!

NAllred91 commented 5 years ago

FWIW I'm having the same issue on my iPhone as well.

I'm using this mp3 to test with here

I'm serving the file on localhost:3001 using Node.js and Express. app.use(express.static(...))

The demos on https://howlerjs.com/ do work on my iPhone.

I also added some hooks to see if I was getting any errors, but onload and onplay are both called as expected and the error handlers are never called.

this.sound = new Howl({
                    src: [this.playingSongId],
                    onplayerror: () => alert('error'),
                    onloaderror: () => alert('load error'),
                    onload: () => alert('load'),
                    onplay: () => alert('playin...'),
                })

And setting html5: true does make it work on my iPhone.

I see that you're setting usingWebAudio to false around here

I don't know what is expected, but webkitAudioContext is defined on my iphone, and I checked that alert( new webkitAudioContext()) shows me an object and alert(new webkitAudioContext().resume) shows me a funcrtion, so I don't think this will set usingWebAudio to false here or mess with autoResume here

NAllred91 commented 5 years ago

Oh....

I keep that little switch on my phone set to keep my ringer on silent. Once I switch that it works without having html5: true.

I keep that set to silent all the time, but I still get audio from my browsers. Not sure why the demo site works and my instance doesn't though..

I installed howler through npm, "howler": "^2.1.2" if thats helpful

levyadams commented 2 years ago

@NAllred91 Oh my god you have no idea how much energy I put into solving this issue. setting the HTML5 flag reduces performance so bad on mobile but I couldnt figure out why everyone on our team with an iphone couldnt hear the sounds.

God I hate you, apple.