removed AudioManager
This commit is contained in:
parent
3edc5c2ff1
commit
cf2d134d08
4 changed files with 104 additions and 232 deletions
|
@ -13,8 +13,6 @@ import 'presentation/state/audio_store.dart';
|
||||||
import 'presentation/state/music_data_store.dart';
|
import 'presentation/state/music_data_store.dart';
|
||||||
import 'presentation/state/navigation_store.dart';
|
import 'presentation/state/navigation_store.dart';
|
||||||
import 'system/audio/audio_handler.dart';
|
import 'system/audio/audio_handler.dart';
|
||||||
import 'system/audio/audio_manager.dart';
|
|
||||||
import 'system/audio/audio_manager_contract.dart';
|
|
||||||
import 'system/audio/audio_player_contract.dart';
|
import 'system/audio/audio_player_contract.dart';
|
||||||
import 'system/audio/audio_player_impl.dart';
|
import 'system/audio/audio_player_impl.dart';
|
||||||
import 'system/audio/queue_generator.dart';
|
import 'system/audio/queue_generator.dart';
|
||||||
|
@ -102,7 +100,6 @@ Future<void> setupGetIt() async {
|
||||||
getIt(),
|
getIt(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
getIt.registerLazySingleton<AudioManager>(() => AudioManagerImpl(getIt()));
|
|
||||||
|
|
||||||
final AudioPlayer audioPlayer = AudioPlayerImpl(
|
final AudioPlayer audioPlayer = AudioPlayerImpl(
|
||||||
ja.AudioPlayer(),
|
ja.AudioPlayer(),
|
||||||
|
|
|
@ -1,152 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:audio_service/audio_service.dart';
|
|
||||||
|
|
||||||
import '../../domain/entities/loop_mode.dart';
|
|
||||||
import '../../domain/entities/playback_state.dart' as entity;
|
|
||||||
import '../../domain/entities/shuffle_mode.dart';
|
|
||||||
import '../models/album_model.dart';
|
|
||||||
import '../models/artist_model.dart';
|
|
||||||
import '../models/playback_state_model.dart';
|
|
||||||
import '../models/song_model.dart';
|
|
||||||
import 'audio_manager_contract.dart';
|
|
||||||
import 'stream_constants.dart';
|
|
||||||
|
|
||||||
typedef Conversion<S, T> = T Function(S);
|
|
||||||
|
|
||||||
class AudioManagerImpl implements AudioManager {
|
|
||||||
AudioManagerImpl(this._audioHandler);
|
|
||||||
|
|
||||||
final AudioHandler _audioHandler;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<SongModel> get currentSongStream => _filterStream<MediaItem, SongModel>(
|
|
||||||
_audioHandler.mediaItem.stream,
|
|
||||||
(MediaItem mi) => SongModel.fromMediaItem(mi),
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<entity.PlaybackState> get playbackStateStream => _filterStream(
|
|
||||||
_audioHandler.playbackState.stream,
|
|
||||||
(PlaybackState ps) => PlaybackStateModel.fromASPlaybackState(ps),
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<int> get currentPositionStream => _position().distinct();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> playSong(int index, List<SongModel> songList) async {
|
|
||||||
final List<String> context = songList.map((s) => s.path).toList();
|
|
||||||
await _audioHandler.customAction(PLAY_WITH_CONTEXT, {'CONTEXT': context, 'INDEX': index});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> play() async {
|
|
||||||
_audioHandler.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> pause() async {
|
|
||||||
await _audioHandler.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> skipToNext() async {
|
|
||||||
await _audioHandler.skipToNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> skipToPrevious() async {
|
|
||||||
await _audioHandler.skipToPrevious();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> setIndex(int index) async {
|
|
||||||
await _audioHandler.customAction(SET_INDEX, {'INDEX': index});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> setShuffleMode(ShuffleMode shuffleMode) async {
|
|
||||||
await _audioHandler.customAction(SET_SHUFFLE_MODE, {'SHUFFLE_MODE': shuffleMode});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> setLoopMode(LoopMode loopMode) async {
|
|
||||||
await _audioHandler.customAction(SET_LOOP_MODE, {'LOOP_MODE': loopMode});
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<T> _filterStream<S, T>(Stream<S> stream, Conversion<S, T> fn) async* {
|
|
||||||
T lastItem;
|
|
||||||
|
|
||||||
await for (final S item in stream) {
|
|
||||||
final T newItem = fn(item);
|
|
||||||
if (newItem != lastItem) {
|
|
||||||
lastItem = newItem;
|
|
||||||
yield newItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<int> _position() async* {
|
|
||||||
PlaybackState state;
|
|
||||||
DateTime updateTime;
|
|
||||||
Duration statePosition;
|
|
||||||
|
|
||||||
// TODO: should this class get an init method for this?
|
|
||||||
_audioHandler.playbackState.stream.listen((currentState) {
|
|
||||||
state = currentState;
|
|
||||||
updateTime = currentState?.updateTime;
|
|
||||||
statePosition = currentState?.position;
|
|
||||||
});
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (statePosition != null && updateTime != null && state != null) {
|
|
||||||
if (state.playing) {
|
|
||||||
yield statePosition.inMilliseconds +
|
|
||||||
(DateTime.now().millisecondsSinceEpoch - updateTime.millisecondsSinceEpoch);
|
|
||||||
} else {
|
|
||||||
yield statePosition.inMilliseconds;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
yield 0;
|
|
||||||
}
|
|
||||||
await Future.delayed(const Duration(milliseconds: 200));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> shuffleAll() async {
|
|
||||||
await _audioHandler.customAction(SHUFFLE_ALL, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> addToQueue(SongModel songModel) async {
|
|
||||||
await _audioHandler.addQueueItem(songModel.toMediaItem());
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> moveQueueItem(int oldIndex, int newIndex) async {
|
|
||||||
await _audioHandler.customAction(MOVE_QUEUE_ITEM, {
|
|
||||||
'OLD_INDEX': oldIndex,
|
|
||||||
'NEW_INDEX': newIndex,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> removeQueueIndex(int index) async {
|
|
||||||
await _audioHandler.removeQueueItemAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> playAlbum(AlbumModel albumModel) async {
|
|
||||||
await _audioHandler.customAction(PLAY_ALBUM, {'ALBUM': albumModel});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> playArtist(ArtistModel artistModel, ShuffleMode shuffleMode) async {
|
|
||||||
await _audioHandler.customAction(PLAY_ARTIST, {
|
|
||||||
'ARTIST': artistModel,
|
|
||||||
'SHUFFLE_MODE': shuffleMode,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
import '../../domain/entities/loop_mode.dart';
|
|
||||||
import '../../domain/entities/playback_state.dart';
|
|
||||||
import '../../domain/entities/shuffle_mode.dart';
|
|
||||||
import '../models/album_model.dart';
|
|
||||||
import '../models/artist_model.dart';
|
|
||||||
import '../models/song_model.dart';
|
|
||||||
|
|
||||||
abstract class AudioManager {
|
|
||||||
Stream<SongModel> get currentSongStream;
|
|
||||||
Stream<PlaybackState> get playbackStateStream;
|
|
||||||
|
|
||||||
/// Current position in the song in milliseconds.
|
|
||||||
Stream<int> get currentPositionStream;
|
|
||||||
|
|
||||||
Future<void> playSong(int index, List<SongModel> songList);
|
|
||||||
Future<void> play();
|
|
||||||
Future<void> pause();
|
|
||||||
Future<void> skipToNext();
|
|
||||||
Future<void> skipToPrevious();
|
|
||||||
Future<void> setIndex(int index);
|
|
||||||
Future<void> setShuffleMode(ShuffleMode shuffleMode);
|
|
||||||
Future<void> setLoopMode(LoopMode loopMode);
|
|
||||||
Future<void> shuffleAll();
|
|
||||||
Future<void> addToQueue(SongModel songModel);
|
|
||||||
Future<void> moveQueueItem(int oldIndex, int newIndex);
|
|
||||||
Future<void> removeQueueIndex(int index);
|
|
||||||
|
|
||||||
Future<void> playAlbum(AlbumModel albumModel);
|
|
||||||
Future<void> playArtist(ArtistModel artistModel, ShuffleMode shuffleMode);
|
|
||||||
}
|
|
|
@ -1,100 +1,157 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:audio_service/audio_service.dart';
|
||||||
|
|
||||||
import '../../domain/entities/album.dart';
|
import '../../domain/entities/album.dart';
|
||||||
import '../../domain/entities/artist.dart';
|
import '../../domain/entities/artist.dart';
|
||||||
import '../../domain/entities/loop_mode.dart';
|
import '../../domain/entities/loop_mode.dart';
|
||||||
import '../../domain/entities/playback_state.dart';
|
import '../../domain/entities/playback_state.dart' as entity;
|
||||||
import '../../domain/entities/shuffle_mode.dart';
|
import '../../domain/entities/shuffle_mode.dart';
|
||||||
import '../../domain/entities/song.dart';
|
import '../../domain/entities/song.dart';
|
||||||
import '../../domain/repositories/audio_repository.dart';
|
import '../../domain/repositories/audio_repository.dart';
|
||||||
import '../audio/audio_manager_contract.dart';
|
import '../audio/stream_constants.dart';
|
||||||
import '../models/album_model.dart';
|
import '../models/album_model.dart';
|
||||||
import '../models/artist_model.dart';
|
import '../models/artist_model.dart';
|
||||||
|
import '../models/playback_state_model.dart';
|
||||||
import '../models/song_model.dart';
|
import '../models/song_model.dart';
|
||||||
|
|
||||||
|
typedef Conversion<S, T> = T Function(S);
|
||||||
|
|
||||||
class AudioRepositoryImpl implements AudioRepository {
|
class AudioRepositoryImpl implements AudioRepository {
|
||||||
AudioRepositoryImpl(this._audioManager);
|
AudioRepositoryImpl(this._audioHandler);
|
||||||
|
|
||||||
final AudioManager _audioManager;
|
final AudioHandler _audioHandler;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<Song> get currentSongStream => _audioManager.currentSongStream;
|
Stream<SongModel> get currentSongStream => _filterStream<MediaItem, SongModel>(
|
||||||
|
_audioHandler.mediaItem.stream,
|
||||||
|
(MediaItem mi) => SongModel.fromMediaItem(mi),
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<PlaybackState> get playbackStateStream => _audioManager.playbackStateStream;
|
Stream<entity.PlaybackState> get playbackStateStream => _filterStream(
|
||||||
|
_audioHandler.playbackState.stream,
|
||||||
|
(PlaybackState ps) => PlaybackStateModel.fromASPlaybackState(ps),
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<int> get currentPositionStream => _audioManager.currentPositionStream;
|
Stream<int> get currentPositionStream => _position().distinct();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> playSong(int index, List<Song> songList) async {
|
Future<void> playSong(int index, List<Song> songList) async {
|
||||||
final List<SongModel> songModelList = songList.map((song) => song as SongModel).toList();
|
|
||||||
|
|
||||||
if (0 <= index && index < songList.length) {
|
if (0 <= index && index < songList.length) {
|
||||||
await _audioManager.playSong(index, songModelList);
|
final List<String> context = songList.map((s) => s.path).toList();
|
||||||
|
await _audioHandler.customAction(PLAY_WITH_CONTEXT, {'CONTEXT': context, 'INDEX': index});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> play() async {
|
Future<void> play() async {
|
||||||
await _audioManager.play();
|
_audioHandler.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> pause() async {
|
Future<void> pause() async {
|
||||||
await _audioManager.pause();
|
await _audioHandler.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> skipToNext() async {
|
Future<void> skipToNext() async {
|
||||||
await _audioManager.skipToNext();
|
await _audioHandler.skipToNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> skipToPrevious() async {
|
Future<void> skipToPrevious() async {
|
||||||
await _audioManager.skipToPrevious();
|
await _audioHandler.skipToPrevious();
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> setShuffleMode(ShuffleMode shuffleMode) async {
|
|
||||||
await _audioManager.setShuffleMode(shuffleMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> shuffleAll() async {
|
|
||||||
await _audioManager.shuffleAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> addToQueue(Song song) async {
|
|
||||||
await _audioManager.addToQueue(song as SongModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> moveQueueItem(int oldIndex, int newIndex) async {
|
|
||||||
await _audioManager.moveQueueItem(oldIndex, newIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> removeQueueIndex(int index) async {
|
|
||||||
await _audioManager.removeQueueIndex(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> setLoopMode(LoopMode loopMode) async {
|
|
||||||
await _audioManager.setLoopMode(loopMode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setIndex(int index) async {
|
Future<void> setIndex(int index) async {
|
||||||
await _audioManager.setIndex(index);
|
await _audioHandler.customAction(SET_INDEX, {'INDEX': index});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setShuffleMode(ShuffleMode shuffleMode) async {
|
||||||
|
await _audioHandler.customAction(SET_SHUFFLE_MODE, {'SHUFFLE_MODE': shuffleMode});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setLoopMode(LoopMode loopMode) async {
|
||||||
|
await _audioHandler.customAction(SET_LOOP_MODE, {'LOOP_MODE': loopMode});
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<T> _filterStream<S, T>(Stream<S> stream, Conversion<S, T> fn) async* {
|
||||||
|
T lastItem;
|
||||||
|
|
||||||
|
await for (final S item in stream) {
|
||||||
|
final T newItem = fn(item);
|
||||||
|
if (newItem != lastItem) {
|
||||||
|
lastItem = newItem;
|
||||||
|
yield newItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<int> _position() async* {
|
||||||
|
PlaybackState state;
|
||||||
|
DateTime updateTime;
|
||||||
|
Duration statePosition;
|
||||||
|
|
||||||
|
// TODO: should this class get an init method for this?
|
||||||
|
_audioHandler.playbackState.stream.listen((currentState) {
|
||||||
|
state = currentState;
|
||||||
|
updateTime = currentState?.updateTime;
|
||||||
|
statePosition = currentState?.position;
|
||||||
|
});
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (statePosition != null && updateTime != null && state != null) {
|
||||||
|
if (state.playing) {
|
||||||
|
yield statePosition.inMilliseconds +
|
||||||
|
(DateTime.now().millisecondsSinceEpoch - updateTime.millisecondsSinceEpoch);
|
||||||
|
} else {
|
||||||
|
yield statePosition.inMilliseconds;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
yield 0;
|
||||||
|
}
|
||||||
|
await Future.delayed(const Duration(milliseconds: 200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> shuffleAll() async {
|
||||||
|
await _audioHandler.customAction(SHUFFLE_ALL, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> addToQueue(Song song) async {
|
||||||
|
await _audioHandler.addQueueItem((song as SongModel).toMediaItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> moveQueueItem(int oldIndex, int newIndex) async {
|
||||||
|
await _audioHandler.customAction(MOVE_QUEUE_ITEM, {
|
||||||
|
'OLD_INDEX': oldIndex,
|
||||||
|
'NEW_INDEX': newIndex,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> removeQueueIndex(int index) async {
|
||||||
|
await _audioHandler.removeQueueItemAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> playAlbum(Album album) async {
|
Future<void> playAlbum(Album album) async {
|
||||||
await _audioManager.playAlbum(album as AlbumModel);
|
await _audioHandler.customAction(PLAY_ALBUM, {'ALBUM': album as AlbumModel});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> playArtist(Artist artist, {ShuffleMode shuffleMode = ShuffleMode.none}) async {
|
Future<void> playArtist(Artist artist, {ShuffleMode shuffleMode = ShuffleMode.none}) async {
|
||||||
await _audioManager.playArtist(artist as ArtistModel, shuffleMode);
|
await _audioHandler.customAction(PLAY_ARTIST, {
|
||||||
|
'ARTIST': artist as ArtistModel,
|
||||||
|
'SHUFFLE_MODE': shuffleMode,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue