-
Notifications
You must be signed in to change notification settings - Fork 853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Play a remote file and cache the file at the same time #374
Comments
+1 |
I believe we could make |
+1 |
1 similar comment
+1 |
hi @somaria this is the technic I am actually using. I am also looking for improvement for this technic or its implementation in the play method. because it will download the file two time in my opinion. one from the remote action and one from the cache. but the next time it is ok I think :). //invoked only when the user want to play a new song
//may be when he clicks on a new music to cache item only once
play({bool isNew = false, bool isLocal = false}) async {
// _cache.emptyCache(); //used for testing
//set the loading to true
//setLoading(true); in case you want to show a loading
_player.stop();
//checking if the file is stored in the cache
FileInfo info;
// this is an object from my provider class
// that let me store info about the current music
final _url = _data['url'];
//set the url to be the cached one if exists
String path = _url;
//ios does not support cache because files are store as mpeg which it does not read
if (!Platform.isIOS) {
info = await _cache.getFileFromCache(_url);
// if the file is not in the cache we cache it for the next time
path = info != null ? info.file.path : path;
}
final int result = await _player.play(
path,
isLocal: info != null,
stayAwake: true,
);
notifyListeners();
//cache the song after playing it
// skiping ios as it does not support mpeg.
//another option could be to store the file locally in a
// custom folder as IOS does not show up folders
if (!Platform.isIOS && result == 1) {
if (info == null) {
await _cache.getSingleFile(_url);
}
}
} |
so this works only for Android and not in iOS? |
You can download a file, and then play it - on all platforms. It's impossible to "play and cache" and the same time. Audio players start playing files before they download the complete file - as soon as they have enough "chunks" for a smooth playback. Each player has its own logic for deciding when it's safe to start playing. I don't know if you can pass individual chunks to Android and iOs players. If it's possible, then you can manage chunking in your own code - get a chunk, give it to a player, and write it out to the file. But this will not be a simple implementation, even if it's possible. Another option would be for a player to manage all the chunking, and then give you the file after it finished loading it. Again, I don't know for sure if any player can do it, but I don't think so. |
This can be done using Flutter Cache Manager for Android. The test code is here https://github.com/somaria/flutter_cache_try |
@somaria In your code the playback starts only after the entire file is downloaded to a device. It will lead to a noticeable delay unless your files are very small. BTW, it’s not a good practice to call async methods from setState(). |
@volgin , yes the mp3 files are very small, but they are many of them. Now there are already a few hundreds. Did you notice that the code doesn't work in iOS? It could be that AudioPlayers doesn't support playing files from iOS device. It only supports playing files from asset folder in iOS. I need to get a confirmation on this. |
I play files from iOs devices using AudioPlayers every day. mp3, m4a - they all work perfectly. Check the file path that you get from the cache manager. |
it does not work on ios because the files are saved in mpeg. which ios does not support |
yes you can still play form ios but the file is not cached |
@feroult I really prefer using Flutter Cache Manager, it works perfectly in Android. |
the last thing we may try is to download the file itself using and store in a custom folder for ios. I think IOS does not show local file such as musics. and then from sqflite save the path and access it. I hope you see the idea |
see Baseflow/flutter_cache_manager#140 Future<void> _playBgm() async {
await _bgm.play(await _fixMp3Url());
}
/// when Flutter Cache Manager delete it
Future<String> _fixMp3Url() async {
var s1 = 'https//a.b/c.mp3';
var f = await DefaultCacheManager().getSingleFile(s1);
if (!Platform.isAndroid && s1.endsWith('.mp3')) {
var s2 = s1 + '.mp3';
var resp;
var cacheFile = await DefaultCacheManager().getFileFromCache(s2);
if (cacheFile == null) {
var f2 = await DefaultCacheManager()
.putFile(s2, await f.readAsBytes(), fileExtension: 'mp3');
resp = f2.path;
} else {
resp = cacheFile.file.path;
}
return resp;
}
return f.path;
} it works well now |
Any suggestion on how I could play a remote files and store the files in cache for faster playing next time?
Anyone has tried using audioplayers with Flutter Cache Manager to cache the audio files? Is that even possible?
The text was updated successfully, but these errors were encountered: