Media buttons on HID remotes (USB/Bluetooth keyboards, common on Android TV) are delivered as key events to the focused window instead of the MediaSession, so they only worked while the app was backgrounded. A global handler now routes play/pause, next/previous, stop, and fast-forward/rewind to the live music session anywhere in the app and consumes the key burst, so a press can neither leak to Android's fallback MediaSession dispatch nor start a focused library item. Same lifecycle as the OS media session; video playback never coexists with it because claiming video disposes the music session first. close #1948
20 lines
1007 B
Dart
20 lines
1007 B
Dart
import 'package:flutter/services.dart';
|
|
|
|
/// A user transport intent. `play`/`pause` are *directed* — a remote with
|
|
/// dedicated buttons must not flip the state it explicitly asked for.
|
|
enum TransportCommand { play, pause, toggle }
|
|
|
|
/// Maps hardware media transport keys to their intent. Returns null for keys
|
|
/// that are not transport keys (including the configured play/pause hotkey,
|
|
/// which callers resolve to [TransportCommand.toggle] themselves).
|
|
///
|
|
/// Shared by the video player screen (foreground remote transport, #1375) and
|
|
/// the music hardware-transport handler (#1948); it deliberately lives outside
|
|
/// `lib/widgets/` so the music service layer does not import widget code.
|
|
TransportCommand? classifyTransportKey(LogicalKeyboardKey key) {
|
|
if (key == LogicalKeyboardKey.mediaPlay) return TransportCommand.play;
|
|
if (key == LogicalKeyboardKey.mediaPause) return TransportCommand.pause;
|
|
if (key == LogicalKeyboardKey.mediaPlayPause) return TransportCommand.toggle;
|
|
return null;
|
|
}
|