Skip to content

Area Magnification on Mobile platforms #340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
| [x86_64 `.apk`](https://github.com/bluecherrydvr/unity/releases/download/v3.0.0-beta23/bluecherry-android-x86_64-release.apk) | | 🚧 **SOON** ~~Microsoft Store~~ | [Raw Executable `.tar.gz`](https://github.com/bluecherrydvr/unity/releases/download/v3.0.0-beta23/bluecherry-linux-x86_64.tar.gz) | |
| 🚧 **SOON** ~~Play Store~~ | | | [Fedora/Red Hat Linux `.rpm`](https://github.com/bluecherrydvr/unity/releases/download/v3.0.0-beta23/bluecherry-linux-x86_64.rpm) | |

Or download the latest release [here](https://github.com/bluecherrydvr/unity/releases/tag/bleeding_edge)*.
Or download the latest release [here](https://github.com/bluecherrydvr/unity/releases/tag/bleeding_edge)\*.

### Installation

Expand Down Expand Up @@ -174,13 +174,13 @@ We support multiple platforms and each platform uses its own rendering backend.
| ------------ | ----------------- | --------------- |
| Android | MPV | media_kit |
| iOS | MPV | media_kit |
| Windows | MPV | media_kit |
| MacOS | MPV | media_kit |
| Web | HTML5 | fvp |
| Windows | MDK | fvp |
| MacOS | MDK | fvp |
| Web | HTML5 | media_kit |
| Linux | MDK | fvp |
| Raspberry Pi | MDK | fvp |

MDK is used for Linux and Raspberry Pi because MPV has shown to be unstable on these platforms, causing crashes. Additionally, `fvp` doesn't require the user to install any additional dependencies.
MDK is used for Desktop platforms because MPV has shown to be unstable on these platforms, causing crashes. Additionally, `fvp` doesn't require the user to install any additional dependencies on Linux and Raspberry Pi.

### Build

Expand Down Expand Up @@ -221,3 +221,11 @@ When running on debug, you must disable the CORS policy in your browser. Note th
```bash
flutter run -d chrome --web-browser-flag "--disable-web-security"
```

### Running and debugging

If running on a desktop platform, it is possible to emulate a mobile platform by passing the `--dart-define="FORCE_MOBILE=true"` argument when running. This will force the app to adapt itself to the mobile layout. This will remove any desktop-specific features and will make the app look like a mobile app.

```bash
flutter run -d [windows|linux|macos] --dart-define="FORCE_MOBILE=true"
```
4 changes: 4 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ Future<void> main(List<String> args) async {
runApp(const SplashScreen());
}

if (kForceMobile) {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
}

DevHttpOverrides.configureCertificates();
API.initialize();
await UnityVideoPlayerInterface.instance.initialize();
Expand Down
9 changes: 6 additions & 3 deletions lib/screens/layouts/desktop/multicast_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import 'package:bluecherry_client/models/device.dart';
import 'package:bluecherry_client/providers/layouts_provider.dart';
import 'package:bluecherry_client/providers/settings_provider.dart';
import 'package:bluecherry_client/utils/constants.dart';
import 'package:bluecherry_client/utils/methods.dart';
import 'package:bluecherry_client/widgets/hover_button.dart';
import 'package:bluecherry_client/widgets/misc.dart';
import 'package:flutter/gestures.dart';
Expand All @@ -33,8 +34,9 @@ import 'package:unity_video_player/unity_video_player.dart';

class MulticastViewport extends StatefulWidget {
final Device? device;
final bool showMobileGrid;

const MulticastViewport({super.key, this.device});
const MulticastViewport({super.key, this.device, this.showMobileGrid = true});

@override
State<MulticastViewport> createState() => _MulticastViewportState();
Expand Down Expand Up @@ -187,13 +189,14 @@ class _MulticastViewportState extends State<MulticastViewport> {
(context, states) => SizedBox.expand(
child: IgnorePointer(
child:
states.isHovering
(isMobile && widget.showMobileGrid) ||
states.isHovering
? Container(
decoration: BoxDecoration(
border: Border.all(
color:
theme.colorScheme.secondary,
width: 2.25,
width: isMobile ? 0.5 : 2.25,
),
),
)
Expand Down
55 changes: 46 additions & 9 deletions lib/screens/players/live_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class _LivePlayerState extends State<LivePlayer> {

@override
Widget build(BuildContext context) {
if (isMobilePlatform) {
if (isMobile) {
return _MobileLivePlayer(
player: widget.player,
device: widget.device,
Expand Down Expand Up @@ -133,12 +133,14 @@ class _MobileLivePlayer extends StatefulWidget {
}

class __MobileLivePlayerState extends State<_MobileLivePlayer> {
bool overlay = true;
var overlay = true;
late UnityVideoFit fit =
widget.device.server.additionalSettings.videoFit ??
SettingsProvider.instance.kVideoFit.value;

late bool ptzEnabled = widget.ptzEnabled;
var showMagnificationGrid =
SettingsProvider.instance.kMatrixedZoomEnabled.value;

@override
void initState() {
Expand Down Expand Up @@ -197,8 +199,26 @@ class __MobileLivePlayerState extends State<_MobileLivePlayer> {
strokeWidth: 3.45,
),
)
else if (commands.isNotEmpty)
PTZData(commands: commands),
else ...[
if (showMagnificationGrid)
Positioned.fill(
child: Center(
child: AspectRatio(
aspectRatio:
controller.aspectRatio == 0 ||
controller.aspectRatio ==
double.infinity
? 16 / 9
: controller.aspectRatio,
child: MulticastViewport(
device: widget.device,
showMobileGrid: showMagnificationGrid,
),
),
),
),
if (commands.isNotEmpty) PTZData(commands: commands),
],
PositionedDirectional(
top: 0.0,
start: 0.0,
Expand Down Expand Up @@ -235,12 +255,29 @@ class __MobileLivePlayerState extends State<_MobileLivePlayer> {
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
CameraViewFitButton(
fit: fit,
onChanged: (newFit) {
setState(() => fit = newFit);
},
SquaredIconButton(
icon: Icon(
showMagnificationGrid
? Icons.grid_on_rounded
: Icons.grid_off_rounded,
),
tooltip:
showMagnificationGrid
? 'Disable magnification grid'
: 'Enable magnification grid',
onPressed:
() => setState(
() =>
showMagnificationGrid =
!showMagnificationGrid,
),
),
// CameraViewFitButton(
// fit: fit,
// onChanged: (newFit) {
// setState(() => fit = newFit);
// },
// ),
if (widget.device.hasPTZ)
PTZToggleButton(
ptzEnabled: ptzEnabled,
Expand Down
2 changes: 2 additions & 0 deletions lib/screens/settings/server_and_devices.dart
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,8 @@ class AreaMagnificationSettings extends StatelessWidget {
),
OptionsChooserTile<MatrixType>(
title: loc.defaultMatrixSize,
description:
'Double tap on the view to change the magnification area size',
icon: Icons.view_quilt,
value: settings.kMatrixSize.value,
values: MatrixType.values.map((size) {
Expand Down
4 changes: 4 additions & 0 deletions lib/utils/methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ Widget wrapExpandedIf(bool condition, {required Widget child}) {
return child;
}

/// Whether the app should force mobile mode. This is useful for testing mobile
/// specific UI elements on a desktop platform.
const kForceMobile = bool.fromEnvironment('FORCE_MOBILE', defaultValue: false);

/// Returns true if the app is running on a desktop platform. This is useful
/// for determining whether to show desktop-specific UI elements.
///
Expand Down
Loading