Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fails on Safari (iOS and macOS) for mp3 and m4a tracks around 10-15 minutes long #27

Open
straydogmatagram opened this issue Jan 26, 2022 · 19 comments

Comments

@straydogmatagram
Copy link

When I load tracks that are between about 10 and 15 minutes long, the player fails on these tracks. (These times are not exact. Problems start for tracks a little longer than 10 minutes, and tracks a bit longer than 15 seem to work.) This only happens on Safari on my Mac and on Safari on iOS. It also only happens for mp3 and m4a files -- wavs work fine.

It is easy to reproduce. For example, upload a 12-or-so minute track to the demonstration page here:
https://ccrma.stanford.edu/~regosen/gapless5
On Safari on a Mac, the time shown is truncated to 2 minutes.
I have one iPhone running iOS 15, and it is the same as on my Mac.
On another iPhone still running iOS 14, then the time shown is not truncated but the player stops playing after two minutes.

(Actually Brave browser, Firefox, and Chrome also show this same problem on iOS, but I think they are just using Safari's innards.)

This is with gapless 5 version 1.3.4.

Any ideas for fix or workaround would really be appreciated.

@regosen
Copy link
Owner

regosen commented Jan 26, 2022

Hi, I'm trying it right now on macOS safari with a 60-minute .m4a (stereo 256 kbps) file and so far it's playing fine and I'm 25 minutes in. I have a couple questions:

  1. What exactly happens when it fails? Does it play for 10-15 minutes and then go silent?
  2. Any errors in the JS console?

@straydogmatagram
Copy link
Author

It also works for me for long files. It is only when they are between about 10 minutes long and 15 minutes long that there is a problem. Do you have one in that range to test?

Here is what happens:

On Safari on a Mac: The play does not show the correct duration, but something about 10 minutes less. For example, if the track is 12 minutes long, the player shows it as 2 minutes long. The first two minutes play, and then it advances to the next track.

On Safari on iOS 15, it is the same as above.

On Safari on iOS 14, the play shows the correct time (12 minutes) but after 2 minutes it goes silent.

Try it with a 12 or 13 minute file.

@straydogmatagram
Copy link
Author

This should allow you to reproduce the problem easily. Here is a track that is 12 minutes and 6 seconds.
https://cloud.grwelch.com/index.php/s/aqEcNDzceZJseHb

This is an ordinary 44.1 kHz, 2 channel, 128 kbps, aac encoded track. Afinfo on a Mac shows the time as 726.07 seconds (12:06). You can download this file to test.m4a.

Now go to this demo page for Gapless-5:
https://ccrma.stanford.edu/~regosen/gapless5/

Using the file upload button at the bottom, upload test.m4a. On Safari, you will see that instead of showing the duration as 12:06, it is shown as 1:57. If you click play, it stops after 1:57. Other browsers on a Mac work correctly. No browsers (afaict) on iOS work correctly.

I don't see anything untoward on the javascript console.

@regosen
Copy link
Owner

regosen commented Jan 26, 2022

Thanks for the details and the link to the track- if only all GitHub issue postings were of this quality! :chef_kiss:

That being said, below is a screenshot of your track after playing for a few minutes through the same demo page- using Safari 15.2 on macOS Monterey (12.1).

This is quite an odd issue- normally I'd suspect you're low on memory or something, but as you said it doesn't happen with longer tracks (or with WAV files no less).

If you have a local setup, can you try constructing the Gapless5 object with either of these options set to false?

  • useWebAudio
  • useHTML5Audio
    I'm curious if setting either to false would fix this for you.

Screen Shot 2022-01-25 at 8 31 32 PM

@straydogmatagram
Copy link
Author

First, thank you for responding so quickly. I really appreciate the help! Yes, this is very frustrating.

To simplify things, I have created a test page here. This page is very simple; it just loads the player with test.mp4 as the sole entry in the play list. I've attached some screenshots in my follow-up.

On Firefox, it loads correctly and shows the correct track time of 12:06. It also plays all the way through. On Safari on either Mac or iOS, the track time shown is truncated to 1:57, and only plays for 1:57.

I also don't think it is a memory issue, because my Mac has 32 GB of ram. But anyway, you can't change your ram in your iPhone. And yes, it works for tracks longer than about 15 minutes, and also with wavs.

As to your question, setting useWebAudio: false does "fix" this problem. That is, the track loads correctly and play all the way through. But this is not really a fix, beause the entire point of the exercise is to get gapless playback and this setting causes a gap after every track.

Setting useHTML5Audio: false has no affect.

@straydogmatagram
Copy link
Author

Using the test page mentioned above:

On Safari on a Mac, this is what I see:
mac
Note that the track duration is not correct: It is showing 1:57. This happens not only on my machine, but every Mac I have tested it on, running Monterrey and Big Sur. Again, the problem is only on Safari, not other browsers.

On my iPhone, I see this:
iphone
Again, you see the track time is 1:57. I have tested this on my wife's iPhone, a friend, and my nextdoor neighbor, and all see the same thing as me.

The behavior is the same on iOS under Firefox, Brave, and Chrome.

I do have an older iPad running iOS 14, and on it the track time is shown correctly. However, the music stops playing (goes silent) after 1:57.

@straydogmatagram
Copy link
Author

straydogmatagram commented Jan 26, 2022

It is very frustrating that this works for you, yet for me it fails on Safari on every machine I try, including those of friends and family. Do you have an iPhone to try it on? I am not sure how much time you want to spend on it, but I would love to use your player in a project and I would be happy to perform any further testing you would like to suggest.

Frankly, I'm much more interested in iOS than Mac. However, I suspect that whatever problem is at the root here is common to both.

I fear that we have uncovered a bug in how Apple implements Web Audio. But if there is something in your library that could be fixed, that would be fantastic for me.

@regosen
Copy link
Owner

regosen commented Jan 26, 2022

Oh interesting! I'm able to reproduce it now on my iPhone. And on macOS Safari it shows the full duration but went silent after a few seconds... though that only happened once.

Would you mind updating your page such that the Gapless5 constructor options includes logLevel: LogLevel.Debug ?

@straydogmatagram
Copy link
Author

Done! I added that line in the constructor. But where is the log?

I have to run off to some meetings right now, so it will be some hours before I can check back here. Thanks again so much for looking at it!

@regosen
Copy link
Owner

regosen commented Jan 26, 2022

Oh the option keys are case-sensitive. I see you did this:

const player = new Gapless5({
	guiId: 'gapless5-player-id',
	LogLevel: LogLevel.Debug,
});

But that last line needs to be this:

	logLevel: LogLevel.Debug,

Then you should see information under Develop -> Show JavaScript Console

@straydogmatagram
Copy link
Author

Sorry! Just changed it. Does this tell you anything?

@regosen
Copy link
Owner

regosen commented Jan 26, 2022

Thanks for this. I see on iPhone we're calling decodeAudioData with data of the correct size, but for some reason decodeAudioData's callback is being called with truncated decoded data.

I think there's something wrong with the file itself that other players are able to handle but not Safari. As a test, I re-converted test.m4a using the Apple Music app, and now it plays fine on my iPhone.

Re-exported file: https://ccrma.stanford.edu/~regosen/gapless5/test-reexport.m4a
Test with new file: https://ccrma.stanford.edu/~regosen/gapless5/bug.html

So I wonder how you're converting these files to mp3 and m4a, and if there's some setting in there that isn't playing nicely with Safari.

@straydogmatagram
Copy link
Author

Man, this is really tough.

Perhaps we are making progress, but this is not solved. While the track you encoded does work on my Mac in Safari, it does not work on my iPhone. I tried my wife's iPhone too (a different model but same iOS version), and it has the same behavior as before (track time showing 1:57 instead of 12:06). This is the same using my test site with your re-encoded file, and also with your test site. I will contact friends and ask them to try it on their iPhones too. What iOS version do you have? I have what seems to be the latest: 15.2.1.

So, progress, but no win.

For what it's worth, I encode all my files with Apple's own tool, afconvert:
afconvert file.wav -d aac -f m4af -b 256000 -q 127 -s 2 file.m4a
(Note, I used 128k for the test track. No difference with 256k.) They play fine (and gaplessly) in Apple's music apps on the Mac and on the iPhone.

I see the same problem with mp3 as well. I encode those with lame:
lame -v -q 1 -V 0 file.wav file.mp3

Running afinfo on my file and also on yours, they are not very different. Yours has a bit different bit rate, and also has sound-check info. Can you tell me how you made it?

I will play around with other conversion options, and also try using fdk-aac instead of Apple's stuff to see if it makes a difference.

@straydogmatagram
Copy link
Author

Oh man. I refreshed your test page in Safari on my Mac, and now it is no longer working.

I also got a friend across town to try it on her iPhone, and it's the same as mine. No glory :-(.

@straydogmatagram
Copy link
Author

Progress!

I tried re-encoding the file with fdk_aac. It works! Both on the Mac and on the iPhone. I tried my wife's iPhone and also my friend, and both play the whole 12 minutes!

You can find the re-encoded file here.

You can run my test site with it in the same place as before.

I am now re-encoding a lot of tracks to run more tests. I will keep you posted.

It is absolutely stunning that Apple's browser fails which Apple's encoder, but works using open source stuff.

Thanks again for bothering! I wish there was a way I could pay the project back, but I'm not much for javascript. I'm pretty good server-side, but JS seems hard to wrap my head around.

@regosen
Copy link
Owner

regosen commented Jan 27, 2022

I'm glad to know that fixed it, such a weird bug!

If you create a cool site that uses this player, I'd be happy to link to it in the Gapless 5 readme under Demos, let me know.

@straydogmatagram
Copy link
Author

Unfortunately there are still problems. Sometimes (it seems random) the player just stops. The timer keeps going up and the scrobbler keeps advancing, but no sound. This happens by far the most after loading, but not always, and sometimes just during playback. Often if I switch from Safari to another app, and then back to Safari, the player will keep advancing but no sound.

I've found some tricks to get the sound back: jumping between tracks sometimes works, and loading a YouTube video in another tab seems to always cause this player to start making sound again.

Unless you have any other ideas, I will keep playing with different encodings. Very frustrating that Safari is so pathetic for decoding aac.

I have high hopes for this. One thing I can say for your player is that the gapless playback is perfect. And that's really hard to find these days.

@regosen
Copy link
Owner

regosen commented Jan 27, 2022

I wonder if it happens when switching from HTML5 Audio to WebAudio. Does it go away if you initialize with useHTML5Audio: false ? It's not needed for gapless playback, but it would allow you to start a track a little sooner.

@straydogmatagram
Copy link
Author

Sadly, that has no (discernible) affect on the problem. I think it's bound to be that the encoding is still not quite something Safari can handle. For example, in one folder of 27 songs, there was still one track where the duration showed up wrong, although it is mostly always right now.

It seems really weird to me that Safari is so much less robust with aac encoding than the Music app (which has no problem with any of these files).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants