Fix background - foreground transition, quality fallback
This commit is contained in:
parent
7df500bc9c
commit
2bd4646796
|
@ -57,15 +57,15 @@ class PlayerHelper {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//Start audio_service
|
//Start audio_service
|
||||||
_startService();
|
startService();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _startService() async {
|
Future startService() async {
|
||||||
if (AudioService.running) return;
|
if (AudioService.running) return;
|
||||||
await AudioService.start(
|
await AudioService.start(
|
||||||
backgroundTaskEntrypoint: backgroundTaskEntrypoint,
|
backgroundTaskEntrypoint: backgroundTaskEntrypoint,
|
||||||
androidEnableQueue: true,
|
androidEnableQueue: true,
|
||||||
androidStopForegroundOnPause: true,
|
androidStopForegroundOnPause: false,
|
||||||
androidNotificationOngoing: false,
|
androidNotificationOngoing: false,
|
||||||
androidNotificationClickStartsActivity: true,
|
androidNotificationClickStartsActivity: true,
|
||||||
androidNotificationChannelDescription: 'Freezer',
|
androidNotificationChannelDescription: 'Freezer',
|
||||||
|
@ -74,6 +74,7 @@ class PlayerHelper {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Repeat toggle
|
//Repeat toggle
|
||||||
Future changeRepeat() async {
|
Future changeRepeat() async {
|
||||||
//Change to next repeat type
|
//Change to next repeat type
|
||||||
|
@ -97,7 +98,7 @@ class PlayerHelper {
|
||||||
|
|
||||||
//Replace queue, play specified track id
|
//Replace queue, play specified track id
|
||||||
Future _loadQueuePlay(List<MediaItem> queue, String trackId) async {
|
Future _loadQueuePlay(List<MediaItem> queue, String trackId) async {
|
||||||
await _startService();
|
await startService();
|
||||||
await settings.updateAudioServiceQuality();
|
await settings.updateAudioServiceQuality();
|
||||||
await AudioService.updateQueue(queue);
|
await AudioService.updateQueue(queue);
|
||||||
await AudioService.playFromMediaId(trackId);
|
await AudioService.playFromMediaId(trackId);
|
||||||
|
@ -128,7 +129,7 @@ class PlayerHelper {
|
||||||
}
|
}
|
||||||
//Load tracks as queue, play track id, set queue source
|
//Load tracks as queue, play track id, set queue source
|
||||||
Future playFromTrackList(List<Track> tracks, String trackId, QueueSource queueSource) async {
|
Future playFromTrackList(List<Track> tracks, String trackId, QueueSource queueSource) async {
|
||||||
await _startService();
|
await startService();
|
||||||
|
|
||||||
List<MediaItem> queue = tracks.map<MediaItem>((track) => track.toMediaItem()).toList();
|
List<MediaItem> queue = tracks.map<MediaItem>((track) => track.toMediaItem()).toList();
|
||||||
await setQueueSource(queueSource);
|
await setQueueSource(queueSource);
|
||||||
|
@ -164,7 +165,7 @@ class PlayerHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future setQueueSource(QueueSource queueSource) async {
|
Future setQueueSource(QueueSource queueSource) async {
|
||||||
await _startService();
|
await startService();
|
||||||
|
|
||||||
this.queueSource = queueSource;
|
this.queueSource = queueSource;
|
||||||
await AudioService.customAction('queueSource', queueSource.toJson());
|
await AudioService.customAction('queueSource', queueSource.toJson());
|
||||||
|
@ -276,10 +277,10 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onSkipToNext() {
|
Future onSkipToNext() async {
|
||||||
//If repeating allowed
|
//If repeating allowed
|
||||||
if (repeatType == 2) {
|
if (repeatType == 2) {
|
||||||
_skip(0);
|
await _skip(0);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
_skip(1);
|
_skip(1);
|
||||||
|
@ -405,6 +406,12 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||||
onSeekTo(_audioPlayer.playbackEvent.position + offset);
|
onSeekTo(_audioPlayer.playbackEvent.position + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future onUpdateMediaItem(MediaItem mediaItem) async {
|
||||||
|
_queue[_queueIndex] = mediaItem;
|
||||||
|
AudioServiceBackground.setMediaItem(mediaItem);
|
||||||
|
}
|
||||||
|
|
||||||
//Audio interruptions
|
//Audio interruptions
|
||||||
@override
|
@override
|
||||||
void onAudioFocusLost(AudioInterruption interruption) {
|
void onAudioFocusLost(AudioInterruption interruption) {
|
||||||
|
@ -492,7 +499,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _getTrackUri(MediaItem mi) async {
|
Future<String> _getTrackUri(MediaItem mi, {int quality}) async {
|
||||||
String prefix = 'DEEZER|${mi.id}|';
|
String prefix = 'DEEZER|${mi.id}|';
|
||||||
|
|
||||||
//Check if song is available offline
|
//Check if song is available offline
|
||||||
|
@ -505,12 +512,27 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||||
id: mi.id,
|
id: mi.id,
|
||||||
playbackDetails: jsonDecode(mi.extras['playbackDetails']) //JSON Because of audio_service bug
|
playbackDetails: jsonDecode(mi.extras['playbackDetails']) //JSON Because of audio_service bug
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//Check connection
|
||||||
|
if (quality == null) {
|
||||||
ConnectivityResult conn = await Connectivity().checkConnectivity();
|
ConnectivityResult conn = await Connectivity().checkConnectivity();
|
||||||
if (conn == ConnectivityResult.wifi) {
|
quality = mobileQuality;
|
||||||
return prefix + t.getUrl(wifiQuality);
|
if (conn == ConnectivityResult.wifi) quality = wifiQuality;
|
||||||
}
|
}
|
||||||
return prefix + t.getUrl(mobileQuality);
|
String url = t.getUrl(quality);
|
||||||
|
|
||||||
|
//Quality fallback
|
||||||
|
Dio dio = Dio();
|
||||||
|
try {
|
||||||
|
await dio.head(url);
|
||||||
|
return prefix + url;
|
||||||
|
} catch (e) {
|
||||||
|
if (quality == 9) return _getTrackUri(mi, quality: 3);
|
||||||
|
if (quality == 3) return _getTrackUri(mi, quality: 1);
|
||||||
|
throw Exception('No available quality!');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<String> _getQualityString(String uri, Duration duration) async {
|
Future<String> _getQualityString(String uri, Duration duration) async {
|
||||||
//Get url/path
|
//Get url/path
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:freezer/api/deezer.dart';
|
||||||
import 'package:freezer/api/player.dart';
|
import 'package:freezer/api/player.dart';
|
||||||
import 'package:freezer/ui/menu.dart';
|
import 'package:freezer/ui/menu.dart';
|
||||||
import 'package:freezer/ui/tiles.dart';
|
import 'package:freezer/ui/tiles.dart';
|
||||||
|
import 'package:async/async.dart';
|
||||||
|
|
||||||
import 'cached_image.dart';
|
import 'cached_image.dart';
|
||||||
import '../api/definitions.dart';
|
import '../api/definitions.dart';
|
||||||
|
@ -14,6 +15,7 @@ import 'player_bar.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PlayerScreen extends StatefulWidget {
|
class PlayerScreen extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
_PlayerScreenState createState() => _PlayerScreenState();
|
_PlayerScreenState createState() => _PlayerScreenState();
|
||||||
|
@ -29,12 +31,19 @@ class _PlayerScreenState extends State<PlayerScreen> {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: StreamBuilder(
|
child: StreamBuilder(
|
||||||
stream: AudioService.playbackStateStream,
|
stream: StreamZip([AudioService.playbackStateStream, AudioService.currentMediaItemStream]),
|
||||||
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||||
|
|
||||||
//Disable lyrics when skipping songs, loading
|
//Disable lyrics when skipping songs, loading
|
||||||
PlaybackState s = snapshot.data;
|
if (snapshot.data is PlaybackState &&
|
||||||
if (s != null && s.processingState != AudioProcessingState.ready && s.processingState != AudioProcessingState.buffering) _lyrics = false;
|
snapshot.data.processingState != AudioProcessingState.ready &&
|
||||||
|
snapshot.data.processingState != AudioProcessingState.buffering) _lyrics = false;
|
||||||
|
|
||||||
|
//When disconnected
|
||||||
|
if (AudioService.currentMediaItem == null) {
|
||||||
|
playerHelper.startService();
|
||||||
|
return Center(child: CircularProgressIndicator(),);
|
||||||
|
}
|
||||||
|
|
||||||
return OrientationBuilder(
|
return OrientationBuilder(
|
||||||
builder: (context, orientation) {
|
builder: (context, orientation) {
|
||||||
|
|
Loading…
Reference in New Issue