2024-05-24 00:10:11 +02:00
|
|
|
import 'package:fast_cached_network_image/fast_cached_network_image.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
2024-05-23 19:14:08 +02:00
|
|
|
import 'package:just_audio/just_audio.dart';
|
|
|
|
import 'package:just_audio_background/just_audio_background.dart';
|
|
|
|
import 'package:ocarina/api/subsonic/song.dart';
|
|
|
|
import 'package:ocarina/main.dart';
|
2024-05-24 00:10:11 +02:00
|
|
|
import 'package:ocarina/util/util.dart';
|
2024-05-23 19:14:08 +02:00
|
|
|
|
|
|
|
/// Service used to control the audio player
|
|
|
|
class AudioPlayerService {
|
|
|
|
/// Service used to control the audio player
|
|
|
|
factory AudioPlayerService() {
|
|
|
|
return _audioPlayerService;
|
|
|
|
}
|
|
|
|
|
|
|
|
AudioPlayerService._internal();
|
|
|
|
static final AudioPlayerService _audioPlayerService =
|
|
|
|
AudioPlayerService._internal();
|
|
|
|
|
|
|
|
/// The [AudioPlayer] instance
|
2024-05-24 00:10:11 +02:00
|
|
|
final _player = AudioPlayer();
|
|
|
|
|
|
|
|
/// True if [AudioPlayer] instance is playing
|
|
|
|
bool get isPlaying => _player.playing;
|
2024-05-23 19:14:08 +02:00
|
|
|
|
|
|
|
/// Currently playing song
|
|
|
|
///
|
|
|
|
/// Null if no song is loaded
|
2024-05-24 00:10:11 +02:00
|
|
|
Song? get song => _song;
|
|
|
|
|
|
|
|
set song(Song? s) {
|
|
|
|
_song = s;
|
|
|
|
logger.d("CHANGE song");
|
|
|
|
songNotifier.value = s;
|
|
|
|
|
|
|
|
_setColorScheme();
|
|
|
|
}
|
|
|
|
|
|
|
|
Song? _song;
|
|
|
|
|
|
|
|
/// Pauses playback
|
|
|
|
Future<void> pause() async {
|
|
|
|
await _player.pause();
|
|
|
|
logger.d("Paused");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Resumes playback
|
|
|
|
void resume() {
|
|
|
|
_player.play();
|
|
|
|
logger.d("Playing");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sets color scheme from image
|
|
|
|
Future<void> _setColorScheme() async {
|
|
|
|
if (AudioPlayerService().song == null) {
|
|
|
|
themeNotifier.value = ColorScheme.fromSeed(seedColor: Colors.deepPurple);
|
|
|
|
}
|
|
|
|
themeNotifier.value = await ColorScheme.fromImageProvider(
|
|
|
|
provider: FastCachedImageProvider(
|
|
|
|
AudioPlayerService().song!.coverArtUrl,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
logger.d(AudioPlayerService().song!.coverArtUrl);
|
|
|
|
}
|
2024-05-23 19:14:08 +02:00
|
|
|
|
|
|
|
/// Plays the passed [Song] as a file
|
|
|
|
Future<void> playFile({Song? song}) async {
|
|
|
|
final doCache = sp.getBool("doCache") ?? true;
|
|
|
|
if (song == null && this.song == null) return;
|
|
|
|
song ??= this.song;
|
2024-05-24 00:10:11 +02:00
|
|
|
await _player.setAudioSource(
|
2024-05-23 19:14:08 +02:00
|
|
|
doCache
|
|
|
|
? LockCachingAudioSource(
|
|
|
|
Uri.parse(song!.streamUrl),
|
|
|
|
tag: MediaItem(
|
|
|
|
id: song.id,
|
|
|
|
title: song.title,
|
|
|
|
album: song.albumName,
|
|
|
|
artist: song.artistName,
|
|
|
|
artUri: Uri.parse(song.coverArtUrl),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
: AudioSource.uri(
|
|
|
|
Uri.parse(song!.streamUrl),
|
|
|
|
tag: MediaItem(
|
|
|
|
id: song.id,
|
|
|
|
title: song.title,
|
|
|
|
album: song.albumName,
|
|
|
|
artist: song.artistName,
|
|
|
|
artUri: Uri.parse(song.coverArtUrl),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
2024-05-24 00:10:11 +02:00
|
|
|
await _player.seek(Duration.zero);
|
|
|
|
playerKey.currentState?.update();
|
|
|
|
resume();
|
2024-05-23 19:14:08 +02:00
|
|
|
}
|
|
|
|
}
|