I'm using the standard HTML audio tag to play an mp3 file on a webpage. The file is a podcast so it's up to an hour long. Playback is absolutely fine until 33 minutes in. Then it stops, and nothing but a page refresh will get it to start playing again.
So far the problem is only happening on iOS, both Safari and Chrome. Desktop browsers work fine. The files are coming from an Amazon Cloudfront instance so they arrive pretty quick.
At first I thought this may be a connection issue, but I've found that it persists on both 3G and wi-fi connections. I haven't experienced any other issues at all with loading the audio and playing it back, only that it stops at 33 minutes regardless of file size, or time length.
Any help on this matter would be greatly appreciated.
Related
I have an app that uses AVPlayer to play live streams and on-demand video. That in-house app (and recent in-house update) plays video beautifully in all sorts of conditions. Until a user in the company updated to iOS 13.
The same app run under iOS 12 from the same location will work perfect as before.
Now, after a reboot of the phone the first video played will play perfect and if it is a live stream will run for an indefinite amount of time without trouble. The second video played will always play audio only or fail depending on the bit rates available for the video. Even the exact same video.
Quiting and restarting the app makes no difference in the results. Restarting the phone WILL fix it for the next video played.
What appears to be happening is that on the first play, observedBitrate in the event log is correct and the correct bit rate stream is played. The second playback shows observedBitrate starting out an order of magnitude less and no reasonable amount of time sees that rate change significantly.
If the connection is an order of magnitude better than necessary (evidently that is true for most of these users including myself pre-Network Link Conditioner testing), then everything appears to work normally and life is good. What is even stranger, is that on these higher quality connections I don't see the same observedBitrate drop. Also, it appears that video served up from a different ip (but not different domains from same ip) will work once and then fail the second time as if some kind of connection bit rate cache is being used? These last two observations have not been repeated enough to be cast in stone but have been observed more than once.
I've scoured the iOS 13 release notes in hopes that I'm missing some change or need for a new key but nothing strikes me as relevant.
Any ideas appreciated!!!
A very similar question was posted earlier this year Video playback issues only on iOS 13 with AVPlayerViewController and AVPlayer when using HLS video. The unaccepted answer in that question does not apply here (and may not apply there either for all we know). I do wait for StreamPlayerItemStatusObserverContext to change to AVPlayerStatusReadyToPlay.
I have been trying to track this down and there doesn't seem to be a consistent answer. If I have a website that tries to play multiple songs in a row (think playlist) using the HTML 5 audio element, can it continue to work on the iOS lock screen?
For some background, this answer seems to indicate it may be possible. But then this article suggests it is not.
I tried following the closest example of what Apple recommends, as found here, to replicate this. I am using plain, vanilla javascript and HTML, nothing fancy. I copied their example exactly and just substituted the audio tag for the video one, picking two random mp3 songs. All it does is wait for one song to end, then switch the src, load, and play the next track.
When I hit Play on the website, I then lock the iPhone. The first song will play, then stop. It does not continue to the next song.
If the website is open to the page, it will properly transition to the next song. On Android, it will continue to the next song even if the phone is locked.
I tried this with iOS 11 and 12. Neither worked. I have read many differing answers about how javascript is stopped when the website isn't in the foreground, and how iOS requires user interaction to play audio (even going from one song to the next). So it doesn't seem like this would work. But then other answers out there seem to indicate this is possible.
Is there a definitive yes or no? Am I doing something wrong here? Or is it just not possible?
There are multiple issues, which is causing some of the confusion.
First track plays, second does not due to user permission
If the first track was started with user permission, then the only way you can switch to a new track via script is with Apple's recommendation. Handle the ended event and swap in a new src, and call .play() before the callback completes. Otherwise, your code will not have permission to start the new audio.
Cannot get to ended event due to time-constrained source (#t=5,10)
Say you have a 30-second audio file and you tell the browser to only load seconds 5 through 10, via something like #t=5,10 at the end of the URL. When you reach 10, a paused event will fire, not ended. Therefore, it isn't possible to go on to the next track normally, as this event is not "blessed" by Apple to count as a relay of the previous user interaction.
I got around this by having my JavaScript check the currentTime repeatedly, and when it crossed a threshold, seek it to the duration (end) of the file myself. This allows ended to fire normally.
iOS doesn't allow scripts to run after the screen is locked or other apps are in use
This one is a real problem to debug, since it doesn't turn up in any of the simulators. In any case, you're right, your JavaScript is going to get suspended so even if you follow Apple's recommendations, you're out of luck. Or, are you?
A hack... set up a ScriptProcessorNode on a Web Audio context. Set the buffer size to like 512 samples or something. Then, on script process, force a timeupdate event for your Audio Element. This keeps your JavaScript there ticking away. ScriptProcessorNode has to have special privileges here, by its nature.
Apple: If you read this, please fix your browser. It would be great if we didn't have to hack around things to make something as simple as an audio playlist to work. Other browsers don't have nearly this level of problems.
I use AVPlayer to play .MOV videos stored on my dedicated server.
When an user wants to play a video, i load it on AVPlayer using a direct link like this : "wwww.myserver.com/videos/video.mov".
(I don't use php file, maybe i should..)
Generally videos take 1-2 seconds to start playing, but sometimes it can be very slow(until 1 minutes)
However, once the video started, the loading is very quick, but the start can be long, very long (even with fast connection).
Videos are small (maximum 6Mo), i compressed them using SDAVAssetExportSession.
Also I've disabled App Transport Security.
The issue can be server side ? i really don't know how solve this problem
Any help is appreciated
edit 1 : link to video on my server
I'm working in an app where I'm able to play a HLS m3u8 playlist of a streaming radio (audio only) without any problem using an instance of AVPlayer. Using Charles I can see how the playlist is updated properly in a normal pace (each 9-10 seconds, which takes one media segment file). When I perform a seekToTime: (back in time), the player success playing the stream from when I want to, but in Charles I observe how the player starts dowloading a huge amount of media segment files, consuming a lot of data. It seems that the player downloads all the media segment files until that time and then keeps again with the normal behaviour.
I understand that the correct behaviour would be to download the media segment file for the time I'm seeking to, start playing it and then download constantly 1 or 2 media segment files each 9-10 seconds, as it does when I play the stream without timeshift.
My question is if this is a normal behaviour, or if something could be wrong with my m3u8 playlist or the client implementation. Anyone could help me to clarify this?
UPDATED: I can confirm this doesn't happen in iOS 7, so it seems to be a bug introduced by iOS 8.
I've been told by Apple that this is not a bug, but a feature. They've made the buffer bigger since iOS 8.
In my app I use MPMoviePlayerController to play an mp3 file from a web server. This plays while downloading the whole file, which is fine over WiFi. But now I want it to work over 3G (and get it into the app store). How do I get it to just buffer the next 10 seconds or so (as per apple rules)? I'm digging through the documentation on AVPlayer, HTTP Live streaming, etc, but I'm still confused about the best way to do this. With so many podcast apps out there, I'm suprised there aren't more tutorials/libraries about it.
Thanks for your time.
I investigated this as well, and I was not able find a way to limit the look-ahead buffer using MPMoviePlayerController. I believe you would have to load chunks at the network layer and feed them in at the AVFoundation layer, but I have not attempted this myself.
That said, I can confirm that you can get an app approved that plays mp3 files using MPMoviePlayerController over both WiFi and 3G connections. In my app I added a setting so the user can decide whether to enable mp3 downloads over 3G or not, although I don't know if that was needed to get approved. I provided it so users didn't inadvertently incur bandwidth costs.