cordova-plugin-media icon indicating copy to clipboard operation
cordova-plugin-media copied to clipboard

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

Open bikubi opened this issue 3 years ago • 7 comments

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

  • iOS 15.1 on iPad
  • 12.3.1 on an iPhone SE
  • 15.0 in an iPhone 13 emulator.

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

  • [x] I searched for existing GitHub issues
  • [x] I updated all Cordova tooling to most recent version
  • [x] I included all the necessary information above

bikubi avatar Dec 15 '21 20:12 bikubi

not sure where to put my fix

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

bikubi avatar Dec 16 '21 13:12 bikubi

Thanks, solved my issue

ShaunBrassell avatar Feb 26 '22 14:02 ShaunBrassell

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

  • play the stream, connect to an AirPlay receiver — receiver plays the stream as expected
  • but, when you enable AirPlay and "pre-connect" to a receiver, and THEN star playing, there is no sound (MEDIA_RUNNING but no progress)

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 avatar Aug 30 '22 16:08 bikubi

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

bikubi avatar Aug 31 '22 11:08 bikubi

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.

ddurham2 avatar Dec 17 '22 01:12 ddurham2

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?

matias-tecnosoul avatar Feb 24 '23 02:02 matias-tecnosoul

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

pinguluk avatar Jun 06 '24 10:06 pinguluk