Skip to content

Commit

Permalink
Servers (bluecherrydvr#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdlukaa authored Oct 13, 2023
2 parents 8def463 + 427e0b7 commit fbc5cfb
Show file tree
Hide file tree
Showing 30 changed files with 895 additions and 686 deletions.
16 changes: 14 additions & 2 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
"configureDescription": "Setup a connection to your remote DVR server",
"hostname": "Hostname",
"port": "Port",
"name": "Name",
"rtspPort": "RTSP Port",
"serverName": "Server Name",
"username": "Username",
"password": "Password",
"savePassword": "Save password",
"showPassword": "Show password",
"hidePassword": "Hide password",
"useDefault": "Use Default",
"connect": "Connect",
"connectAutomaticallyAtStartup": "Connect automatically at startup",
Expand All @@ -26,7 +29,7 @@
"tip1": "Use the buttons above the live view to create, save and switch layouts - even with cameras from multiple servers.",
"tip2": "Double-click on a server to open its configuration page in a new window, where you can configure cameras and recordings.",
"tip3": "Click the events icon to open the history and watch or save recordings.",
"errorTextField": "{field} is not entered.",
"errorTextField": "{field} must not be empty.",
"@errorTextField": {
"placeholders": {
"field": {
Expand All @@ -44,6 +47,14 @@
}
},
"serverNotAddedErrorDescription": "Please check the entered details and ensure the server is online.\n\nIf you are connecting remote, make sure the 7001 and 7002 ports are open to the Bluecherry server!",
"serverAlreadyAdded": "The {serverName} server is already added",
"@serverAlreadyAdded": {
"placeholders": {
"serverName": {
"type": "String"
}
}
},
"noServersAvailable": "No servers available",
"error": "Error",
"videoError": "An error happened while trying to play the video.",
Expand All @@ -63,6 +74,7 @@
"removeFromView": "Remove from view",
"addToView": "Add to view",
"addAllToView": "Add all to view",
"removeAllFromView": "Remove all from view",
"eventBrowser": "Events History",
"eventsTimeline": "Timeline of Events",
"server": "Server",
Expand Down
14 changes: 13 additions & 1 deletion lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
"configureDescription": "Configurons une connexion à votre serveur DVR distant",
"hostname": "Nom d'hôte",
"port": "Port",
"name": "Nom",
"rtspPort": "RTSP Port",
"serverName": "Server Name",
"username": "Nom d'utilisateur",
"password": "Mot de passe",
"savePassword": "Sauvegarder mot de passe",
"showPassword": "Show password",
"hidePassword": "Hide password",
"useDefault": "Par défaut",
"connect": "Connecter",
"connectAutomaticallyAtStartup": "Connecter automatiquement au démarrage",
Expand Down Expand Up @@ -40,6 +43,14 @@
}
},
"serverNotAddedErrorDescription": "Please check the entered details and ensure the server is online.\n\nIf you are connecting remote, make sure the 7001 and 7002 ports are open to the Bluecherry server!",
"serverAlreadyAdded": "The {serverName} server is already added",
"@serverAlreadyAdded": {
"placeholders": {
"serverName": {
"type": "String"
}
}
},
"noServersAvailable": "Aucun serveur disponible",
"error": "Erreur",
"videoError": "An error happened while trying to play the video.",
Expand All @@ -59,6 +70,7 @@
"removeFromView": "Retirer de la vue",
"addToView": "Ajouter à la vue",
"addAllToView": "Add all to view",
"removeAllFromView": "Remove all from view",
"eventBrowser": "Historique d'événements",
"eventsTimeline": "Timeline of Events",
"server": "Serveur",
Expand Down
14 changes: 13 additions & 1 deletion lib/l10n/app_pl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
"configureDescription": "Ustawienia połączenia ze zdalnym serwerem DVR",
"hostname": "Nazwa hosta",
"port": "Port",
"name": "Nazwa",
"rtspPort": "RTSP Port",
"serverName": "Server Name",
"username": "Nazwa użytkownika",
"password": "Hasło",
"savePassword": "Zapisz hasło",
"showPassword": "Show password",
"hidePassword": "Hide password",
"useDefault": "Użyj wartości domyślnych",
"connect": "Połącz",
"connectAutomaticallyAtStartup": "Połącz automatycznie przy uruchomieniu",
Expand Down Expand Up @@ -44,6 +47,14 @@
}
},
"serverNotAddedErrorDescription": "Sprawdź wprowadzone dane i upewnij się, że serwer jest online.\n\nJeśli łączysz się zdalnie to upewnij się, że porty na serwerzy Blueberry: 7001 i 7002, są otwarte!",
"serverAlreadyAdded": "The {serverName} server is already added",
"@serverAlreadyAdded": {
"placeholders": {
"serverName": {
"type": "String"
}
}
},
"noServersAvailable": "Brak dostępnych serwerów",
"error": "Błąd",
"videoError": "An error happened while trying to play the video.",
Expand All @@ -63,6 +74,7 @@
"removeFromView": "Usuń z widoku",
"addToView": "Dodaj do widoku",
"addAllToView": "Dodaj wszystkie do widoku",
"removeAllFromView": "Remove all from view",
"eventBrowser": "Historia zdarzeń",
"eventsTimeline": "Oś czasu zdarzeń",
"server": "Serwer",
Expand Down
14 changes: 13 additions & 1 deletion lib/l10n/app_pt.arb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
"configureDescription": "Configure uma conexão com seu servidor DVR remoto",
"hostname": "Hostname",
"port": "Porta",
"name": "Nome",
"rtspPort": "Porta RTSP",
"serverName": "Nome do servidor",
"username": "Nome de usuário",
"password": "Senha",
"savePassword": "Salvar senha",
"showPassword": "Mostrar senha",
"hidePassword": "Ocultar senha",
"useDefault": "Usar Padrão",
"connect": "Conectar",
"connectAutomaticallyAtStartup": "Conectar automaticamente ao iniciar",
Expand Down Expand Up @@ -44,6 +47,14 @@
}
},
"serverNotAddedErrorDescription": "Por favor verifique os dados inseridos e certifique-se que o servidor está online.\n\nSe você está conectando remotamente, certifique-se que as portas 7001 e 7002 estão abertas para o servidor Bluecherry!",
"serverAlreadyAdded": "O {serverName} servidor já foi adicionado.",
"@serverAlreadyAdded": {
"placeholders": {
"serverName": {
"type": "String"
}
}
},
"noServersAvailable": "Nenhum servidor disponível.",
"error": "Erro",
"videoError": "Ocorreu um erro ao tentar reproduzir o vídeo.",
Expand All @@ -63,6 +74,7 @@
"removeFromView": "Remover do layout",
"addToView": "Adicionar ao layout",
"addAllToView": "Adicionar tudo ao layout",
"removeAllFromView": "Remover tudo do layout",
"eventBrowser": "Histórico de eventos",
"eventsTimeline": "Linha do tempo de eventos",
"server": "Servidor",
Expand Down
18 changes: 18 additions & 0 deletions lib/models/device.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import 'dart:convert';

import 'package:bluecherry_client/models/server.dart';
import 'package:bluecherry_client/providers/server_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;

Expand Down Expand Up @@ -68,6 +69,23 @@ class Device {

String get uri => 'live/$id';

String get uuid {
return '${server.ip}:${server.port}/$id';
}

static Device fromUUID(String uuid) {
final serverIp = uuid.split(':')[0];
final serverPort = int.tryParse(uuid.split(':')[1].split('/')[0]) ?? -1;
final deviceId = int.tryParse(uuid.split(':')[1].split('/')[1]) ?? -1;

final server = ServersProvider.instance.servers.firstWhere(
(s) => s.ip == serverIp && s.port == serverPort,
orElse: Server.dump,
);

return server.devices.firstWhere((d) => d.id == deviceId);
}

factory Device.fromServerJson(Map map, Server server) {
return Device(
map['device_name'],
Expand Down
5 changes: 3 additions & 2 deletions lib/models/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

import 'package:bluecherry_client/models/device.dart';
import 'package:bluecherry_client/utils/constants.dart';

/// A [Server] added by a user.
class Server {
Expand Down Expand Up @@ -52,7 +53,7 @@ class Server {
this.login,
this.password,
this.devices, {
this.rtspPort = 7002,
this.rtspPort = kDefaultRTSPPort,
this.serverUUID,
this.cookie,
this.savePassword = false,
Expand All @@ -68,7 +69,7 @@ class Server {
this.login = 'admin',
this.password = 'admin',
this.devices = const [],
this.rtspPort = 7002,
this.rtspPort = kDefaultRTSPPort,
this.serverUUID,
this.cookie,
this.savePassword = false,
Expand Down
10 changes: 5 additions & 5 deletions lib/providers/desktop_view_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class DesktopViewProvider extends ChangeNotifier {
await _restore();
// Create video player instances for the device tiles already present in the view (restored from cache).
for (final device in currentLayout.devices) {
UnityPlayers.players[device] = UnityPlayers.forDevice(device);
UnityPlayers.players[device.uuid] = UnityPlayers.forDevice(device);
}
}
}
Expand Down Expand Up @@ -118,7 +118,7 @@ class DesktopViewProvider extends ChangeNotifier {
}
}

UnityPlayers.players[device] ??= UnityPlayers.forDevice(device);
UnityPlayers.players[device.uuid] ??= UnityPlayers.forDevice(device);
currentLayout.devices.add(device);
debugPrint('Added $device');

Expand All @@ -133,7 +133,7 @@ class DesktopViewProvider extends ChangeNotifier {
if (!UnityPlayers.players.containsKey(device)) return;
if (!layouts
.any((layout) => layout.devices.any((d) => d.id == device.id))) {
UnityPlayers.releaseDevice(device);
UnityPlayers.releaseDevice(device.uuid);
}
}

Expand All @@ -152,7 +152,7 @@ class DesktopViewProvider extends ChangeNotifier {
/// Removes all the [devices] provided
///
/// This is usually used when a server is deleted
Future<void> removeDevices(List<Device> devices) {
Future<void> removeDevices(Iterable<Device> devices) {
for (final layout in layouts) {
layout.devices.removeWhere(
(d1) => devices.any((d2) => d1.uri == d2.uri),
Expand Down Expand Up @@ -232,7 +232,7 @@ class DesktopViewProvider extends ChangeNotifier {
_currentLayout = layoutIndex;

for (final device in currentLayout.devices) {
UnityPlayers.players[device] ??= UnityPlayers.forDevice(device);
UnityPlayers.players[device.uuid] ??= UnityPlayers.forDevice(device);
}

notifyListeners();
Expand Down
10 changes: 3 additions & 7 deletions lib/providers/events_playback_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,27 +73,23 @@ class EventsProvider extends ChangeNotifier {
}
}

static String idForDevice(Device device) {
return '${device.server.ip}:${device.server.port}/${device.name}';
}

Future<void> clear() {
selectedIds.clear();
return _save();
}

bool contains(Device device) {
return selectedIds.contains(idForDevice(device));
return selectedIds.contains(device.uuid);
}

Future<void> add(Device device) {
selectedIds.add(idForDevice(device));
selectedIds.add(device.uuid);

return _save();
}

Future<void> remove(Device device) {
selectedIds.remove(idForDevice(device));
selectedIds.remove(device.uuid);

return _save();
}
Expand Down
28 changes: 14 additions & 14 deletions lib/providers/mobile_view_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class MobileViewProvider extends ChangeNotifier {
// Create video player instances for the device tiles already present in the view (restored from cache).
for (final device in current) {
if (device != null) {
UnityPlayers.players[device] = UnityPlayers.forDevice(device);
UnityPlayers.players[device.uuid] = UnityPlayers.forDevice(device);
}
}
}
Expand All @@ -115,15 +115,15 @@ class MobileViewProvider extends ChangeNotifier {
final items = devices[value]!;
// Find the non-common i.e. new device tiles in this tab & create a new video player for them.
for (final device in items) {
if (!UnityPlayers.players.keys.contains(device) && device != null) {
UnityPlayers.players[device] = UnityPlayers.forDevice(device);
if (device != null && !UnityPlayers.players.keys.contains(device.uuid)) {
UnityPlayers.players[device.uuid] = UnityPlayers.forDevice(device);
}
}
// Remove & dispose the video player instances that will not be used in this new tab.
UnityPlayers.players.removeWhere((key, value) {
final result = items.contains(key);
UnityPlayers.players.removeWhere((deviceUUID, player) {
final result = items.contains(Device.fromUUID(deviceUUID));
if (!result) {
value
player
..release()
..dispose();
}
Expand All @@ -146,9 +146,9 @@ class MobileViewProvider extends ChangeNotifier {
// Only dispose if it was the only instance available.
// If some other tile exists showing same camera device, then don't dispose the video player controller.
if (count == 1) {
UnityPlayers.players[device]?.release();
UnityPlayers.players[device]?.dispose();
UnityPlayers.players.remove(device);
UnityPlayers.players[device?.uuid]?.release();
UnityPlayers.players[device?.uuid]?.dispose();
UnityPlayers.players.remove(device?.uuid);
}
// Remove.
devices[tab]![index] = null;
Expand All @@ -161,7 +161,7 @@ class MobileViewProvider extends ChangeNotifier {
// Only create new video player instance, if no other camera tile in the same tab is showing the same camera device.
if (!devices[tab]!.contains(device)) {
debugPrint('Added $device');
UnityPlayers.players[device] = UnityPlayers.forDevice(device);
UnityPlayers.players[device.uuid] = UnityPlayers.forDevice(device);
}
devices[tab]![index] = device;
notifyListeners();
Expand All @@ -178,13 +178,13 @@ class MobileViewProvider extends ChangeNotifier {
// Only dispose if it was the only instance available.
// If some other tile exists showing same camera device, then don't dispose the video player controller.
if (count == 1) {
await UnityPlayers.players[current]?.release();
UnityPlayers.players[current]?.dispose();
UnityPlayers.players.remove(current);
await UnityPlayers.players[current?.uuid]?.release();
UnityPlayers.players[current?.uuid]?.dispose();
UnityPlayers.players.remove(current?.uuid);
}
if (!devices[tab]!.contains(device)) {
debugPrint('Replaced $device');
UnityPlayers.players[device] = UnityPlayers.forDevice(device);
UnityPlayers.players[device.uuid] = UnityPlayers.forDevice(device);
}
// Save the new [device] at the position.
devices[tab]![index] = device;
Expand Down
9 changes: 9 additions & 0 deletions lib/providers/server_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import 'package:bluecherry_client/providers/mobile_view_provider.dart';
import 'package:bluecherry_client/utils/constants.dart';
import 'package:bluecherry_client/utils/methods.dart';
import 'package:bluecherry_client/utils/storage.dart';
import 'package:bluecherry_client/utils/video_player.dart';
import 'package:flutter/foundation.dart';

/// This class manages & saves (caching) the currently added [Server]s by the user.
Expand Down Expand Up @@ -141,9 +142,17 @@ class ServersProvider extends ChangeNotifier {
servers.firstWhere((s) => s.ip == server.ip && s.port == server.port);
final serverIndex = servers.indexOf(s);

for (final device in server.devices) {
device.server = server;
if (UnityPlayers.players.keys.contains(device.uuid)) {
UnityPlayers.reloadDevice(device);
}
}

servers[serverIndex] = server;

await _save();
UnityPlayers.reloadAll();
}

/// If [ids] is provided, only the provided ids will be refreshed
Expand Down
Loading

0 comments on commit fbc5cfb

Please sign in to comment.