mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
casting works!
just need to add session key check and remote video controls
This commit is contained in:
parent
4d86773ffe
commit
f5ed1360e6
@ -119,6 +119,13 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
const [],
|
||||
);
|
||||
|
||||
useEffect(() {
|
||||
final asset = loadAsset(currentIndex.value);
|
||||
ref.read(castProvider.notifier).loadMedia(asset, false);
|
||||
}, [
|
||||
ref.watch(castProvider).isCasting,
|
||||
]);
|
||||
|
||||
void showInfo() {
|
||||
final asset = ref.read(currentAssetProvider);
|
||||
if (asset == null) {
|
||||
|
@ -14,6 +14,8 @@ class GCastRepository {
|
||||
void Function(CastSessionState)? onCastStatus;
|
||||
void Function(Map<String, dynamic>)? onCastMessage;
|
||||
|
||||
Map<String, dynamic>? _receiverStatus;
|
||||
|
||||
GCastRepository();
|
||||
|
||||
Future<void> connect(CastDevice device) async {
|
||||
@ -26,6 +28,9 @@ class GCastRepository {
|
||||
|
||||
_castSession?.messageStream.listen((message) {
|
||||
onCastMessage?.call(message);
|
||||
if (message['type'] == 'RECEIVER_STATUS') {
|
||||
_receiverStatus = message;
|
||||
}
|
||||
});
|
||||
|
||||
// open the default receiver
|
||||
@ -38,6 +43,14 @@ class GCastRepository {
|
||||
}
|
||||
|
||||
Future<void> disconnect() async {
|
||||
final sessionID =
|
||||
_receiverStatus?['status']['applications'][0]['sessionId'];
|
||||
|
||||
sendMessage(CastSession.kNamespaceReceiver, {
|
||||
'type': "STOP",
|
||||
"sessionId": sessionID,
|
||||
});
|
||||
|
||||
await _castSession?.close();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:cast/device.dart';
|
||||
import 'package:cast/session.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
@ -55,12 +56,6 @@ class GCastService implements ICastDestinationService {
|
||||
|
||||
void _onCastMessageCallback(Map<String, dynamic> message) {
|
||||
final msgType = message['type'];
|
||||
|
||||
print(message);
|
||||
|
||||
if (msgType == 'RECEIVER_STATUS') {
|
||||
print("Got receiver status");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> connect(CastDevice device) async {
|
||||
@ -99,8 +94,6 @@ class GCastService implements ICastDestinationService {
|
||||
|
||||
@override
|
||||
void loadMedia(Asset asset, bool reload) async {
|
||||
print("Casting media: ${asset.remoteId}");
|
||||
|
||||
if (!isConnected) {
|
||||
return;
|
||||
} else if (asset.remoteId == null) {
|
||||
@ -119,7 +112,7 @@ class GCastService implements ICastDestinationService {
|
||||
);
|
||||
|
||||
final unauthenticatedUrl = asset.isVideo
|
||||
? getOriginalUrlForRemoteId(
|
||||
? getPlaybackUrlForRemoteId(
|
||||
asset.remoteId!,
|
||||
)
|
||||
: getThumbnailUrlForRemoteId(
|
||||
@ -142,14 +135,12 @@ class GCastService implements ICastDestinationService {
|
||||
"type": "LOAD",
|
||||
"media": {
|
||||
"contentId": authenticatedURL,
|
||||
"streamType": "LIVE",
|
||||
"streamType": "BUFFERED",
|
||||
"contentType": mimeType,
|
||||
"contentUrl": authenticatedURL,
|
||||
},
|
||||
"autoplay": true,
|
||||
});
|
||||
|
||||
print("Sending message: $authenticatedURL");
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -73,6 +73,10 @@ String getThumbnailUrlForRemoteId(
|
||||
return '${Store.get(StoreKey.serverEndpoint)}/assets/$id/thumbnail?size=${type.value}';
|
||||
}
|
||||
|
||||
String getPlaybackUrlForRemoteId(final String id) {
|
||||
return '${Store.get(StoreKey.serverEndpoint)}/assets/$id/video/playback?';
|
||||
}
|
||||
|
||||
String getFaceThumbnailUrl(final String personId) {
|
||||
return '${Store.get(StoreKey.serverEndpoint)}/people/$personId/thumbnail';
|
||||
}
|
||||
|
@ -12,6 +12,14 @@ class CastDialog extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final castManager = ref.watch(castProvider);
|
||||
|
||||
bool isCurrentDevice(String deviceName) {
|
||||
return castManager.receiverName == deviceName && castManager.isCasting;
|
||||
}
|
||||
|
||||
bool isDeviceConnecting(String deviceName) {
|
||||
return castManager.receiverName == deviceName && !castManager.isCasting;
|
||||
}
|
||||
|
||||
return AlertDialog(
|
||||
title: const Text(
|
||||
"cast",
|
||||
@ -53,7 +61,7 @@ class CastDialog extends ConsumerWidget {
|
||||
title: Text(
|
||||
deviceName,
|
||||
style: TextStyle(
|
||||
color: castManager.receiverName == deviceName
|
||||
color: isCurrentDevice(deviceName)
|
||||
? context.colorScheme.primary
|
||||
: null,
|
||||
),
|
||||
@ -62,12 +70,22 @@ class CastDialog extends ConsumerWidget {
|
||||
type == CastDestinationType.googleCast
|
||||
? Icons.cast
|
||||
: Icons.cast_connected,
|
||||
color: isCurrentDevice(deviceName)
|
||||
? context.colorScheme.primary
|
||||
: null,
|
||||
),
|
||||
trailing: castManager.isCasting &&
|
||||
castManager.receiverName == deviceName
|
||||
trailing: isCurrentDevice(deviceName)
|
||||
? Icon(Icons.check, color: context.colorScheme.primary)
|
||||
: null,
|
||||
: isDeviceConnecting(deviceName)
|
||||
? const CircularProgressIndicator()
|
||||
: null,
|
||||
onTap: () {
|
||||
// dont accept taps if the device is already connected or is connecting now
|
||||
if (isDeviceConnecting(deviceName) ||
|
||||
castManager.isCasting) {
|
||||
return;
|
||||
}
|
||||
|
||||
ref.read(castProvider.notifier).connect(type, deviceObj);
|
||||
},
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user