apache / cordova-plugin-media

Apache Cordova Media Plugin
https://cordova.apache.org/
Apache License 2.0
390 stars 763 forks source link

Live streams (over http, like web radio) don't play on iOS #324

Open bikubi opened 2 years ago

bikubi commented 2 years ago

Bug Report

Problem

What is expected to happen?

new Media('http://example.com/finite.mp3'); plays a sound from the internet, new Media('http://example.com/infinite-radio-live.mp3'); should play a live streaming sound.

What does actually happen?

I see a status update to 2 (MEDIA_RUNNING), but there is no sound.

Information

I've tried different radio stations (servers), protocols (http(s)) and formats (mp3, aac) to no avail.

Command or Code

I have made a Minimal Reproduction Repo, originally in the probably unrelated issue #242 (OP mentions Android): https://github.com/bikubi/cordova-plugin-media-mwe

I have since found the issue and a possible fix: player.automaticallyWaitsToMinimizeStalling has to be true -- which makes sense with live streaming ("let it buffer").
I have implemented it as a proof of concept: https://github.com/bikubi/cordova-plugin-media/commit/591a7772b38e51f5832cb0582a5248caae207587 ...and have my MRR use it in branch hotfix.
I'd fashion a PR, but am not sure where to put my fix (and how, this was my first line of ObjectiveC (?)), especially how to apply it only when the url is a live stream. There's no way to tell by the URL, so I guess it would have to be an extra parameter.

Environment, Platform, Device

Version information

cordova 10.0.0
cordova-ios 6.2.0
cordova-plugin-file 6.0.2
cordova-plugin-whitelist 1.3.5
XCode 13.1 on macOS 11.6

Checklist

bikubi commented 2 years ago

not sure where to put my fix

Maybe as option for play() akin to playAudioWhenScreenIsLocked.
Would fit nicely under iOS quirks, too...

ShaunBrassell commented 2 years ago

Thanks, solved my issue

bikubi commented 1 year ago

I have noticed that my fix above has problems with AirPlay:

With a vaguely related StackOverflow answer I was able to guess a fix:

[avPlayer setAllowsExternalPlayback:NO];

see commit a8527f54edfd8223a291dfb6d3971baa6eb42cc2.

No idea about what this actually does, or if it might have any unintended side-effects.

I've also updated the Minimal Repro repo linked above.

bikubi commented 1 year ago

randomly found out that this was introduced with https://github.com/apache/cordova-plugin-media/pull/149, so it probably broke somewhere between iOS 11 and 12

ddurham2 commented 1 year ago

v6.1.0

I too am getting no playback on iOS when streaming from the network a live stream. This stream I don't believe gives a content length and that may be part of the problem given what the docs say, but I'm not positive.

For now, I'm having to patch the code thusly:

--- node_modules/cordova-plugin-media/src/ios/CDVSound.m.orig   2022-12-16 19:32:41.000000000 -0600
+++ node_modules/cordova-plugin-media/src/ios/CDVSound.m        2022-12-16 19:32:28.000000000 -0600
@@ -272,11 +272,7 @@
             // Pass the AVPlayerItem to a new player
             avPlayer = [[AVPlayer alloc] initWithPlayerItem:playerItem];

-            // Avoid excessive buffering so streaming media can play instantly on iOS
-            // Removes preplay delay on ios 10+, makes consistent with ios9 behaviour
-            if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10,0,0}]) {
-                avPlayer.automaticallyWaitsToMinimizeStalling = NO;
-            }
+            avPlayer.automaticallyWaitsToMinimizeStalling = YES;
         }

         self.currMediaId = mediaId;

... basically reverting this change.

Also, regarding the original reason for the change, it doesn't wait 8-10 seconds in my case.. My guess is that the original complaint was hitting a source that was throttled to just the needed bandwidth, but didn't allow an initial burst of bandwidth to get the process started and buffers filled up.

I'm thinking it needs to be an caller-controlled option, or more careful thought needs to be given to that change.

matias-tecnosoul commented 1 year ago

This seems to still be happening with Cordova 11.1.0 and ios 6.2.0.

I've also tried with the html audio tag but got same problem. Whenever I insert any live audio in my index.html the app freezes when starting.

I tried with iframes and got 1 js player working but not others.

Any hints to make an icecast stream play in ios?

pinguluk commented 3 weeks ago

This seems to still be happening with Cordova 11.1.0 and ios 6.2.0.

I've also tried with the html audio tag but got same problem. Whenever I insert any live audio in my index.html the app freezes when starting.

I tried with iframes and got 1 js player working but not others.

Any hints to make an icecast stream play in ios?

https://github.com/apache/cordova-plugin-media/issues/256