99 lines
3.3 KiB
Dart
99 lines
3.3 KiB
Dart
// lib/services/media_service.dart
|
|
|
|
import 'dart:typed_data';
|
|
import 'package:flutter/services.dart';
|
|
import '../models/media_info.dart';
|
|
|
|
// Uncomment when adding widgets:
|
|
// import 'package:home_widget/home_widget.dart';
|
|
|
|
class MediaService {
|
|
static const _methodChannel = MethodChannel('pt.ruifpb.openvinyl/media_control');
|
|
static const _eventChannel = EventChannel('pt.ruifpb.openvinyl/media_events');
|
|
|
|
Stream<MediaInfo>? _mediaStream;
|
|
|
|
Stream<MediaInfo> get mediaStream {
|
|
_mediaStream ??= _eventChannel
|
|
.receiveBroadcastStream()
|
|
.map(_parseEvent)
|
|
.where((info) => info != null)
|
|
.cast<MediaInfo>();
|
|
return _mediaStream!;
|
|
}
|
|
|
|
Future<bool> hasPermission() async {
|
|
try {
|
|
return await _methodChannel.invokeMethod<bool>('hasPermission') ?? false;
|
|
} on PlatformException catch (e) {
|
|
print('MediaService.hasPermission error: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<void> requestPermission() async {
|
|
try {
|
|
await _methodChannel.invokeMethod('requestPermission');
|
|
} on PlatformException catch (e) {
|
|
print('MediaService.requestPermission error: $e');
|
|
}
|
|
}
|
|
|
|
Future<MediaInfo> getCurrentMedia() async {
|
|
try {
|
|
final data = await _methodChannel.invokeMethod<Map>('getCurrentMedia');
|
|
if (data == null) return MediaInfo.empty;
|
|
return _parseMap(Map<String, dynamic>.from(data));
|
|
} on PlatformException catch (e) {
|
|
print('MediaService.getCurrentMedia error: $e');
|
|
return MediaInfo.empty;
|
|
}
|
|
}
|
|
|
|
/// Sends a play or pause command to the active MediaSession.
|
|
/// Android decides which based on the current playback state,
|
|
/// so this is a true toggle.
|
|
Future<void> playPause() async {
|
|
try {
|
|
await _methodChannel.invokeMethod('playPause');
|
|
} on PlatformException catch (e) {
|
|
print('MediaService.playPause error: $e');
|
|
}
|
|
}
|
|
|
|
// ─── Private helpers ──────────────────────────────────────────────────────
|
|
|
|
MediaInfo? _parseEvent(dynamic event) {
|
|
if (event == null) return null;
|
|
try {
|
|
final map = Map<String, dynamic>.from(event as Map);
|
|
final info = _parseMap(map);
|
|
// _pushToWidget(info); // uncomment when adding widgets
|
|
return info;
|
|
} catch (e) {
|
|
print('MediaService._parseEvent error: $e');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
MediaInfo _parseMap(Map<String, dynamic> map) {
|
|
Uint8List? albumArt;
|
|
if (map['albumArt'] != null) {
|
|
albumArt = Uint8List.fromList(List<int>.from(map['albumArt']));
|
|
}
|
|
return MediaInfo(
|
|
title: map['title'] as String? ?? 'Unknown Title',
|
|
artist: map['artist'] as String? ?? 'Unknown Artist',
|
|
album: map['album'] as String? ?? '',
|
|
albumArt: albumArt,
|
|
isPlaying: map['isPlaying'] as bool? ?? false,
|
|
);
|
|
}
|
|
|
|
// ── WIDGET HOOK ────────────────────────────────────────────────────────────
|
|
// Future<void> _pushToWidget(MediaInfo info) async {
|
|
// await HomeWidget.saveWidgetData('title', info.title);
|
|
// await HomeWidget.saveWidgetData('artist', info.artist);
|
|
// await HomeWidget.updateWidget(androidName: 'VinylWidgetReceiver');
|
|
// }
|
|
} |