Initial commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
// 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');
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user