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.
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):
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
audio_service plugin as well as the audio_session.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.
I am keeping this open for the reason stated above.
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/dooboolab/flutter_sound/search?q=opus&type=code
@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.