audio_service
audio_service copied to clipboard
How to load a local image into a curtain using: - AudioServiceBackground.setMediaItem ( and property: - artUri
Is your feature request related to a problem? Please describe. How to load a local image into a curtain using: "artUri"
mistakenly I asked the question elsewhere: https://github.com/ryanheise/audio_service/issues/354#issuecomment-726042710 please look.
My code
MediaItem(
id: _params['id']?.toString() ?? AudioService.MEDIA_ROOT_ID,
album: _mediaDataItuns.collectionName,
title: _params['name'],
artist: _mediaDataItuns.artistName,
displayTitle: _params['name'],
displaySubtitle: _mediaDataItuns.displaySubtitle,
artUri: _artUri,
extras: {
'id': _params['id'],
'url': _params['url'],
'name': _params['name'],
'trackName': _mediaDataItuns.trackName,
'artworkUrl30': _mediaDataItuns.artworkUrl30,
'artworkUrl100': _mediaDataItuns.artworkUrl100,
'artworkUrl820': _mediaDataItuns.artworkUrl820,
'control': event?.info?.title,
},
),
Describe the solution you'd like I think you need to introduce several ways to load artUri
- artUrl
- artAsset
- artByte
Describe alternatives you've considered Here's what I've tried: but it did not help(((
/// got full path
var tempDir = await path_provider.getApplicationDocumentsDirectory();
//AND
var _artUri = join("file://", tempDir.uri.path, _params['artUri']);
/// OR
var _artUri = join(tempDir.uri.path, _params['artUri']);
Additional context
These are good suggestions. I hadn't yet thought about the bytes option, but I do have plans to add an assets option.
While the bytes option seems like a good idea, it will probably be too inefficient to transfer bytes over the platform channel as another MediaItem
field because these media items get transferred frequently. I think the assets option will probably be enough.
Your workaround will not work because Flutter assets are not stored in the documents directory. They are embedded as bytes within the app binary itself. You read assets in your program as a stream of bytes via rootBundle
.
Until this feature is implemented in the plugin, you can still workaround it. What you need to do is read the asset out of rootBundle
and copy it into a file on app initialisation, then you can pass the file://
URI pointing to that in your artUri
.
what's wrong with my path?
my pubspec.yaml
and import.
what have I missed?
You missed this:
Your workaround will not work because Flutter assets are not stored in the documents directory. They are embedded as bytes within the app binary itself. You read assets in your program as a stream of bytes via rootBundle.
You are using rootBundle.loadString
but your asset is an image in a binary format, not a string. You need to read the bytes and store those bytes into a file. These are not my APIs, so I can't provide more advice on that. But you can take a look at how I implemented asset loading in just_audio for inspiration.
Thank you for the clarification. You have complete information in the first message !!!
I read your previous message for the second time and now I found the right solution !!!)))
Directory appDir = await path_provider.getApplicationDocumentsDirectory();
ByteData bytes = await rootBundle.load(_params['artUri']);
File _file = File(join(appDir.path, 'default_images.webp'));
File _newFile = await _file.writeAsBytes(bytes.buffer.asUint8List());
String _artUri = "file://" + _newFile.path;
AudioServiceBackground.setMediaItem(
MediaItem(
id: _params['id']?.toString() ?? AudioService.MEDIA_ROOT_ID,
album: _mediaDataItuns.collectionName,
title: _params['name'],
artist: _mediaDataItuns.artistName,
displayTitle: _params['name'],
displaySubtitle: _mediaDataItuns.displaySubtitle,
artUri: _artUri,
extras: {
'id': _params['id'],
'url': _params['url'],
'name': _params['name'],
'trackName': _mediaDataItuns.trackName,
'artworkUrl30': _mediaDataItuns.artworkUrl30,
'artworkUrl100': _mediaDataItuns.artworkUrl100,
'artworkUrl820': _mediaDataItuns.artworkUrl820,
'control': event?.info?.title,
},
),
);
But I still continue to wait for your decision in new version:
- artAsset
I'm glad you figured it out. I will still leave your feature request open until I implement the feature.
ryanheise says "These are good suggestions. I hadn't yet thought about the bytes option, but I do have plans to add an assets option." Do you have implemented asset image option?
I haven't. If I do implement it, it will be announced in the CHANGELOG.
Do you have any advice at this point? My app works offline so I can't get the image from the internet. Is there any way to load in the artUri parameter of the MediaItem a local image? Thanks
I did give advice above in my very first reply. Maybe you can read it and ask me specifically about what I have written in that above advice.
👍🏻 Thanks
For people still needing to load local images as art URI here is an updated example:
import 'package:path_provider/path_provider.dart';
final Directory appDir = await getApplicationDocumentsDirectory();
File file = File('${appDir.path}/cover.jpg');
//coverImageBytes of type Uint8List
File newFile = await file.writeAsBytes(coverImageBytes);
String artUri = "file://${newFile.path}";
return MediaItem(id: id, album: book.title, artist: chapter.title, title: book.title, artUri: Uri.tryParse(artUri));