just_audio
just_audio copied to clipboard
unable to set asset on Android
Which API doesn't behave as documented, and how does it misbehave?
AudioPlayer().setAsset()
on Android emulator is unable to set asset from local file.
Minimal reproduction project https://github.com/riverscuomo/audio-asset-test.git
To Reproduce (i.e. user steps, not code) Steps to reproduce the behavior:
- Run the minimal reproduction project in an Android emulator.
- See the error in the DEBUG CONSOLE.
Error messages
I/ExoPlayerImpl( 7352): Init d9decb9 [ExoPlayerLib/2.15.0] [generic_x86_arm, sdk_gphone_x86, Google, 30]
E/ExoPlayerImplInternal( 7352): Playback error
E/ExoPlayerImplInternal( 7352): com.google.android.exoplayer2.ExoPlaybackException: Source error
E/ExoPlayerImplInternal( 7352): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:624)
E/ExoPlayerImplInternal( 7352): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:594)
E/ExoPlayerImplInternal( 7352): at android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal( 7352): at android.os.Looper.loop(Looper.java:223)
E/ExoPlayerImplInternal( 7352): at android.os.HandlerThread.run(HandlerThread.java:67)
E/ExoPlayerImplInternal( 7352): Caused by: com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, JpegExtractor) could read the stream.
E/ExoPlayerImplInternal( 7352): at com.google.android.exoplayer2.source.BundledExtractorsAdapter.init(BundledExtractorsAdapter.java:92)
E/ExoPlayerImplInternal( 7352): at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1025)
E/ExoPlayerImplInternal( 7352): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:409)
E/ExoPlayerImplInternal( 7352): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/ExoPlayerImplInternal( 7352): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/ExoPlayerImplInternal( 7352): at java.lang.Thread.run(Thread.java:923)
E/AudioPlayer( 7352): TYPE_SOURCE: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, JpegExtractor) could read the stream.
I/ExoPlayerImpl( 7352): Release d9decb9 [ExoPlayerLib/2.15.0] [generic_x86_arm, sdk_gphone_x86, Google, 30] [goog.exo.core]
Expected behavior I expect the local file to be loaded into the player.
Screenshots N/A
Desktop (please complete the following information):
- OS: Windows 11
Smartphone (please complete the following information):
- Device: Android
- OS: 12
Flutter SDK version
[√] Flutter (Channel stable, 2.10.5, on Microsoft Windows [Version 10.0.22000.613], locale en-US)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
X Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/windows#android-setup for more details.
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Build Tools 2019 16.8.4)
[√] Android Studio (version 4.1)
[√] VS Code, 64-bit edition (version 1.66.2)
[√] Connected device (4 available)
[√] HTTP Host Availability
Additional context
I'm using the nature.mp3
from the just_audio repository to eliminate the possibility that there is a problem with my mp3 files.
I have tried just_audio versions:
- 0.9.21
- 0.9.0
- 0.7.1
Works as expected in Chrome. setAudioSource() from uri works as expected Looks like the same bug reported here:
- https://github.com/ryanheise/just_audio/issues/643
- https://www.reddit.com/r/flutterhelp/comments/stm4nb/just_audio_works_on_web_doesnt_work_on_android/
Your repository is empty.
Whoops. I just pushed to code into the repo. Sorry about that.
I just built it on my wife's Mac and it works fine. So it's just Android where I'm having the problem.
having same issue
Works on iOS iPhone simulator, does not work on physical Android Pixel 6 phone.
final player = AudioPlayer();
await player.setAsset('assets/correct.mp3');
await player.play();
I/ExoPlayerImpl(19219): Init 83b2c2e [ExoPlayerLib/2.17.1] [oriole, Pixel 6, Google, 32]
E/ExoPlayerImplInternal(19219): Playback error
E/ExoPlayerImplInternal(19219): com.google.android.exoplayer2.ExoPlaybackException: Source error
E/ExoPlayerImplInternal(19219): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:641)
E/ExoPlayerImplInternal(19219): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:611)
E/ExoPlayerImplInternal(19219): at android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal(19219): at android.os.Looper.loopOnce(Looper.java:201)
E/ExoPlayerImplInternal(19219): at android.os.Looper.loop(Looper.java:288)
E/ExoPlayerImplInternal(19219): at android.os.HandlerThread.run(HandlerThread.java:67)
E/ExoPlayerImplInternal(19219): Caused by: com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, JpegExtractor) could read the stream.
E/ExoPlayerImplInternal(19219): at com.google.android.exoplayer2.source.BundledExtractorsAdapter.init(BundledExtractorsAdapter.java:92)
E/ExoPlayerImplInternal(19219): at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1020)
E/ExoPlayerImplInternal(19219): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)
E/ExoPlayerImplInternal(19219): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/ExoPlayerImplInternal(19219): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/ExoPlayerImplInternal(19219): at java.lang.Thread.run(Thread.java:920)
E/AudioPlayer(19219): TYPE_SOURCE: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, JpegExtractor) could read the stream.
I/ExoPlayerImpl(19219): Release 83b2c2e [ExoPlayerLib/2.17.1] [oriole, Pixel 6, Google, 32] [goog.exo.core, goog.exo.exoplayer, goog.exo.decoder, goog.exo.datasource, goog.exo.extractor]
E/flutter (19219): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: (0) Source error
E/flutter (19219): #0 AudioPlayer._load (package:just_audio/just_audio.dart:800:9)
E/flutter (19219): <asynchronous suspension>
E/flutter (19219): #1 AudioPlayer._setPlatformActive.setPlatform (package:just_audio/just_audio.dart:1370:28)
E/flutter (19219): <asynchronous suspension>
same issue
I tried this on my Pixel 3a and wasn't able to reproduce the issue.
What device did you test? Was it an emulator or an actual device, and what specific device?
I was using an emulator. I also had a more experienced friend try it out and he said "It doesn't work on the android emulator for me, but when I ran it on a physical android device, the nature sound plays."
Has anyone been able to reproduce this on an actual device?
Sorry, I see above yes it has also been encountered on actual devices.
There have been similar issues reported in the past with Android, and my suspicion at the time was that there is some lag between when Flutter writes a file to storage and completely flushes the IO stream, vs when the native part of this plugin tries to open that file and start playing it. You can verify this by seeing whether the app fails on the first launch but succeeds on the second launch. It's only a working theory, but if it is correct, you may be able to work around this by inserting a time delay between these two steps (extracting the file and playing the file). That may mean handling the asset extraction yourself when your app starts for the first time.
For example:
final assetFile = File(...); // where you want to extract the asset to - typically the cache/temporary dir
// Extract assets the first time
await assetFile.writeAsBytes((await rootBundle.load(assetPath)).buffer.asUint8List());
// Wait a bit after writing the file to give Flutter a chance to "actually" write it.
await Future.delayed(Duration(seconds: 1));
// Use the file from now on:
player.setFilePath(assetFile.path); // or you could a AudioSource.uri('file://......')
If you extract the asset into a file on the first startup, then of course on the second startup you won't need to insert any delay, because the file will already exist and be ready to go.
Related: #520
If it is a timing issue, maybe it is the sort of thing that requires either a slow device or emulator, or a large file, to reproduce. I might not have a slow enough phone, but I can experiment with longer files.
I've just tested with longer/larger audio assets, and with an older device, but unfortunately was still not able to reproduce the issue. So I would be interested to hear if the above experiment (inserting a delay between writing the file and playing the file) will confirm that it's a timing issue with Flutter's I/O vs Android's I/O.
Nothing works for me. I have this playlist defined:
AudioSource.uri(
Uri.parse("asset:///audio/nature.mp3"),
tag: MediaItem(
id: '${_nextMediaId++}',
album: "Geniet van de rust!",
title: "Natuurlijke componenten",
artUri: Uri.parse(
"https://media.wnyc.org/i/1400/1400/l/80/1/ScienceFriday_WNYCStudios_1400.jpg"),
),
),
In my initstate i have this method to activate my playlist:
try {
await _player.setAudioSource(_playlist);
} catch (e, stackTrace) {
// Catch load errors: 404, invalid url ...
print("Error loading playlist: $e");
print(stackTrace);
}
But when i run this i get this error:
TYPE_SOURCE: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, JpegExtractor) could read the stream.
E/flutter (10238): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(0, Source error, null, null)
E/flutter (10238):
E/flutter (10238): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(0, Source error, null, null)
E/flutter (10238):
E/flutter (10238): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(0, Source error, null, null)
E/flutter (10238):
E/flutter (10238): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(0, Source error, null, null)
E/flutter (10238):
How can i fix this?
@Jens05 would you like to try the experiment I have outlined above to help the investigation?
@Jens05 would you like to try the experiment I have outlined above to help the investigation?
It only doesn't work when i use a AudioSource with the uri as follows: uri: Uri.parse(asset:///assets/audio/test.mp3) The example you provided with the rootbundle is working fine, but how can i make that work in a AudioSource uri then?
@Jens05 Once you extract the audio to a file, you can use the file URI in your audio source. i.e. Uri.parse('file:///path/to/where/you/extracted/it.mp3')
.
@Jens05 Once you extract the audio to a file, you can use the file URI in your audio source. i.e.
Uri.parse('file:///path/to/where/you/extracted/it.mp3')
.
So i would just define the file like this: final assetFile = File(assets/audios/mysong.mp3); await assetFile.writeAsBytes((await rootBundle.load(assetPath)).buffer.asUint8List());
And then Uri.parse('file://assetfile')? Something like this & if its wrong could you please help me out?
From my suggestion above:
final assetFile = File(...); // where you want to extract the asset to - typically the cache/temporary dir
In other words. you want to store it in the cache or temporary directory which is in a different location on Android vs iOS. You can use the path_provider package to find where that directory is for the installed operating system, and then you can append your additional path onto the end of that base path when storing your file.
From my suggestion above:
final assetFile = File(...); // where you want to extract the asset to - typically the cache/temporary dir
In other words. you want to store it in the cache or temporary directory which is in a different location on Android vs iOS. You can use the path_provider package to find where that directory is for the installed operating system, and then you can append your additional path onto the end of that base path when storing your file.
Quick answer to my issue: it was a debug & android issue. It happens when you change your playlist without reinstalling the apk.... So people: REINSTALL apk's! Then it should work
From my suggestion above:
final assetFile = File(...); // where you want to extract the asset to - typically the cache/temporary dir
Btw, is there a way to load the artwork from assets?
@Jens05 Feel free to make a separate feature request for that.
@Jens05 - instead of Uri.parse("asset:///audio/nature.mp3")
type Uri.parse("asset:/assets/audio/nature.mp3")
but I agree that error is misleading, and not having dedicated AudioSource.asset()
is a real bummer
@Jens05 - instead of
Uri.parse("asset:///audio/nature.mp3")
typeUri.parse("asset:/assets/audio/nature.mp3")
but I agree that error is misleading, and not aving dedicated
AudioSource.asset()
is a real bummer
But asset:///audio/nature.mp3 is working fine. Can you confirm that asset:/assets is working somehow?
I've just got similar error and it worked for me ;)
asset:///audio/nature.mp3
and asset:/audio/nature.mp3
makes no difference. They are equivalent because Uri.parse
has a single implementation across all platforms and always returns scheme=asset
and path=/audio/nature
for either URI.
@Jens05 I suspect that you may have encountered an issue with formatting your URI. Are you sure you didn't accidentally use asset://audio/nature.mp3
? The path part should always begin with a /
because otherwise the first segment of the path will instead be interpreted as the authority/host. And this is true across all platforms, not an issue that would only affect Android.
You could verify whether you are having the same issue by confirming whether the code you encountered failing actually works on iOS but fails only on Android - if your code fails on both platforms, it would have to be a different issue than this one.
asset:///audio/nature.mp3
andasset:/audio/nature.mp3
makes no difference. They are equivalent becauseUri.parse
has a single implementation across all platforms and always returnsscheme=asset
andpath=/audio/nature
for either URI.@Jens05 I suspect that you may have encountered an issue with formatting your URI. Are you sure you didn't accidentally use
asset://audio/nature.mp3
? The path part should always begin with a/
because otherwise the first segment of the path will instead be interpreted as the authority/host. And this is true across all platforms, not an issue that would only affect Android.You could verify whether you are having the same issue by confirming whether the code you encountered failing actually works on iOS but fails only on Android - if your code fails on both platforms, it would have to be a different issue than this one.
I know where the issue is coming from. It's the fact that i use just_audio_background & my album URI is an asset. It gives an error on both android and ios. I think it's because just_audio_background only supports networkimages in the notification. If else, let me hear! The issue is not within the /'s and i explained above why my asset audio was not loading. (Because i needed to reinstall the apk)
As mentioned above, I would recommend opening a separate issue regarding artwork as otherwise it can be difficult for me to manage the different issues.
As mentioned above, I would recommend opening a separate issue regarding artwork as otherwise it can be difficult for me to manage the different issues.
Sorry, i will open one now
@ryanheise I have similar problem which occurs on Android Emulator as well on Physical Android Device. Apple Physical device works great.
While trying to set Source to player on android throws ExoPlayer error but on IOS works well. (Still, cannot play audio since there is no audio but I'm trying to figure it out.)
Sample code:
final soundtrack =
await _lsService.soundService.getFile(_filePath!.lastSubstring('/'));
if (soundtrack != null) {
await _player.setAudioSource(ByteSource(soundtrack.toList()));
}
class ByteSource extends StreamAudioSource {
final List<int> bytes;
ByteSource(this.bytes);
@override
Future<StreamAudioResponse> request([int? start, int? end]) async {
start ??= 0;
end ??= bytes.length;
return StreamAudioResponse(
sourceLength: bytes.length,
contentLength: end - start,
offset: start,
stream: Stream.value(bytes.sublist(start, end)),
contentType: 'audio/mpeg',
);
}
}
Flutter doctor:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.2, on macOS 12.6 21G115 darwin-arm (Rosetta), locale pl-PL)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc2)
[✓] Xcode - develop for iOS and macOS (Xcode 14.0)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] VS Code (version 1.66.2)
[✓] VS Code (version 1.66.2)
[✓] Connected device (5 available)
[✓] HTTP Host Availability
• No issues found!
Error:
E/ExoPlayerImplInternal( 2251): Playback error
E/ExoPlayerImplInternal( 2251): com.google.android.exoplayer2.ExoPlaybackException: Source error
E/ExoPlayerImplInternal( 2251): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:632)
E/ExoPlayerImplInternal( 2251): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:602)
E/ExoPlayerImplInternal( 2251): at android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal( 2251): at android.os.Looper.loop(Looper.java:205)
E/ExoPlayerImplInternal( 2251): at android.os.HandlerThread.run(HandlerThread.java:65)
E/ExoPlayerImplInternal( 2251): Caused by: com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, AviExtractor, JpegExtractor) could read the stream.
E/ExoPlayerImplInternal( 2251): at com.google.android.exoplayer2.source.BundledExtractorsAdapter.init(BundledExtractorsAdapter.java:92)
E/ExoPlayerImplInternal( 2251): at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1017)
E/ExoPlayerImplInternal( 2251): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)
E/ExoPlayerImplInternal( 2251): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/ExoPlayerImplInternal( 2251): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/ExoPlayerImplInternal( 2251): at java.lang.Thread.run(Thread.java:764)
E/AudioPlayer( 2251): TYPE_SOURCE: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, AviExtractor, JpegExtractor) could read the stream.
I/ExoPlayerImpl( 2251): Release b500aa6 [ExoPlayerLib/2.18.1] [joan, LG-H930, LGE, 28] [goog.exo.core, goog.exo.exoplayer, goog.exo.decoder, goog.exo.datasource, goog.exo.extractor]
Hi @PcolBP , FYI this issue is about the setAsset
method only. I want to solve this bug although it is harder to manage when multiple unrelated issues are being raised that are not on the topic of setAsset
. I'll mark both yours and my comment as off-topic, but if you have a different issue that you believe is a bug in just_audio (as opposed to a bug in your implementation), you are welcome to open a new issue.
@Jens05 I have a write a complete solution of this . Please have a look https://stackoverflow.com/questions/75456939/how-to-show-artmusic-on-media-control-notification-from-assets-file-in-flutter/75578627#75578627