0.5.0 - Rewritten downloads, many bugfixes

This commit is contained in:
exttex 2020-10-09 20:52:45 +02:00
parent f7cbb09bc1
commit f2f6b202d1
38 changed files with 5176 additions and 1365 deletions

View file

@ -1,6 +1,9 @@
import 'dart:math';
import 'package:audio_service/audio_service.dart';
import 'package:audio_session/audio_session.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:freezer/api/cache.dart';
import 'package:freezer/api/deezer.dart';
import 'package:freezer/ui/android_auto.dart';
import 'package:just_audio/just_audio.dart';
@ -21,6 +24,7 @@ PlayerHelper playerHelper = PlayerHelper();
class PlayerHelper {
StreamSubscription _customEventSubscription;
StreamSubscription _mediaItemSubscription;
StreamSubscription _playbackStateStreamSubscription;
QueueSource queueSource;
LoopMode repeatType = LoopMode.off;
@ -65,9 +69,26 @@ class PlayerHelper {
//Log song (if allowed)
if (event == null) return;
if (event.processingState == AudioProcessingState.ready && event.playing) {
if (settings.logListen) deezerAPI.logListen(AudioService.currentMediaItem.id);
if (settings.logListen) {
//Check if duplicate
if (cache.loggedTrackId == AudioService.currentMediaItem.id) return;
cache.loggedTrackId = AudioService.currentMediaItem.id;
deezerAPI.logListen(AudioService.currentMediaItem.id);
}
}
});
_mediaItemSubscription = AudioService.currentMediaItemStream.listen((event) {
//Save queue
AudioService.customAction('saveQueue');
//Add to history
if (event == null) return;
if (cache.history == null) cache.history = [];
if (cache.history.length > 0 && cache.history.last.id == event.id) return;
cache.history.add(Track.fromMediaItem(event));
cache.save();
});
//Start audio_service
startService();
}
@ -79,7 +100,7 @@ class PlayerHelper {
androidEnableQueue: true,
androidStopForegroundOnPause: false,
androidNotificationOngoing: false,
androidNotificationClickStartsActivity: true,
androidNotificationClickStartsActivity: false,
androidNotificationChannelDescription: 'Freezer',
androidNotificationChannelName: 'Freezer',
androidNotificationIcon: 'drawable/ic_logo',
@ -110,6 +131,7 @@ class PlayerHelper {
Future onExit() async {
_customEventSubscription.cancel();
_playbackStateStreamSubscription.cancel();
_mediaItemSubscription.cancel();
}
//Replace queue, play specified track id
@ -256,6 +278,13 @@ class AudioPlayerTask extends BackgroundAudioTask {
});
//Update state on all clients on change
_eventSub = _player.playbackEventStream.listen((event) {
//Quality string
if (_queueIndex != -1 && _queueIndex < _queue.length) {
Map extras = mediaItem.extras;
extras['qualityString'] = event.qualityString??'';
_queue[_queueIndex] = mediaItem.copyWith(extras: extras);
}
//Update
_broadcastState();
});
_player.processingStateStream.listen((state) {
@ -296,6 +325,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
//Skip in player
await _player.seek(Duration.zero, index: newIndex);
_queueIndex = newIndex;
_skipState = null;
onPlay();
}
@ -327,6 +357,40 @@ class AudioPlayerTask extends BackgroundAudioTask {
@override
Future<void> onSeekBackward(bool begin) async => _seekContinuously(begin, -1);
@override
Future<void> onSkipToNext() async {
//Shuffle
if (_player.shuffleModeEnabled??false) {
int newIndex = Random().nextInt(_queue.length)-1;
//Update state
_skipState = newIndex > _queueIndex
? AudioProcessingState.skippingToNext
: AudioProcessingState.skippingToPrevious;
_queueIndex = newIndex;
await _player.seek(Duration.zero, index: _queueIndex);
_skipState = null;
return;
}
//Update buffering state
_skipState = AudioProcessingState.skippingToNext;
_queueIndex++;
await _player.seekToNext();
_skipState = null;
await _broadcastState();
}
@override
Future<void> onSkipToPrevious() async {
if (_queueIndex == 0) return;
//Update buffering state
_skipState = AudioProcessingState.skippingToPrevious;
_queueIndex--;
await _player.seekToPrevious();
_skipState = null;
}
@override
Future<List<MediaItem>> onLoadChildren(String parentMediaId) async {
AudioServiceBackground.sendCustomEvent({
@ -417,12 +481,16 @@ class AudioPlayerTask extends BackgroundAudioTask {
this._queue = q;
AudioServiceBackground.setQueue(_queue);
//Load
_queueIndex = 0;
await _loadQueue();
await _player.seek(Duration.zero, index: 0);
//await _player.seek(Duration.zero, index: 0);
}
//Load queue to just_audio
Future _loadQueue() async {
//Don't reset queue index by starting player
int qi = _queueIndex;
List<AudioSource> sources = [];
for(int i=0; i<_queue.length; i++) {
sources.add(await _mediaItemToAudioSource(_queue[i]));
@ -432,9 +500,11 @@ class AudioPlayerTask extends BackgroundAudioTask {
//Load in just_audio
try {
await _player.load(_audioSource);
await _player.seek(Duration.zero, index: qi);
} catch (e) {
//Error loading tracks
}
_queueIndex = qi;
AudioServiceBackground.setMediaItem(mediaItem);
}
@ -523,13 +593,14 @@ class AudioPlayerTask extends BackgroundAudioTask {
//Export queue to JSON
Future _saveQueue() async {
if (_queueIndex == 0 && _queue.length == 0) return;
String path = await _getQueuePath();
File f = File(path);
//Create if doesnt exist
//Create if doesn't exist
if (! await File(path).exists()) {
f = await f.create();
}
Map data = {
'index': _queueIndex,
'queue': _queue.map<Map<String, dynamic>>((mi) => mi.toJson()).toList(),
@ -552,7 +623,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
if (_queue != null) {
await AudioServiceBackground.setQueue(_queue);
await _loadQueue();
AudioServiceBackground.setMediaItem(mediaItem);
await AudioServiceBackground.setMediaItem(mediaItem);
}
}
//Send restored queue source to ui
@ -568,7 +639,6 @@ class AudioPlayerTask extends BackgroundAudioTask {
//-1 == play next
if (index == -1) index = _queueIndex + 1;
_queue.insert(index, mi);
await AudioServiceBackground.setQueue(_queue);
await _audioSource.insert(index, await _mediaItemToAudioSource(mi));