just_audio icon indicating copy to clipboard operation
just_audio copied to clipboard

Webm not playing on iOS

Open newdev8 opened this issue 3 years ago • 10 comments

Which API doesn't behave as documented, and how does it misbehave? So my app gets links dynamically, some are webm files from YouTube (I don't know if this matters but when you try to preview the url it forces the download of the file). The name of the file is always videoplayback, no extension or nothing.

An example of the url is: https://r1---sn-8vq54voxn25po-cjoz.googlevideo.com/videoplayback?expire=1604559693&ei=7U6jX9m4CaSPxN8PyviTmAQ&ip=31.4.243.97&id=o-ADdpFkAM7rsg_VijJ5hWunLORlKBsLpT_xU2JS16vW44&itag=251&source=youtube&requiressl=yes&mh=Si&mm=31%2C29&mn=sn-8vq54voxn25po-cjoz%2Csn-h5q7dnlk&ms=au%2Crdu&mv=m&mvi=1&pcm2cms=yes&pl=24&initcwndbps=818750&vprv=1&mime=audio%2Fwebm&gir=yes&clen=3422454&dur=200.021&lmt=1599850528510078&mt=1604537912&fvip=1&keepalive=yes&c=WEB&txp=5511222&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cgir%2Cclen%2Cdur%2Clmt&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpcm2cms%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgRhFhyxsVHEdiRIAJOtufcOgKfKDTJY3Te__Q6VN1wc4CICaj_i0bTmNsBIpZKe99rHG5ciV2p4GjVEn9bO0zsm17&sig=AOq0QJ8wRAIgFghKnxbY_freCTvMuq1d5ujBiigxh7HH6-rYYRf5RnUCIFotwdQqQM0Z6-tj6QKmkTAvh0Ive5hF0wg8WM_qKYHH

Minimal reproduction project I've created a function inside the AudioPlayerTask class that fetches the url before playing it:

String _url = myurl;
int _closest = urlTiming;
// Here we get the current mediaItem from the class to update it
trackMetaData = mediaItem;
      // Here I set the url and the duration in the player
      _player.setUrl(_url).then((dur) {
        trackMetaData = trackMetaData.copyWith(
          duration: Duration(milliseconds: _closest),
        );
        // Here I update the mediaItem object
        AudioServiceBackground.setMediaItem(trackMetaData);
        _player.setAutomaticallyWaitsToMinimizeStalling(false);
      });
      // Here I pre-load the audio
      await _player.load(ConcatenatingAudioSource(
        children:
        queue.map((item) => AudioSource.uri(Uri.parse(_url))).toList(),
      ));
      _player.play();
  }

To Reproduce (i.e. user steps, not code) The user clicks on a button and then it calls onCustomAction that then runs the upper code.

Error messages

[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: PlatformException(abort, Connection aborted, null, null)
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: PlatformException(abort, Connection aborted, null, null)
flutter: #0      AudioPlayer._load (package:just_audio/just_audio.dart:498:9)
<asynchronous suspension>
#1      AudioPlayer.load (package:just_audio/just_audio.dart:456:30)
#2      AudioPlayerTask.getTrack (package:lainke_music/functions/music.dart:137:21)
<asynchronous suspension>

This upper line makes reference to the .load function I've put in the "minimal reproduction project" part.

#3      AudioPlayerTask.onCustomAction (package:lainke_music/functions/music.dart:85:15)
<asynchronous suspension>

This upper line makes reference to the whole function in the "minimal reproduction project" part.

#4      AudioServiceBackground.run.<anonymous closure> (package:audio_service/audio_service.dart:1319:42)
#5      MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:430:55)
#6      MethodChannel.setMethodCallHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:383:34)
#7      _DefaultBinaryMessenger.handlePlatformMessage (package:flutter/src/services/binding.dart:283:33)
#8      BinaryMessages.handlePlatformMessage (package:flutter/src/services/platform_messages.dart:58:29)
#9      _invoke3.<anonymous closure> (dart:ui/hooks.dart:280:15)
#10  <…>
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: PlatformException(-11828, Cannot Open, null, null)
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: PlatformException((-11828) Cannot Open, null, null, null)
#0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:582:7)
#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:159:18)
<asynchronous suspension>
#2      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:332:12)
#3      AudioService.customAction (package:audio_service/audio_service.dart:1064:27)
#4      updateQueue (package:lainke_music/functions/music.dart:351:22)

This upper line makes reference to "onCustomAction" function which calls the function I've put in the "minimal reproduction project" part.

#5      playTrack (package:lainke_music/functions/handlers.dart:32:9)
#6      trackHorizontalList.<anonymous closure>.<anonymous closure> (package:lainke_music/widgets/widgets.dart:72:29)
#7      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:183:24)
#8      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:598:11)
#9      BaseTapGestureRecognizer._checkUp (package:flutter<…>

Expected behavior The url should play as it does on Android.

Screenshots Not necessary.

Smartphone (please complete the following information):

  • Device: iPhone SE – 2nd generation (Simulator) it doesn't work on a real iPhone (6s Plus) either.
  • OS: 14.1 (also on the physical iPhone).

Flutter SDK version

[✓] Flutter (Channel stable, 1.22.3, on Mac OS X 10.15.7 19H2, locale es-ES)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 12.1)
[!] Android Studio (version 4.1)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.

These both upper lines are a bug as I do have the plugins installed for Android Studio.

[✓] Connected device (1 available)
    ! Error: Apple TV is busy: Waiting for Device. Xcode will continue when Apple TV is finished. (code -10)

This upper line is a bug because I'm also working on an Apple TV app.

! Doctor found issues in 1 category.

Additional context

  • It does work on Android.
  • I can't change the file name.
  • I always know the extension beforehand.
  • I'm using the audio_service plugin as well as the audio_session.

newdev8 avatar Nov 05 '20 01:11 newdev8

The iOS APIs unfortunately don't support all codecs, particularly ones associated with Google ;-)

I'll leave this issue open, since theoretically this is possible to implement (e.g. OGVKit).

However, in the meantime, you might try requesting the audio from YouTube in a different format (assuming you have a license to use YouTube in this way), or using a server-side solution to transcode audio formats that iOS's libraries don't support.

ryanheise avatar Nov 05 '20 02:11 ryanheise

I am keeping this open for the reason stated above.

ryanheise avatar Nov 19 '20 01:11 ryanheise

youtube webm file using the opus format. The voice performance of opus is much better than MP3, and the file is half smaller. It is strongly recommended to support playing OPUS, thank you.


https://github.com/sbooth/SFBAudioEngine FLAC, Ogg Opus, and MP3 are natively supported by Core Audio, however SFBAudioEngine provides its own encoders and decoders for these formats.


https://github.com/ap4y/OrigamiEngine/blob/0bbdc3c5344b631e039a67a0aff481746e1aded3/OrigamiEngine/Plugins/OpusFileDecoder.m


https://github.com/dooboolab/flutter_sound/search?q=opus&type=code

zxl777 avatar Dec 23 '20 09:12 zxl777

@zxl777 thank you for the useful link. While this isn't at the top of my priority list, it is helpful to collect useful resources here so that someone can eventually take up the challenge using one of these libraries.

ryanheise avatar Dec 23 '20 10:12 ryanheise

Has this been resolved with the recent addition of webm to safari in iOS 15?

Coronon avatar Jul 14 '22 22:07 Coronon

I now serve different formats of audio for iOS/Android separately.

zxl777 avatar Jul 15 '22 00:07 zxl777

Doesn't seem to work still, at least with webm with the VP9 codec. The same video works on Android though.

banool avatar Feb 26 '23 16:02 banool

Any update over .webm it's still not working with only iOS.

GujjuFlutterGuy avatar Jun 26 '23 10:06 GujjuFlutterGuy

To those who are asking whether I have implemented this yet, please read my previous comment. It is an open invitation for someone who is sufficiently motivated to have this feature to become a project contributor.

It is not a particularly high priority for me personally, I am happy to just use the codecs that Apple wants me to use. Apple has started to support WebM in small ways in the past couple of years, but as for iPhone, I will leave Apple's decisions up to Apple. This means that content intended for consumption on iPhones will tend to be encoded using codecs that Apple says they officially support.

If someone wants to work around that by putting in the substantial effort to implement the codec manually within just_audio, you are certainly welcome to contribute your efforts back to the project! Although on the other hand, if the audio assets are your own and you exert some control over them, you may want to consider simply re-encoding them for Apple.

ryanheise avatar Jun 26 '23 13:06 ryanheise

any update or work around for this webm?

narakai avatar Feb 01 '24 05:02 narakai

anyone find solution?

s20797 avatar Feb 07 '24 12:02 s20797