network addition
This commit is contained in:
parent
3bd713d667
commit
2099d3d64d
27 changed files with 2237 additions and 40 deletions
92
lib/remote/remote_playback.dart
Normal file
92
lib/remote/remote_playback.dart
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import 'package:just_audio/just_audio.dart' show LoopMode;
|
||||
|
||||
import '../playback/playback_engine.dart';
|
||||
import '../subsonic/models.dart';
|
||||
import 'messages.dart';
|
||||
import 'remote_session.dart';
|
||||
|
||||
/// Map a wire [StateSnapshot] back into the app's [PlaybackState] so the UI can
|
||||
/// render a remote device's playback exactly as it renders local playback.
|
||||
PlaybackState playbackStateFromSnapshot(StateSnapshot s) => PlaybackState(
|
||||
queue: s.queue,
|
||||
currentIndex: s.currentIndex,
|
||||
playing: s.playing,
|
||||
position: Duration(milliseconds: s.positionMs),
|
||||
duration: Duration(milliseconds: s.durationMs),
|
||||
shuffle: s.shuffle,
|
||||
loop: LoopMode.values.firstWhere(
|
||||
(m) => m.name == s.loop,
|
||||
orElse: () => LoopMode.off,
|
||||
),
|
||||
supported: true,
|
||||
);
|
||||
|
||||
/// The command half of the facade while attached to another device: every
|
||||
/// [PlaybackCommands] call is serialized into a [RemoteCommand] and sent to the
|
||||
/// host, which applies it to *its* engine. Playback state comes back the other
|
||||
/// way as snapshots (see `remote_providers.dart`), so this proxy holds none.
|
||||
///
|
||||
/// Commands are fire-and-forget: LAN round-trips are sub-frame, and the host's
|
||||
/// next snapshot is the source of truth, so there is no optimistic local edit
|
||||
/// to reconcile.
|
||||
class RemotePlaybackProxy implements PlaybackCommands {
|
||||
RemotePlaybackProxy(this._session);
|
||||
|
||||
final RemoteSession _session;
|
||||
|
||||
@override
|
||||
Future<void> playSongs(List<Song> songs, {int startIndex = 0}) async =>
|
||||
_session.send(RemoteCommand.playSongs(songs, startIndex: startIndex));
|
||||
|
||||
@override
|
||||
Future<void> jumpTo(int index) async =>
|
||||
_session.send(RemoteCommand.jumpTo(index));
|
||||
|
||||
@override
|
||||
Future<void> playNext(Song song) async =>
|
||||
_session.send(RemoteCommand.playNext(song));
|
||||
|
||||
@override
|
||||
Future<void> addToQueue(Song song) async =>
|
||||
_session.send(RemoteCommand.addToQueue(song));
|
||||
|
||||
@override
|
||||
Future<void> removeAt(int index) async =>
|
||||
_session.send(RemoteCommand.removeAt(index));
|
||||
|
||||
@override
|
||||
Future<void> reorderQueue(int oldIndex, int newIndex) async =>
|
||||
_session.send(RemoteCommand.reorder(oldIndex, newIndex));
|
||||
|
||||
@override
|
||||
Future<void> togglePlayPause() async =>
|
||||
_session.send(const RemoteCommand.playPause());
|
||||
|
||||
@override
|
||||
Future<void> next() async => _session.send(const RemoteCommand.next());
|
||||
|
||||
@override
|
||||
Future<void> previous() async =>
|
||||
_session.send(const RemoteCommand.previous());
|
||||
|
||||
@override
|
||||
Future<void> seek(Duration position) async =>
|
||||
_session.send(RemoteCommand.seek(position.inMilliseconds));
|
||||
|
||||
@override
|
||||
Future<void> toggleShuffle() async =>
|
||||
_session.send(const RemoteCommand.toggleShuffle());
|
||||
|
||||
@override
|
||||
Future<void> cycleLoop() async =>
|
||||
_session.send(const RemoteCommand.cycleLoop());
|
||||
|
||||
@override
|
||||
Future<void> retry() async => _session.send(const RemoteCommand.retry());
|
||||
|
||||
@override
|
||||
void resyncFromPlayer() {
|
||||
// No-op: the remote device owns the player; we receive its state pushed to
|
||||
// us and have no local playhead to re-read.
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue