diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml index 03767d4..91d7a3e 100644 --- a/.github/workflows/flutter-build.yml +++ b/.github/workflows/flutter-build.yml @@ -319,7 +319,7 @@ jobs: find ./artifacts \( -name "app-release.apk" -o \ -name "app-release.aab" -o \ -name "netr-web.zip" -o \ - -name "netr-linux-x64.tar.gz" -o \ + -name "netr-linux-x64.tar.gz" -o \ -name "netr-linux-x64.pkg.tar.zst" -o \ -name "netr-linux-x64.pkg.tar.zst.sig" -o \ -name "netr-linux-x64.deb" -o \ diff --git a/build-app.bat b/build-app.bat deleted file mode 100644 index 7d09117..0000000 --- a/build-app.bat +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -echo ################################################# -echo # Building Apk # -echo ################################################# -call flutter build apk --split-per-abi -dir build\app\outputs\apk\release diff --git a/build-app.sh b/build-app.sh deleted file mode 100755 index ed701e3..0000000 --- a/build-app.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -set -e - -if [ $# -eq 0 ] -then - echo "Usage: $0 " - exit 1 -fi - -DEST="$1" -SOURCE=build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk - -mkdir -p "${DEST}" -flutter build apk --split-per-abi --verbose -VERSION=$(aapt dump badging "${SOURCE}" | \ - sed -e '/^package: /!d' \ - -e "s/.*versionCode='\([0-9]\+\)' .*/\1/") -cp -av "${SOURCE}" "${DEST}" -echo "{ \"version\":\"${VERSION}\" }" > "${DEST}/info.json" diff --git a/build-arch.sh b/build-arch.sh deleted file mode 100755 index 3494940..0000000 --- a/build-arch.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -set -e - -flutter build linux --release --verbose - -OS=Arch -ARCH=$(uname -m) -BUILD_DIR=build/netr-arch -DEST_DIR="/opt/netr" -DESKTOP_DIR="/usr/share/applications" -PIXMAP_DIR="/usr/share/pixmaps" -BIN_DIR="/usr/bin" -MY_DIR=$(dirname "$0") -APP_VER=$(/opt/flutter/bin/dart "$MY_DIR/version.dart") - -case $ARCH in - x86_64) - SARCH='x64' - ;; - *) - SARCH=$ARCH -esac - -rm -rf "$BUILD_DIR" -mkdir -p "$BUILD_DIR" -cat > "$BUILD_DIR/PKGBUILD" << EOF -# Maintainer: Neeraj J - -pkgname=netr -pkgver=${APP_VER} -pkgrel=1 -pkgdesc="A CCTV camera monitor App" -arch=('i686' 'x86_64') -depends=('vlc') -license=(custom) -options=(!strip) - -package() { - mkdir -vp "\$pkgdir$BIN_DIR" "\$pkgdir$DEST_DIR" "\$pkgdir$DESKTOP_DIR" "\$pkgdir$PIXMAP_DIR" - pwd - cp -av ../../../linux/netr.desktop "\$pkgdir$DESKTOP_DIR/netr.desktop" - cp -av ../../../icons/netr.png "\$pkgdir$PIXMAP_DIR" - cp -av ../../linux/$SARCH/release/bundle/* "\$pkgdir$DEST_DIR" - ln -s /opt/netr/netr "\$pkgdir$BIN_DIR" -} -EOF -cd "$BUILD_DIR" -makepkg -cf -cd - - diff --git a/build-debian.sh b/build-debian.sh deleted file mode 100755 index 6a5a8ad..0000000 --- a/build-debian.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -set -e - -flutter build linux --release --verbose - -OS=$(lsb_release -is) -RELEASE=$(lsb_release -cs) -ARCH=$(dpkg --print-architecture) -BUILD_DIR=build/netr-$OS-$RELEASE-$ARCH -DEB_DIR="$BUILD_DIR/DEBIAN" -DEST_DIR="$BUILD_DIR/opt/netr" -DESKTOP_DIR="$BUILD_DIR/usr/share/applications" -PIXMAP_DIR="$BUILD_DIR/usr/share/pixmaps" -BIN_DIR="$BUILD_DIR/usr/bin" -MY_DIR=$(dirname "$0") -APP_VER=$(dart "$MY_DIR/version.dart") - -case $ARCH in - amd64) - SARCH='x64' - ;; - *) - SARCH=$ARCH -esac - -rm -rf "$BUILD_DIR" -mkdir -vp "$DEB_DIR" "$BIN_DIR" "$DEST_DIR" "$DESKTOP_DIR" "$PIXMAP_DIR" -cat > "$DEB_DIR/control" << EOF -Package: netr -Maintainer: Neeraj J -Version: ${APP_VER} -Section: misc -Priority: optional -Standards-Version: ${APP_VER} -Architecture: $ARCH -Depends: vlc -Description: A CCTV camera monitor App -EOF -cp -av linux/netr.desktop "$DESKTOP_DIR/netr.desktop" -cp -av icons/netr.png "$PIXMAP_DIR" -cp -av build/linux/$SARCH/release/bundle/* "$DEST_DIR" -ln -s /opt/netr/netr "$BIN_DIR" -dpkg-deb --build "$BUILD_DIR" -rm -rf "$BIN_DIR" "$DEST_DIR" "$DESKTOP_DIR" "$PIXMAP_DIR" diff --git a/build-web.sh b/build-web.sh deleted file mode 100755 index d1862c0..0000000 --- a/build-web.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -e - -flutter build web --release --verbose --base-href /netr/ -rm -f netr-web.tar.xz -cd build/web && tar cvJf netr-web.tar.xz * && cd - diff --git a/build.bat b/build.bat deleted file mode 100644 index 3515d79..0000000 --- a/build.bat +++ /dev/null @@ -1,34 +0,0 @@ -@echo off - -echo ################################################# -echo # Building Windows Executable # -echo ################################################# -call flutter build windows --release -dir build\windows\runner\Release\netr.exe - -if exist "C:\Program Files (x86)\Resource Hacker\ResourceHacker.exe" ( -"C:\Program Files (x86)\Resource Hacker\ResourceHacker.exe" ^ - -open %cd%\build\windows\runner\Release\netr.exe ^ - -save %cd%\build\windows\runner\Release\netr.exe ^ - -action addskip ^ - -res %cd%\windows\runner\resources\app_icon.ico ^ - -mask ICONGROUP,MAINICON, -) else ( -echo "Please install resource hacker to change app icon from: http://www.angusj.com/resourcehacker/" -) - -echo ################################################# -echo # Building Windows Installer # -echo ################################################# -rem call flutter pub run msix:create -rem dir build\windows\runner\Release\netr.msix - -rmdir /q /s build\nsis -mkdir build\nsis -mkdir build\nsis\netr -copy windows\netr.nsi build\nsis -xcopy /a /s build\windows\runner\Release build\nsis\netr -cd build\nsis -"C:\Program Files (x86)\NSIS\makensis.exe" /V4 netr.nsi -cd ..\.. -rmdir /q /s build\nsis\netr diff --git a/images/vlc_icon.png b/images/vlc_icon.png deleted file mode 100644 index be7ad8b..0000000 Binary files a/images/vlc_icon.png and /dev/null differ diff --git a/lib/config.dart b/lib/config.dart deleted file mode 100644 index 9dc4e5f..0000000 --- a/lib/config.dart +++ /dev/null @@ -1,118 +0,0 @@ -const Map properties = { - 'upgrade': { - 'baseUrls': [ - 'http://192.168.1.10/apks/netr' - ], - 'fileName': 'app-armeabi-v7a-release.apk', - }, - 'defaultImageLocation': 'location1', - 'images': { - '/location1': { - 'client_id': '', - 'key': '', - 'secret': '', - 'refreshToken': - '', - }, - }, - 'ssh': { - 'location1': { - 'host': '', - 'port': '', - 'user': '', - 'privateKey': """ ------BEGIN RSA PRIVATE KEY----- -................... -................... ------END RSA PRIVATE KEY----- -""" - }, - 'location2': { - 'host': '', - 'port': '', - 'user': '', - 'privateKey': """ ------BEGIN RSA PRIVATE KEY----- -................... -................... ------END RSA PRIVATE KEY----- -""" - } - }, - 'cameras': { - 'camera1': { - 'user': '', - 'password': '', - 'default-access-point': 'location2', - 'streams': { - 'paths': { - 'high': '/Streaming/Channels/101/', - 'low': '/Streaming/Channels/102/', - }, - 'access-points': { - 'location1': { - 'host': '', - 'port': 554, - }, - 'location2': { - 'host': '', - 'port': 55541, - }, - }, - }, - 'archive': { - 'path': '/Streaming/tracks/101?starttime=', - 'access-points': { - 'location1': { - 'host': '', - 'port': 554, - }, - 'location2': { - 'host': '', - 'port': 55540, - }, - } - }, - }, - 'camera2': { - 'user': '', - 'password': '', - 'default-access-point': 'location2', - 'streams': { - 'paths': { - 'high': '/Streaming/Channels/101/', - 'low': '/Streaming/Channels/102/', - }, - 'access-points': { - 'location1': { - 'host': '', - 'port': 554, - }, - 'location2': { - 'host': '', - 'port': 55542, - }, - }, - }, - 'archive': { - 'path': '/Streaming/tracks/201?starttime=', - 'access-points': { - 'location1': { - 'host': '', - 'port': 554, - }, - 'location2': { - 'host': '', - 'port': 55540, - }, - } - } - } - }, - 'vlc': { - 'host': '', - 'port': '8080', - 'user': '', - 'password': '', - }, -}; diff --git a/lib/controllers/media_kit_controller.dart b/lib/controllers/media_kit_controller.dart deleted file mode 100644 index 902ce30..0000000 --- a/lib/controllers/media_kit_controller.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'dart:developer'; -import 'dart:ui'; - -import 'package:media_kit/media_kit.dart'; -import 'package:media_kit_video/media_kit_video.dart'; -import 'package:netr/controllers/video_player_controller_interface.dart'; - -class MediaKitController implements VideoPlayerControllerInterface { - MediaKitController(dataSource, {autoPlay = false}) - : playing = true, - player = Player() { - player.stream.buffering.listen( - (buffering) { - log('Buffering: $buffering'); - return _bufferingListener?.call(50); - }, - onError: _errorHandler, - onDone: () { - log('Buffering complete'); - _bufferingListener?.call(100); - }); - player.stream.playing.listen( - (playing) { - if (playing) { - _bufferingListener?.call(100); - return _playingListener?.call(); - } else { - return _stoppedListener?.call(); - } - }, - onError: _errorHandler, - onDone: () { - log("playback done"); - _stoppedListener?.call(); - }); - - player.stream.error.listen((error) { - log("Error during play: $error"); - _errorListener?.call("Unknown error: $error"); - }); - - controller = VideoController(player); - setMediaFromNetwork(dataSource, autoPlay: autoPlay); - } - - bool playing; - Player player; - late VideoController controller; - VoidCallback? _playingListener; - DoubleCallback? _bufferingListener; - VoidCallback? _stoppedListener; - ErrorCallback? _errorListener; - - void _errorHandler(Object error, StackTrace trace) { - log("Error [$error]: $trace"); - if (_errorListener != null) { - if (error.runtimeType == String) { - _errorListener!(error as String); - } else { - _errorListener!("Unknown error: $error"); - } - } - } - - @override - bool isInitialized() { - return true; - } - - @override - Future play() async { - playing = true; - return player.play(); - } - - @override - Future pause() async { - playing = false; - return player.pause(); - } - - @override - Future stop() async { - playing = false; - return player.stop(); - } - - @override - Future isPlaying() async { - return playing; - } - - @override - Future setMediaFromNetwork(String dataSource, {bool? autoPlay}) async { - player.open(Media(dataSource), play: autoPlay ?? false); - player.play(); - } - - @override - void addListener( - VoidCallback onInitListener, - DoubleCallback bufferingListener, - VoidCallback playingListener, - VoidCallback stoppedListener, - ErrorCallback errorListener) { - _bufferingListener = bufferingListener; - _playingListener = playingListener; - _stoppedListener = stoppedListener; - _errorListener = errorListener; - } - - @override - void removeListener() { - _playingListener = null; - _stoppedListener = null; - _errorListener = null; - } - - @override - Future dispose() async { - return player.dispose(); - } -} diff --git a/lib/controllers/video_player_controller_interface.dart b/lib/controllers/video_player_controller_interface.dart deleted file mode 100644 index f669963..0000000 --- a/lib/controllers/video_player_controller_interface.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:ui'; - -typedef ErrorCallback = void Function(String error); -typedef DoubleCallback = void Function(double value); - -abstract class VideoPlayerControllerInterface { - Future play(); - Future pause(); - Future stop(); - bool isInitialized(); - Future isPlaying(); - Future dispose(); - Future setMediaFromNetwork(String dataSource, {bool? autoPlay}); - void addListener( - VoidCallback onInitListener, - DoubleCallback bufferingListener, - VoidCallback playingListener, - VoidCallback stoppedListener, - ErrorCallback errorListener); - void removeListener(); -} diff --git a/lib/controllers/vlc_remote_controller.dart b/lib/controllers/vlc_remote_controller.dart deleted file mode 100644 index a637f80..0000000 --- a/lib/controllers/vlc_remote_controller.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'dart:convert'; -import 'dart:developer'; -import 'dart:ui'; - -import 'package:netr/config.dart'; -import 'package:http/http.dart' as http; -import 'package:netr/controllers/video_player_controller_interface.dart'; - -// Documentation: https://wiki.videolan.org/VLC_HTTP_requests/ -class VlcRemoteController implements VideoPlayerControllerInterface { - VlcRemoteController.network(this._url); - - String _url; - bool _isPlaying = false; - - @override - Future setMediaFromNetwork(String dataSource, { - bool? autoPlay, - }) async { - await _setStreamUrl(dataSource); - } - - @override - Future play() async { - String url = '/requests/status.xml?command=in_play&input=${Uri.encodeComponent(_url)}'; - await _processVlcUrl(url); - _isPlaying = true; - } - - @override - Future pause() async { - String path = '/requests/status.xml?command=pl_pause'; - await _processVlcUrl(path); - _isPlaying = false; - } - - @override - Future stop() async { - String path = '/requests/status.xml?command=pl_stop'; - await _processVlcUrl(path); - _isPlaying = false; - } - - @override - Future isPlaying() async { - return _isPlaying; - } - - Future _processVlcUrl(String path) async { - String url = - 'http://${properties['vlc']['host']}:${properties['vlc']['port']}$path'; - log('Url: $url'); - String basicAuth = 'Basic ${base64Encode(utf8.encode( - properties['vlc']['user'] + ':' + properties['vlc']['password']))}'; - try { - var contents = await http.read(Uri.parse(url), - headers: {'authorization': basicAuth}); - log(contents); - } on Exception catch (e) { - log('Error: $e'); - throw 'Failed to process request: $e'; - } - } - - Future _setStreamUrl(String dataSource) async { - _url = dataSource; - await play(); - } - - @override - void addListener(VoidCallback onInitListener, - DoubleCallback bufferingListener, - VoidCallback playingListener, - VoidCallback stoppedListener, - ErrorCallback errorListener) { - // - } - - @override - void removeListener() { - - } - - @override - bool isInitialized() { - return true; - } - - @override - Future dispose() async { - - } -} \ No newline at end of file diff --git a/lib/cubit/viewer/live_camera_view_cubit.dart b/lib/cubit/viewer/live_camera_view_cubit.dart index 9725b29..204e626 100644 --- a/lib/cubit/viewer/live_camera_view_cubit.dart +++ b/lib/cubit/viewer/live_camera_view_cubit.dart @@ -9,9 +9,9 @@ import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:netr/models/credential.dart'; import '../../models/camera.dart'; +import '../../models/credential.dart'; import '../mixin/camera_view_cubit_mixin.dart'; import 'camera_view_state.dart'; import 'view_state.dart'; diff --git a/lib/desktop_home_screen.dart b/lib/desktop_home_screen.dart index 135aca7..11282c3 100644 --- a/lib/desktop_home_screen.dart +++ b/lib/desktop_home_screen.dart @@ -9,10 +9,11 @@ import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:netr/application_life_cycle.dart'; -import 'package:netr/main_app.dart'; import 'package:window_manager/window_manager.dart'; +import 'application_life_cycle.dart'; +import 'main_app.dart'; + class DesktopHomeScreen extends StatefulWidget { const DesktopHomeScreen({super.key}); diff --git a/lib/helpers/camera_helper.dart b/lib/helpers/camera_helper.dart deleted file mode 100644 index aeadc51..0000000 --- a/lib/helpers/camera_helper.dart +++ /dev/null @@ -1,47 +0,0 @@ -typedef OnLoadHandler = void Function(); -typedef OnErrorHandler = void Function(String error); - -abstract class CameraHelper { - bool isInitialized = false; - OnLoadHandler onLoadHandler; - OnErrorHandler onErrorHandler; - - CameraHelper(this.onLoadHandler, this.onErrorHandler); - - Future init() async { - await load(); - } - - Future load(); - - List getCameras(String? videoQuality) { - if (isInitialized) { - return getCamerasInternal(videoQuality); - } - - throw "Not initialised"; - } - - bool doesCameraExist(String camera, String? videoQuality) { - List cameras = getCameras(videoQuality); - return cameras.contains(camera); - } - - List getTypes(String camera) { - if (isInitialized) { - return getTypesInternal(camera); - } - - throw "Not initialised"; - } - - String getDefaultType(); - - List getCamerasInternal(String? videoQuality); - - List getTypesInternal(String camera); - - String getDefaultLocation(String camera); - - List getLocations(String camera); -} diff --git a/lib/helpers/dropbox_camera_helper.dart b/lib/helpers/dropbox_camera_helper.dart deleted file mode 100644 index 56eba8f..0000000 --- a/lib/helpers/dropbox_camera_helper.dart +++ /dev/null @@ -1,131 +0,0 @@ -import 'dart:convert'; -import 'dart:developer'; - -import 'package:http/http.dart' as http; -import 'package:http/http.dart'; -import 'package:netr/config.dart'; -import 'package:netr/helpers/camera_helper.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -abstract class DropboxCameraHelper extends CameraHelper { - final int _maxApiRetries = 3; - String? _accessToken; - String location; - bool _initialized = false; - - DropboxCameraHelper(super.onLoadHandler, super.onErrorHandler) - : location = "/${properties['defaultImageLocation']}"; - - Future _authenticateUsingRefreshToken() async { - _initialized = true; - Response? response = - await _postDropboxRequestWithBasicAuthentication('/oauth2/token', { - 'grant_type': 'refresh_token', - 'refresh_token': properties['images'][location]['refreshToken'], - }); - - if (response == null) { - return false; - } else if (response.statusCode == 200) { - log('Successfully acquired access token'); - Map json = jsonDecode(response.body); - _accessToken = json['access_token']; - SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.setString('dropboxAccessToken', _accessToken!); - return true; - } else { - log('Error [${response.statusCode}]: ${response.body}'); - return false; - } - } - - Future _postDropboxRequestWithBasicAuthentication( - String url, Object body) async { - String key = properties['images'][location]['key']; - String secret = properties['images'][location]['secret']; - String authorization = "Basic ${base64Encode(utf8.encode('$key:$secret'))}"; - return _postDropboxRequest( - url, 'application/x-www-form-urlencoded', authorization, body); - } - - Future _postDropboxRequestWithAccessToken(String url, Object body, - [int retries = 1]) async { - if (!_initialized) { - await _authenticateUsingRefreshToken(); - } - - String authorization = 'Bearer $_accessToken'; - Response? response = - await _postDropboxRequest(url, 'application/json', authorization, body); - if (response == null) { - return response; - } else if (retries <= _maxApiRetries && - response.statusCode == 401 && - response.body.contains('expired_access_token')) { - log('Access Token has expired. Will try refreshing token ...'); - await _authenticateUsingRefreshToken(); - return _postDropboxRequestWithAccessToken(url, body, retries + 1); - } else { - return response; - } - } - - Future _postDropboxRequest( - String url, String contentType, String authorization, Object body) async { - try { - var headers = { - 'authorization': authorization, - 'content-type': contentType, - }; - return await http.post(Uri.parse('https://api.dropbox.com$url'), - headers: headers, body: body); - } catch (e) { - log('Error executing dropbox request [$url]: $e'); - return null; - } - } - - Future fileExists(path) async { - Response? response = await _postDropboxRequestWithAccessToken( - '/2/files/get_metadata', '{"path": "$path"}'); - - if (response == null) { - return false; - } else if (response.statusCode == 200) { - return true; - } else { - log('Error [${response.statusCode}]: ${response.body}'); - return false; - } - } - - Future getDropboxUrl(String sourcePath) async { - Response? response = await _postDropboxRequestWithAccessToken( - '/2/files/get_temporary_link', '{"path": "$sourcePath"}'); - if (response == null) { - return null; - } else if (response.statusCode == 200) { - Map json = jsonDecode(response.body); - String link = json['link'] as String; - log('Dropbox url is $link'); - return link; - } else { - log('Error [${response.statusCode}]: ${response.body}'); - return null; - } - } - - @override - String getDefaultLocation(String camera) { - return properties['defaultImageLocation']; - } - - @override - List getLocations(String camera) { - List locations = []; - properties['images'].keys.forEach((location) { - locations.add(location); - }); - return locations; - } -} diff --git a/lib/helpers/historical_photo_camera_helper.dart b/lib/helpers/historical_photo_camera_helper.dart deleted file mode 100644 index 5bd5c5f..0000000 --- a/lib/helpers/historical_photo_camera_helper.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'dart:developer'; - -import 'package:intl/intl.dart'; -import 'package:netr/helpers/photo_camera_helper.dart'; - -class HistoricalPhotoCameraHelper extends PhotoCameraHelper { - HistoricalPhotoCameraHelper(super.onLoadHandler, super.onErrorHandler); - - Future getHistoricalImageUrl( - DateTime dateTime, String camera, int index, String type) async { - String formattedDate = - DateFormat('yyyy-MM-dd/yyyy-MM-dd-HH:mm').format(dateTime); - String sourcePath = - '$location/$formattedDate-$type-${index + 1}-$camera.jpg'; - - try { - final String? link = await getDropboxUrl(sourcePath); - log('$sourcePath => $link!'); - return link; - } on Exception catch (e) { - log('Error occurred: $e'); - return null; - } - } -} diff --git a/lib/helpers/photo_camera_helper.dart b/lib/helpers/photo_camera_helper.dart deleted file mode 100644 index e24074c..0000000 --- a/lib/helpers/photo_camera_helper.dart +++ /dev/null @@ -1,103 +0,0 @@ -import 'dart:convert'; -import 'dart:async'; -import 'dart:developer'; - -import 'package:http/http.dart' as http; -import 'package:netr/helpers/dropbox_camera_helper.dart'; -import 'package:netr/models/latest_info.dart'; - -class PhotoCameraHelper extends DropboxCameraHelper { - static const String _latestInfoFileName = 'latest.json'; - - LatestInfo? _latestInfo; - - PhotoCameraHelper(super.onLoadHandler, super.onErrorHandler); - - @override - Future load() async { - await _loadLatestJson(); - _checkAndRerunLoadLatestJson(true); - } - - Future _checkAndRerunLoadLatestJson(bool first) async { - if (_latestInfo == null) { - log('Dropbox not initialized: Will retry'); - Timer(Duration(seconds: first ? 10 : 60), () async { - _loadLatestJson(); - _checkAndRerunLoadLatestJson(false); - }); - } else { - isInitialized = true; - onLoadHandler(); - } - } - - Future reload() async { - await _loadLatestJson(); - } - - @override - String getDefaultType() { - return 'high'; - } - - @override - List getCamerasInternal(String? videoQuality) { - return _latestInfo?.cameras ?? []; - } - - @override - List getTypesInternal(String camera) { - return _latestInfo?.types ?? []; - } - - String _getUrl(String camera, String type) { - int index = _latestInfo?.cameras.indexOf(camera) ?? 0; - return "${_latestInfo?.dest}/${_latestInfo?.time}-$type-${index + 1}-$camera.jpg"; - } - - Future _loadLatestJson() async { - var sourcePath = '$location/$_latestInfoFileName'; - - final String? link = await getDropboxUrl(sourcePath); - - if (link == null) { - return; - } - - try { - var contents = await http.read(Uri.parse(link)); - _latestInfo = LatestInfo.fromJson(jsonDecode(contents)); - } on Exception catch (e) { - log('Error: $e'); - onErrorHandler('Error loading camera configuration: $e'); - } - } - - Future getImageUrl(String camera) async { - if (_latestInfo == null) { - await _loadLatestJson(); - if (_latestInfo == null) { - return null; - } - } - - String sourcePath = _getUrl(camera, 'high'); - final String? link = await getDropboxUrl(sourcePath); - return link; - } - - int getFrequency(String camera) { - if (_latestInfo!.minCameras.contains(camera)) { - return _latestInfo!.minCameraFrequency; - } else if (_latestInfo!.cameras.contains(camera)) { - return _latestInfo!.frequency; - } - - throw UnsupportedError('$camera is not supported'); - } - - String getLatestImageTime() { - return _latestInfo!.time; - } -} diff --git a/lib/helpers/stream_camera_helper.dart b/lib/helpers/stream_camera_helper.dart deleted file mode 100644 index 755849c..0000000 --- a/lib/helpers/stream_camera_helper.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:netr/config.dart'; -import 'package:netr/helpers/camera_helper.dart'; -import 'package:netr/tool.dart'; - -class StreamCameraHelper extends CameraHelper { - StreamCameraHelper(this.videoStreamMode, OnLoadHandler onLoadHandler, - OnErrorHandler onErrorHandler) - : super(onLoadHandler, onErrorHandler); - - VideoStreamMode? videoStreamMode; - - @override - Future load() async { - isInitialized = true; - onLoadHandler(); - } - - @override - String getDefaultType() { - return 'low'; - } - - @override - List getCamerasInternal(String? videoQuality) { - List cameras = []; - properties['cameras'].keys.forEach((camera) { - if (videoQuality == null || - properties['cameras'][camera]['streams']['paths'] - .containsKey(videoQuality) || - (videoQuality == 'archive' && - properties['cameras'][camera].containsKey(videoQuality))) { - cameras.add(camera); - } - }); - return cameras; - } - - @override - List getTypesInternal(String camera) { - List types = []; - properties['cameras'][camera]['streams']['paths'].keys.forEach((type) { - types.add(type); - }); - return types; - } - - @override - String getDefaultLocation(String camera) { - return properties['cameras'][camera]['default-access-point']; - } - - @override - List getLocations(String camera) { - List locations = []; - properties['cameras'][camera]['streams']['access-points'] - .keys - .forEach((accessPoint) { - if (videoStreamMode == VideoStreamMode.streamOverSsh && - !properties['ssh'].containsKey(accessPoint)) { - return; - } - locations.add(accessPoint); - }); - - return locations; - } -} diff --git a/lib/helpers/swipedetector.dart b/lib/helpers/swipedetector.dart deleted file mode 100644 index ac7827b..0000000 --- a/lib/helpers/swipedetector.dart +++ /dev/null @@ -1,125 +0,0 @@ -import 'package:flutter/material.dart'; - -class SwipeConfiguration { - //Vertical swipe configuration options - final double verticalSwipeMaxWidthThreshold; - final double verticalSwipeMinDisplacement; - final double verticalSwipeMinVelocity; - - //Horizontal swipe configuration options - final double horizontalSwipeMaxHeightThreshold; - final double horizontalSwipeMinDisplacement; - final double horizontalSwipeMinVelocity; - - const SwipeConfiguration({ - this.verticalSwipeMaxWidthThreshold = 50.0, - this.verticalSwipeMinDisplacement = 100.0, - this.verticalSwipeMinVelocity = 300.0, - this.horizontalSwipeMaxHeightThreshold = 50.0, - this.horizontalSwipeMinDisplacement = 100.0, - this.horizontalSwipeMinVelocity = 300.0, - }); -} - -void doNothing() {} - -class SwipeDetector extends StatelessWidget { - final Widget child; - final Function() onSwipeUp; - final Function() onSwipeDown; - final Function() onSwipeLeft; - final Function() onSwipeRight; - final Function() onTap; - final SwipeConfiguration swipeConfiguration; - - const SwipeDetector({ - super.key, - required this.child, - this.onSwipeUp = doNothing, - this.onSwipeDown = doNothing, - this.onSwipeLeft = doNothing, - this.onSwipeRight = doNothing, - this.onTap = doNothing, - this.swipeConfiguration = const SwipeConfiguration(), - }); - - @override - Widget build(BuildContext context) { - //Vertical drag details - DragStartDetails? startVerticalDragDetails; - DragUpdateDetails? updateVerticalDragDetails; - - //Horizontal drag details - DragStartDetails? startHorizontalDragDetails; - DragUpdateDetails? updateHorizontalDragDetails; - - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: onTap, - onVerticalDragStart: (dragDetails) { - startVerticalDragDetails = dragDetails; - }, - onVerticalDragUpdate: (dragDetails) { - updateVerticalDragDetails = dragDetails; - }, - onVerticalDragEnd: (endDetails) { - if (updateVerticalDragDetails == null || - startVerticalDragDetails != null) { - return; - } - double dx = (updateVerticalDragDetails?.globalPosition.dx ?? 0.0) - - (startVerticalDragDetails?.globalPosition.dx ?? 0.0); - double dy = (updateVerticalDragDetails?.globalPosition.dy ?? 0.0); - -(startVerticalDragDetails?.globalPosition.dy ?? 0.0); - double velocity = endDetails.primaryVelocity ?? 0; - - //Convert values to be positive - if (dx < 0) dx = -dx; - if (dy < 0) dy = -dy; - double positiveVelocity = velocity < 0 ? -velocity : velocity; - - if (dx > swipeConfiguration.verticalSwipeMaxWidthThreshold) return; - if (dy < swipeConfiguration.verticalSwipeMinDisplacement) return; - if (positiveVelocity < swipeConfiguration.verticalSwipeMinVelocity) { - return; - } - - if (velocity < 0) { - onSwipeUp(); - } else { - onSwipeDown(); - } - }, - onHorizontalDragStart: (dragDetails) { - startHorizontalDragDetails = dragDetails; - }, - onHorizontalDragUpdate: (dragDetails) { - updateHorizontalDragDetails = dragDetails; - }, - onHorizontalDragEnd: (endDetails) { - double dx = (updateHorizontalDragDetails?.globalPosition.dx ?? 0.0) - - (startHorizontalDragDetails?.globalPosition.dx ?? 0.0); - double dy = (updateHorizontalDragDetails?.globalPosition.dy ?? 0.0) - - (startHorizontalDragDetails?.globalPosition.dy ?? 0.0); - double velocity = endDetails.primaryVelocity ?? 0.0; - - if (dx < 0) dx = -dx; - if (dy < 0) dy = -dy; - double positiveVelocity = velocity < 0 ? -velocity : velocity; - - if (dx < swipeConfiguration.horizontalSwipeMinDisplacement) return; - if (dy > swipeConfiguration.horizontalSwipeMaxHeightThreshold) return; - if (positiveVelocity < swipeConfiguration.horizontalSwipeMinVelocity) { - return; - } - - if (velocity < 0) { - onSwipeLeft(); - } else { - onSwipeRight(); - } - }, - child: child, - ); - } -} diff --git a/lib/home_page.dart b/lib/home_page.dart deleted file mode 100644 index b5e1792..0000000 --- a/lib/home_page.dart +++ /dev/null @@ -1,798 +0,0 @@ -import 'dart:async'; - -import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; -import 'package:flutter/material.dart'; -import 'package:netr/helpers/camera_helper.dart'; -import 'package:netr/helpers/historical_photo_camera_helper.dart'; -import 'package:netr/helpers/photo_camera_helper.dart'; -import 'package:netr/helpers/stream_camera_helper.dart'; -import 'package:netr/tool.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -typedef HomePageCallback = void Function( - ViewerMode viewerMode, - VideoStreamMode? videoStreamMode, - VideoStreamType? videoStreamType, - String videoQuality, - String? location, - DateTime? archiveDateTime, - String selectedVideoCamera, - int selectedCameraIndex, - PhotoCameraHelper? photoCameraHelper, - HistoricalPhotoCameraHelper? historicalPhotoCameraHelper, - StreamCameraHelper? streamCameraHelper); - -class HomePage extends StatefulWidget { - const HomePage(this.onSubmit, - {super.key, - this.viewerMode, - this.videoStreamMode, - this.videoStreamType, - this.videoQuality, - this.location, - this.archiveDateTime, - this.selectedVideoCamera, - this.selectedCameraIndex, - this.photoCameraHelper, - this.historicalPhotoCameraHelper, - this.streamCameraHelper}) - : isRestored = false; - - const HomePage.restore( - this.onSubmit, - this.viewerMode, - this.videoStreamMode, - this.videoStreamType, - this.videoQuality, - this.location, - this.archiveDateTime, - this.selectedVideoCamera, - this.selectedCameraIndex, - this.photoCameraHelper, - this.historicalPhotoCameraHelper, - this.streamCameraHelper, - {super.key}) - : isRestored = true; - - final bool isRestored; - final HomePageCallback onSubmit; - final ViewerMode? viewerMode; - final VideoStreamMode? videoStreamMode; - final VideoStreamType? videoStreamType; - final String? videoQuality; - final String? location; - final DateTime? archiveDateTime; - final String? selectedVideoCamera; - final int? selectedCameraIndex; - final PhotoCameraHelper? photoCameraHelper; - final HistoricalPhotoCameraHelper? historicalPhotoCameraHelper; - final StreamCameraHelper? streamCameraHelper; - - @override - _HomePageState createState() => _HomePageState(); -} - -class _HomePageState extends State { - final String _archive = 'archive'; - - Timer? _minuteTimer; - ViewerMode? _viewerMode; - VideoStreamMode? _videoStreamMode; - VideoStreamType? _videoStreamType; - String? _location; - String? _videoQuality; - DateTime? _archiveDateTime; - String? _selectedVideoCamera; - int? _selectedCameraIndex; - PhotoCameraHelper? _photoCameraHelper; - HistoricalPhotoCameraHelper? _historicalPhotoCameraHelper; - StreamCameraHelper? _streamCameraHelper; - String? _selectedArchiveDateTimeButton; - - _HomePageState(); - - @override - void initState() { - super.initState(); - - _viewerMode = widget.viewerMode; - _videoStreamMode = widget.videoStreamMode; - _videoStreamType = widget.videoStreamType; - _videoQuality = widget.videoQuality; - _location = widget.location; - _archiveDateTime = widget.archiveDateTime; - _selectedVideoCamera = widget.selectedVideoCamera; - _selectedCameraIndex = widget.selectedCameraIndex; - _photoCameraHelper = widget.photoCameraHelper; - _streamCameraHelper = widget.streamCameraHelper; - _selectedArchiveDateTimeButton = null; - - if (!widget.isRestored) { - _loadConfiguration(null); - } - - _minuteTimer = Timer.periodic(const Duration(minutes: 1), (Timer t) { - setState(() {}); - }); - } - - @override - void dispose() { - if (_minuteTimer != null) { - _minuteTimer!.cancel(); - } - _saveConfiguration(); - super.dispose(); - } - - void _addViewerModes(List columns) { - var viewerModesWidgets = []; - viewerModesWidgets - .add(const FittedBox(fit: BoxFit.fitHeight, child: Text('Mode:'))); - - for (var viewerMode in ViewerMode.values) { - if (viewerMode == ViewerMode.none) { - continue; - } - - if (isWebPlatform() && viewerMode == ViewerMode.inAppVideo) { - continue; - } - - viewerModesWidgets.add(createIconButton( - viewerMode.iconData, - _viewerMode == viewerMode - ? null - : () async { - await _saveConfiguration(); - const videoModes = [ - ViewerMode.inAppVideo, - ViewerMode.remoteVlc - ]; - const pictureModes = [ - ViewerMode.pictureArchive, - ViewerMode.picture - ]; - if ((videoModes.contains(viewerMode) && - pictureModes.contains(_viewerMode)) || - (videoModes.contains(_viewerMode) && - pictureModes.contains(viewerMode))) { - _location = null; - } - - await _loadConfiguration(viewerMode.toString()); - setState(() { - _viewerMode = viewerMode; - }); - }, - viewerMode.displayTitle)); - } - columns.add( - FocusTraversalGroup( - child: SizedBox( - height: 35, - child: ListView( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - children: viewerModesWidgets), - ), - ), - ); - columns.add(Container(height: 5)); - } - - CameraHelper? _addCameraWidgets(List columns) { - var cameraWidgets = []; - cameraWidgets.add( - const FittedBox(fit: BoxFit.fitHeight, child: Text('Which camera:'))); - CameraHelper? cameraHelper; - bool noneSelected = false; - switch (_viewerMode) { - case ViewerMode.picture: - if (_photoCameraHelper == null) { - _photoCameraHelper = PhotoCameraHelper(() { - setState(() { - cameraHelper = _photoCameraHelper; - }); - }, (error) { - showSnackBar(context, 'Error loading info: $error'); - _photoCameraHelper = null; - }); - _photoCameraHelper?.init(); - } else { - cameraHelper = _photoCameraHelper!; - } - break; - case ViewerMode.pictureArchive: - if (_historicalPhotoCameraHelper == null) { - _historicalPhotoCameraHelper = HistoricalPhotoCameraHelper(() { - setState(() { - cameraHelper = _historicalPhotoCameraHelper; - }); - }, (error) { - showSnackBar(context, 'Error loading info: $error'); - _historicalPhotoCameraHelper = null; - }); - _historicalPhotoCameraHelper?.init(); - } else { - cameraHelper = _historicalPhotoCameraHelper!; - } - break; - case ViewerMode.remoteVlc: - case ViewerMode.inAppVideo: - if (_streamCameraHelper == null) { - _streamCameraHelper = StreamCameraHelper(_videoStreamMode, () { - setState(() { - cameraHelper = _streamCameraHelper; - }); - }, (error) { - showSnackBar(context, 'Error loading info: $error'); - _streamCameraHelper = null; - }); - _streamCameraHelper?.init(); - } else { - cameraHelper = _streamCameraHelper!; - } - break; - case ViewerMode.none: - default: - noneSelected = true; - break; - } - if (noneSelected) { - cameraWidgets - .add(const Center(child: Text('Select View Mode to list cameras'))); - } else if (cameraHelper == null) { - cameraWidgets.add(getBusyIndicator()); - } else { - String? quality = _videoQuality == _archive ? null : _videoQuality; - List cameras = cameraHelper!.getCameras(quality); - for (int i = 0; i < cameras.length; i++) { - String camera = cameras[i]; - var text = toDisplayText(camera); - cameraWidgets.add(createButton( - text, - _selectedVideoCamera == camera - ? null - : () { - setState(() { - _selectedVideoCamera = camera; - _selectedCameraIndex = i; - }); - })); - } - } - columns.add( - FocusTraversalGroup( - child: SizedBox( - height: 35, - child: ListView( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - children: cameraWidgets, - ), - ), - ), - ); - - return cameraHelper; - } - - void _addStreamModeWidgets(List columns) { - if (_viewerMode == ViewerMode.remoteVlc) { - _videoStreamMode = VideoStreamMode.streamDirect; - } else { - var videoStreamModeWidgets = []; - videoStreamModeWidgets.add(const FittedBox( - fit: BoxFit.fitHeight, child: Text('How (stream mode): '))); - - for (var videoStreamMode in VideoStreamMode.values) { - videoStreamModeWidgets.add(createButton( - videoStreamMode.displayTitle, - _videoStreamMode == videoStreamMode - ? null - : () { - setState(() { - _videoStreamMode = videoStreamMode; - }); - })); - } - columns.add( - FocusTraversalGroup( - child: Row(children: videoStreamModeWidgets), - ), - ); - } - } - - void _addLocationWidgets(CameraHelper? cameraHelper, List columns) { - if (_viewerMode == null || cameraHelper == null) { - return; - } - - if (((_selectedVideoCamera != null && _videoStreamMode != null) || - _viewerMode == ViewerMode.picture || - _viewerMode == ViewerMode.pictureArchive)) { - List locations = - cameraHelper.getLocations(_selectedVideoCamera ?? ''); - String title = ''; - switch (_viewerMode) { - case ViewerMode.inAppVideo: - case ViewerMode.remoteVlc: - title = 'Where (access point): '; - break; - case ViewerMode.picture: - case ViewerMode.pictureArchive: - default: - title = 'Which (location): '; - break; - } - - if (locations.length > 1) { - String defaultLocation = - cameraHelper.getDefaultLocation(_selectedVideoCamera!); - _location ??= defaultLocation; - - var locationWidgets = []; - locationWidgets - .add(FittedBox(fit: BoxFit.fitHeight, child: Text(title))); - - for (String location in locations) { - locationWidgets.add(createButton( - toDisplayText(location), - _location == location - ? null - : () { - setState(() { - _location = location; - }); - })); - } - - columns.add( - FocusTraversalGroup( - child: Row(children: locationWidgets), - ), - ); - } else { - _location = locations[0]; - } - } - } - - void _addVideoStreamWidgets(List columns) { - if (_viewerMode == ViewerMode.inAppVideo || - _viewerMode == ViewerMode.remoteVlc) { - var videoStreamTypeWidgets = []; - videoStreamTypeWidgets.add(const FittedBox( - fit: BoxFit.fitHeight, child: Text('Which (stream type): '))); - - for (var videoStreamType in VideoStreamType.values) { - videoStreamTypeWidgets.add(createButton( - videoStreamType.displayTitle, - _videoStreamType == videoStreamType - ? null - : () { - setState(() { - _videoStreamType = videoStreamType; - }); - })); - } - columns.add( - FocusTraversalGroup( - child: Row(children: videoStreamTypeWidgets), - ), - ); - } - } - - void _addQualityWidgets(CameraHelper? cameraHelper, List columns) { - switch (_viewerMode) { - case ViewerMode.inAppVideo: - case ViewerMode.remoteVlc: - if (_videoStreamType == VideoStreamType.archive) { - _videoQuality = _archive; - return; - } else if (_videoStreamType == null) { - return; - } - break; - default: - } - - if (_selectedVideoCamera != null) { - List types = cameraHelper?.getTypes(_selectedVideoCamera!) ?? []; - String defaultType = cameraHelper?.getDefaultType() ?? ''; - if (types.isNotEmpty) { - _videoQuality ??= defaultType; - var videoQualityWidgets = []; - videoQualityWidgets.add(const FittedBox( - fit: BoxFit.fitHeight, child: Text('Which (quality): '))); - for (var videoQuality in types) { - videoQualityWidgets.add(createButton( - toDisplayText(videoQuality), - _videoQuality == videoQuality - ? null - : () { - setState(() { - _videoQuality = videoQuality; - }); - })); - } - columns.add( - FocusTraversalGroup( - child: Row(children: videoQualityWidgets), - ), - ); - } - } - } - - void _addArchiveDateTimeWidgets(List columns) { - if (_viewerMode != ViewerMode.remoteVlc && - _viewerMode != ViewerMode.inAppVideo) { - return; - } - - if (_videoStreamType == VideoStreamType.archive) { - var now = DateTime.now(); - var firstDate = _viewerMode == ViewerMode.pictureArchive - ? now.subtract(const Duration(days: 5)) - : now.subtract(const Duration(days: 30)); - - final Map dateTimeMapping = { - '1 min': now.subtract(const Duration(minutes: 1)), - '2 min': now.subtract(const Duration(minutes: 2)), - '3 min': now.subtract(const Duration(minutes: 3)), - '5 min': now.subtract(const Duration(minutes: 5)), - '10 min': now.subtract(const Duration(minutes: 10)), - '30 min': now.subtract(const Duration(minutes: 30)), - '1 hour': now.subtract(const Duration(hours: 1)), - '2 hour': now.subtract(const Duration(hours: 2)), - '3 hour': now.subtract(const Duration(hours: 3)), - '6 hour': now.subtract(const Duration(hours: 6)), - '12 hours': now.subtract(const Duration(hours: 12)), - '1 day': now.subtract(const Duration(days: 1)), - '2 day': now.subtract(const Duration(days: 2)), - '1 week': now.subtract(const Duration(days: 7)), - }; - - var archiveDateTimeWidgets = []; - archiveDateTimeWidgets.add( - const FittedBox(fit: BoxFit.fitHeight, child: Text('What (time): '))); - - DatePicker.showDateTimePicker( - context, - minTime: _archiveDateTime, - maxTime: DateTime(now.year, now.month, now.day), - onChanged: (input) { - //var input = DateTime.parse(val); - var now = DateTime.now(); - if (input.isAfter(now)) { - input = now; - } - - if (_viewerMode == ViewerMode.pictureArchive) { - var rem = input.minute % 15; - if (rem >= 8) { - input = input.add(Duration(minutes: rem)); - } else if (rem > 0) { - input = input.subtract(Duration(minutes: rem)); - } - } - - _selectedArchiveDateTimeButton = null; - setState(() { - _archiveDateTime = input; - }); - }, - ); - - /* - DatePicker dateTimePicker = DatePicker( - type: DateTimePickerType.dateTime, - initialDate: _archiveDateTime, - initialTime: _archiveDateTime == null - ? null - : TimeOfDay( - hour: _archiveDateTime!.hour, minute: _archiveDateTime!.minute), - firstDate: firstDate, - lastDate: DateTime(now.year, now.month, now.day), - icon: const Icon(Icons.archive), - dateLabelText: 'What (date and time):', - onChanged: (val) { - var input = DateTime.parse(val); - var now = DateTime.now(); - if (input.isAfter(now)) { - input = now; - } - - if (_viewerMode == ViewerMode.pictureArchive) { - var rem = input.minute % 15; - if (rem >= 8) { - input = input.add(Duration(minutes: rem)); - } else if (rem > 0) { - input = input.subtract(Duration(minutes: rem)); - } - } - - _selectedArchiveDateTimeButton = null; - setState(() { - _archiveDateTime = input; - }); - }, - ); - - */ - - dateTimeMapping.forEach((key, value) { - archiveDateTimeWidgets.add(createButton( - toDisplayText(key), - _selectedArchiveDateTimeButton == key - ? null - : () { - _selectedArchiveDateTimeButton = key; - setState(() { - _archiveDateTime = value; - }); - })); - }); - archiveDateTimeWidgets.add( - const FittedBox(fit: BoxFit.fitHeight, child: Text(' in the past'))); - - columns.add( - FocusTraversalGroup( - child: Row(children: archiveDateTimeWidgets), - ), - ); - //columns.add(dateTimePicker); - } - } - - void _addGoWidgets(List columns, CameraHelper? cameraHelper) { - bool enableGoButton = false; - if (cameraHelper != null) { - switch (_viewerMode) { - case ViewerMode.picture: - case ViewerMode.pictureArchive: - enableGoButton = - _selectedVideoCamera != null && _videoQuality != null; - break; - case ViewerMode.remoteVlc: - case ViewerMode.inAppVideo: - enableGoButton = _selectedVideoCamera != null && - _videoStreamMode != null && - isStringEmptyOrNull(_videoQuality) && - isStringEmptyOrNull(_location) && - _videoStreamType != null && - (_videoStreamType == VideoStreamType.live || - _archiveDateTime != null); - break; - default: - } - } - if (!enableGoButton) { - columns.add(const Text( - 'Please select all required options to move forward', - style: TextStyle(color: Colors.blueAccent), - )); - } else { - columns.add( - createIconButton( - Icons.start, - () { - _saveConfigurationAndSubmit(); - }, - 'Go', - ButtonStyle( - alignment: Alignment.center, - backgroundColor: WidgetStateProperty.all(Colors.black54), - foregroundColor: WidgetStateProperty.all(Colors.blue), - textStyle: WidgetStateProperty.all( - const TextStyle( - fontSize: 35, - fontWeight: FontWeight.bold, - ), - ), - ), - true, - true, - ), - ); - } - } - - Future _loadConfiguration(String? strViewerMode) async { - _viewerMode = null; - _videoStreamMode = null; - _videoStreamType = null; - _location = null; - _videoQuality = null; - _archiveDateTime = null; - _selectedVideoCamera = null; - _selectedCameraIndex = null; - - SharedPreferences prefs = await SharedPreferences.getInstance(); - strViewerMode ??= prefs.getString("ViewerMode"); - if (strViewerMode == null) { - return; - } - - _viewerMode = - ViewerMode.values.firstWhere((e) => e.toString() == strViewerMode); - - _selectedCameraIndex = prefs.getInt("$strViewerMode.SelectedCameraIndex"); - _selectedVideoCamera = - prefs.getString("$strViewerMode.SelectedVideoCamera"); - _videoQuality = prefs.getString("$strViewerMode.VideoQuality"); - - if (_viewerMode == ViewerMode.remoteVlc || - _viewerMode == ViewerMode.inAppVideo) { - String? videoStreamType = - prefs.getString("$strViewerMode.VideoStreamType"); - if (videoStreamType != null) { - _videoStreamType = VideoStreamType.values - .firstWhere((e) => e.toString() == videoStreamType); - } - _location = prefs.getString("$strViewerMode.Location"); - String? archiveDateTime = - prefs.getString("$strViewerMode.ArchiveDateTime"); - if (archiveDateTime != null) { - _archiveDateTime = DateTime.parse(archiveDateTime); - } - } - - if (_viewerMode == ViewerMode.inAppVideo) { - String? videoStreamMode = - prefs.getString("$strViewerMode.VideoStreamMode"); - if (videoStreamMode != null) { - _videoStreamMode = VideoStreamMode.values - .firstWhere((e) => e.toString() == videoStreamMode); - } - } - - setState(() {}); - } - - Future _saveConfiguration() async { - if (_viewerMode == null) { - return; - } - - SharedPreferences prefs = await SharedPreferences.getInstance(); - String strViewerMode = _viewerMode.toString(); - await prefs.setString("ViewerMode", strViewerMode); - - if (_selectedCameraIndex != null) { - await prefs.setInt( - "$strViewerMode.SelectedCameraIndex", _selectedCameraIndex!); - } - if (_selectedVideoCamera != null) { - await prefs.setString( - "$strViewerMode.SelectedVideoCamera", _selectedVideoCamera!); - } - if (_videoQuality != null) { - await prefs.setString("$strViewerMode.VideoQuality", _videoQuality!); - } - - if (_viewerMode == ViewerMode.remoteVlc || - _viewerMode == ViewerMode.inAppVideo) { - if (_videoStreamType != null) { - await prefs.setString( - "$strViewerMode.VideoStreamType", _videoStreamType.toString()); - } - if (_location != null) { - await prefs.setString("$strViewerMode.Location", _location!); - } - if (_archiveDateTime != null) { - await prefs.setString( - "$strViewerMode.ArchiveDateTime", _archiveDateTime.toString()); - } - } - - if (_viewerMode == ViewerMode.inAppVideo) { - if (_videoStreamMode != null) { - await prefs.setString( - "$strViewerMode.VideoStreamMode", _videoStreamMode.toString()); - } - } - } - - Future _saveConfigurationAndSubmit() async { - await _saveConfiguration(); - - widget.onSubmit( - _viewerMode!, - _videoStreamMode, - _videoStreamType, - _videoQuality!, - _location, - _archiveDateTime, - _selectedVideoCamera!, - _selectedCameraIndex!, - _photoCameraHelper, - _historicalPhotoCameraHelper, - _streamCameraHelper); - } - - @override - Widget build(BuildContext context) { - var columns = []; - if (_videoQuality == _archive && - (_videoStreamType != VideoStreamType.archive || - _viewerMode == ViewerMode.picture || - _viewerMode == ViewerMode.pictureArchive)) { - _videoQuality = null; - } - if ((_viewerMode == ViewerMode.inAppVideo || - _viewerMode == ViewerMode.remoteVlc) && - _streamCameraHelper != null) { - _streamCameraHelper!.videoStreamMode = _videoStreamMode; - } - - // ################################################################ - // # Viewer Mode - // ################################################################ - _addViewerModes(columns); - - // ################################################################ - // # Camera Selection - // ################################################################ - CameraHelper? cameraHelper = _addCameraWidgets(columns); - - if (cameraHelper != null && _selectedVideoCamera != null) { - if (!cameraHelper.doesCameraExist(_selectedVideoCamera!, _videoQuality)) { - _selectedCameraIndex = null; - _selectedVideoCamera = null; - _videoQuality = null; - } - } - - switch (_viewerMode) { - case ViewerMode.inAppVideo: - case ViewerMode.remoteVlc: - // ################################################################ - // # Stream Mode (Direct|Ssh) - // ################################################################ - _addStreamModeWidgets(columns); - // ################################################################ - // # Access point - // ################################################################ - _addLocationWidgets(cameraHelper, columns); - break; - case ViewerMode.picture: - case ViewerMode.pictureArchive: - // ################################################################ - // # Location - // ################################################################ - _addLocationWidgets(cameraHelper, columns); - break; - default: - } - - // ################################################################ - // # Stream Type (Live|Archive) - // ################################################################ - _addVideoStreamWidgets(columns); - - // ################################################################ - // # Quality - // ################################################################ - _addQualityWidgets(cameraHelper, columns); - - // ################################################################ - // # Archive date time - // ################################################################ - _addArchiveDateTimeWidgets(columns); - - // ################################################################ - // # Go Button - // ################################################################ - _addGoWidgets(columns, cameraHelper); - - return Scaffold( - appBar: AppBar(title: const Text('Netr App')), - body: SingleChildScrollView(child: Column(children: columns)), - ); - } -} diff --git a/lib/models/app_info.dart b/lib/models/app_info.dart deleted file mode 100644 index d34fb9e..0000000 --- a/lib/models/app_info.dart +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2024 Neeraj Jakhar - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -class AppInfo { - final String version; - - AppInfo.fromJson(Map json) : version = json['version']; -} diff --git a/lib/pages/player/archive_players.dart b/lib/pages/player/archive_players.dart index 5c8a281..96dd825 100644 --- a/lib/pages/player/archive_players.dart +++ b/lib/pages/player/archive_players.dart @@ -7,10 +7,10 @@ */ import 'package:flutter/material.dart'; -import 'package:netr/pages/player/player_vlc_player.dart'; import 'archive_player_base.dart'; import 'player_media_kit.dart'; +import 'player_vlc_player.dart'; class DesktopArchivePlayer extends ArchivePlayerBase { DesktopArchivePlayer(super.maxWidth, super.maxHeight, super.state, diff --git a/lib/pages/player/live_players.dart b/lib/pages/player/live_players.dart index c706bbc..9d2e9a0 100644 --- a/lib/pages/player/live_players.dart +++ b/lib/pages/player/live_players.dart @@ -7,9 +7,10 @@ */ import 'package:flutter/material.dart'; -import 'package:netr/pages/player/live_player_base.dart'; -import 'package:netr/pages/player/player_media_kit.dart'; -import 'package:netr/pages/player/player_vlc_player.dart'; + +import 'live_player_base.dart'; +import 'player_media_kit.dart'; +import 'player_vlc_player.dart'; class DesktopLivePlayer extends LivePlayerBase { DesktopLivePlayer(super.maxWidth, super.maxHeight, super.state, diff --git a/lib/pages/player/player_vlc_player.dart b/lib/pages/player/player_vlc_player.dart index 750af8b..ebd2aa0 100644 --- a/lib/pages/player/player_vlc_player.dart +++ b/lib/pages/player/player_vlc_player.dart @@ -10,10 +10,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_vlc_player_16kb/flutter_vlc_player.dart'; -import 'package:netr/helpers/thumbnail_manager.dart'; import '../../cubit/mixin/camera_view_cubit_mixin.dart'; import '../../cubit/viewer/video_player_cubit.dart'; +import '../../helpers/thumbnail_manager.dart'; import 'lib_helper.dart'; class CameraPlayerStreamVlcPlayer extends CameraPlayerStream { diff --git a/lib/ssh/netr_ssh_forward_channel.dart b/lib/ssh/netr_ssh_forward_channel.dart deleted file mode 100644 index c82fbca..0000000 --- a/lib/ssh/netr_ssh_forward_channel.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:async'; -import 'dart:typed_data'; - -class Test implements StreamConsumer { - final StreamSink> _sink; - - Test(this._sink); - - @override - Future addStream(Stream stream) { - return _sink.addStream(stream.map((event) { - return List.from(event); - })); - } - - @override - Future close() { - return _sink.close(); - } - -} diff --git a/lib/viewers/base_camera_viewer.dart b/lib/viewers/base_camera_viewer.dart deleted file mode 100644 index e1b8fb7..0000000 --- a/lib/viewers/base_camera_viewer.dart +++ /dev/null @@ -1,124 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:netr/viewers/base_viewer.dart'; -import 'package:netr/tool.dart'; -import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; - -abstract class BaseCameraViewer extends BaseViewer { - const BaseCameraViewer(selectedVideoCamera, selectedVideoQuality, - String location, ViewerCallback callback, - {super.key}) - : super(selectedVideoCamera, selectedVideoQuality, location, callback); -} - -abstract class BaseCameraViewerState - extends BaseViewerState { - String? selectedVideoCameraPrevious; - String? selectedVideoCameraNext; - - @override - void initState() { - super.initState(); - selectedVideoCameraPrevious = getPreviousCamera(widget.selectedVideoCamera); - selectedVideoCameraNext = getNextCamera(widget.selectedVideoCamera); - - setState(() {}); - } - - List getCameras(); - - @override - Widget getSelectionView() { - List cameras = getCameras(); - - return ScrollablePositionedList.separated( - itemScrollController: ItemScrollController(), - itemCount: cameras.length, - initialAlignment: 0.5, - initialScrollIndex: selectedVideoCamera == null - ? 0 - : cameras.indexOf(selectedVideoCamera!), - itemBuilder: (context, index) { - var camera = cameras[index]; - return createButton( - "${index + 1}. ${toDisplayText(camera)}", - () async { - Navigator.pop(context); - await finishCameraConnection(); - selectedVideoCameraPrevious = getPreviousCamera(camera); - selectedVideoCamera = camera; - selectedVideoCameraNext = getNextCamera(camera); - await initCameraConnection(); - }, - getPopupItemStyle(), - ); - }, - separatorBuilder: (BuildContext context, int index) { - return const SizedBox(height: 0); - }, - ); - } - - String? getPreviousCamera(camera) { - var cameras = getCameras(); - for (int i = 0; i < cameras.length; i++) { - if (camera == cameras[i]) { - if (i == 0) { - return cameras[cameras.length - 1]; - } else { - return cameras[i - 1]; - } - } - } - - return null; - } - - String? getNextCamera(camera) { - var cameras = getCameras(); - for (int i = 0; i < cameras.length; i++) { - if (camera == cameras[i]) { - if (i == cameras.length - 1) { - return cameras[0]; - } else { - return cameras[i + 1]; - } - } - } - - return null; - } - - Future initCameraConnection() async {} - - Future finishCameraConnection() async {} - - @override - Future next() async { - var camera = selectedVideoCamera; - if (selectedVideoCameraNext == null) { - showSnackBar(context, '${toDisplayText(camera!)} is the last camera'); - return; - } - - await finishCameraConnection(); - selectedVideoCameraPrevious = camera; - selectedVideoCamera = selectedVideoCameraNext!; - selectedVideoCameraNext = getNextCamera(selectedVideoCamera); - await initCameraConnection(); - } - - @override - Future previous() async { - var camera = selectedVideoCamera; - if (selectedVideoCameraPrevious == null) { - showSnackBar(context, '${toDisplayText(camera!)} is the first camera'); - return; - } - - await finishCameraConnection(); - selectedVideoCameraNext = camera; - selectedVideoCamera = selectedVideoCameraPrevious!; - selectedVideoCameraPrevious = getPreviousCamera(selectedVideoCamera); - await initCameraConnection(); - } -} diff --git a/lib/viewers/base_viewer.dart b/lib/viewers/base_viewer.dart deleted file mode 100644 index bc812e2..0000000 --- a/lib/viewers/base_viewer.dart +++ /dev/null @@ -1,376 +0,0 @@ -import 'dart:core'; -import 'dart:io' show Platform; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:netr/tool.dart'; -import 'package:netr/viewers/picture_historical_viewer.dart'; -import 'package:vector_math/vector_math_64.dart' as vm64; -import 'package:wakelock_plus/wakelock_plus.dart'; - -typedef ViewerCallback = void Function(bool showInstruction); - -abstract class BaseViewer extends StatefulWidget { - const BaseViewer(this.selectedVideoCamera, this.selectedVideoQuality, - this.location, this.callback, - {super.key}); - - final String selectedVideoCamera; - final String selectedVideoQuality; - final String location; - final ViewerCallback callback; -} - -abstract class BaseViewerState extends State { - bool isInitialized = false; - String? selectedVideoCamera; - late TransformationController _controller; - - final double _drag = 8; - final double _minDeltaAllowed = 1.0e-5; - final double _minScale = 1.0; - final double _maxScale = 8.0; - final double _scaleFactor = 1.3034; - final double _translationStep = 10; - - @override - void initState() { - super.initState(); - selectedVideoCamera = widget.selectedVideoCamera; - _controller = TransformationController(); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - Future backButtonCleanup(context) async {} - - Future next(); - - Future previous(); - - Future close() async { - await backButtonCleanup(context); - widget.callback(false); - } - - Future togglePlay() async {} - - Future lockScreen() async { - if (isWebPlatform() || !Platform.isLinux) { - await WakelockPlus.enable(); - } - } - - Future unlockScreen() async { - if (isWebPlatform() || !Platform.isLinux) { - await WakelockPlus.disable(); - } - } - - Widget getPreviousButton(context) { - return createNavigatorButton(Icons.arrow_back, () async { - Navigator.pop(context); - await previous(); - }); - } - - Widget getNextButton(context) { - return createNavigatorButton(Icons.arrow_forward, () async { - Navigator.pop(context); - await next(); - }); - } - - Widget getBackButton(context) { - return createNavigatorButton(Icons.settings_backup_restore, () async { - Navigator.pop(context); - await close(); - }); - } - - void initializeViewer(BuildContext context) {} - - List getNavigators(BuildContext context); - - Widget getMainViewWidget(BuildContext context); - - Widget getSelectionView(); - - TextStyle getPopupInfoStyle() { - return const TextStyle( - color: Colors.green, - fontWeight: FontWeight.bold, - fontSize: 30, - ); - } - - ButtonStyle getPopupItemStyle() { - return ButtonStyle( - alignment: Alignment.centerLeft, - backgroundColor: WidgetStateProperty.all(Colors.black54), - foregroundColor: WidgetStateProperty.resolveWith((states) { - if (states.contains(WidgetState.disabled)) { - return Colors.amber; - } - return Colors.blue; - }), - textStyle: WidgetStateProperty.all(const TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - )), - ); - } - - void _scaleAndCenter(double scaleFactor) { - Matrix4 value = Matrix4.copy(_controller.value)..scale(scaleFactor); - double scale = value.getMaxScaleOnAxis(); - double maxWidth = MediaQuery.of(context).size.width; - double maxHeight = MediaQuery.of(context).size.height; - maxWidth *= scale - 1; - maxHeight *= scale - 1; - value.setTranslationRaw(-maxWidth / 2, -maxHeight / 2, 0); - _controller.value = value; - } - - void _restoreToOriginal() { - _controller.value = Matrix4.identity(); - } - - void _translate(bool left, bool right, bool up, bool down) { - double scale = _controller.value.getMaxScaleOnAxis(); - double maxWidth = MediaQuery.of(context).size.width; - double maxHeight = MediaQuery.of(context).size.height; - maxWidth *= scale - 1; - maxHeight *= scale - 1; - Matrix4 value = Matrix4.copy(_controller.value); - vm64.Vector3 translation = value.getTranslation(); - double x = translation.x; - double y = translation.y; - - double low(l) { - if (-(l + _translationStep) > 0) { - return _translationStep; - } else if (-l > 0) { - return -l; - } else { - return 0; - } - } - - double high(h, max) { - if (-(h + _translationStep) < max) { - return _translationStep; - } else if (max > -h) { - return max + h; - } else { - return 0; - } - } - - if (left) { - x += low(x); - } - if (right) { - x -= high(x, maxWidth); - } - if (up) { - y += low(y); - } - if (down) { - y -= high(y, maxHeight); - } - - value.setTranslationRaw(x, y, translation.z); - _controller.value = value; - } - - void _zoomIn() { - double scale = _controller.value.getMaxScaleOnAxis(); - if (scale * _scaleFactor < _maxScale) { - _scaleAndCenter(_scaleFactor); - } else { - _scaleAndCenter(_maxScale / scale); - } - } - - void _zoomOut() { - double scale = _controller.value.getMaxScaleOnAxis(); - if (scale / _scaleFactor > _minScale) { - _scaleAndCenter(1 / _scaleFactor); - } else { - _scaleAndCenter(_minScale / scale); - } - } - - List _getDialogItems() { - List navigators = getNavigators(context); - navigators.add(getBackButton(context)); - - return [ - SizedBox( - height: 35, - child: ListView( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - children: navigators, - ), - ), - Text( - this is! PictureHistoricalViewerHomeState - ? "Select a Camera" - : "Select Date Time", - style: getPopupInfoStyle(), - ), - SizedBox( - height: 300, - child: getSelectionView(), - ), - ]; - } - - void _onTap() { - showGeneralDialog( - context: context, - barrierColor: Colors.black38, - barrierLabel: 'Camera Selection', - barrierDismissible: true, - pageBuilder: (_, __, ___) => Center( - child: Material( - color: Colors.transparent, - child: SizedBox( - height: 400, - width: 400, - child: ListView( - scrollDirection: Axis.vertical, - children: _getDialogItems(), - ), - ), - ), - ), - ); - } - - bool _valueCloseToZero(double value) => value.abs() < _minDeltaAllowed; - - bool _isNotZoomedAndNotTranslated(Matrix4 value) { - vm64.Vector3 translation = value.getTranslation(); - return _valueCloseToZero(value.getMaxScaleOnAxis() - 1.0) && - _valueCloseToZero(translation.x) && - _valueCloseToZero(translation.y) && - _valueCloseToZero(translation.z); - } - - void _onInteractionEnd(ScaleEndDetails details) { - if (_isNotZoomedAndNotTranslated(_controller.value)) { - if (details.pointerCount == 0) { - if (details.velocity.pixelsPerSecond.dx > _drag) { - previous(); - } - if (details.velocity.pixelsPerSecond.dx < -_drag) { - next(); - } - } - } - } - - void _onKey(KeyEvent event) { - if (event is KeyDownEvent) { - if (event.logicalKey.keyId == LogicalKeyboardKey.select.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.enter.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.contextMenu.keyId) { - _onTap(); - } else if (event.logicalKey.keyId == LogicalKeyboardKey.space.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.mediaPlay.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.mediaPlayPause.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.mediaPause.keyId) { - togglePlay(); - } else if (event.logicalKey.keyId == - LogicalKeyboardKey.mediaFastForward.keyId) { - _zoomIn(); - } else if (event.logicalKey.keyId == - LogicalKeyboardKey.mediaRewind.keyId) { - _zoomOut(); - } else if (event.logicalKey.keyId == LogicalKeyboardKey.arrowLeft.keyId) { - if (_controller.value.isIdentity()) { - previous(); - } else { - _translate(true, false, false, false); - } - } else if (event.logicalKey.keyId == - LogicalKeyboardKey.arrowRight.keyId) { - if (_controller.value.isIdentity()) { - next(); - } else { - _translate(false, true, false, false); - } - } else if (event.logicalKey.keyId == LogicalKeyboardKey.arrowUp.keyId) { - if (!_controller.value.isIdentity()) { - _translate(false, false, true, false); - } - } else if (event.logicalKey.keyId == LogicalKeyboardKey.arrowDown.keyId) { - if (!_controller.value.isIdentity()) { - _translate(false, false, false, true); - } - } else if (event.logicalKey.keyId == LogicalKeyboardKey.zoomOut.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.minus.keyId) { - _zoomOut(); - } else if (event.logicalKey.keyId == LogicalKeyboardKey.zoomIn.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.add.keyId) { - _zoomIn(); - } else if (event.logicalKey.keyId == LogicalKeyboardKey.backspace.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.escape.keyId) { - if (_controller.value.isIdentity()) { - close(); - } else { - _restoreToOriginal(); - } - } - } - } - - Future _onWillPop() async { - if (_controller.value.isIdentity()) { - await close(); - } else { - _restoreToOriginal(); - } - return false; - } - - @override - Widget build(BuildContext context) { - initializeViewer(context); - - return WillPopScope( - onWillPop: _onWillPop, - child: KeyboardListener( - autofocus: true, - focusNode: FocusNode(), - onKeyEvent: _onKey, - child: Scaffold( - body: InteractiveViewer( - panEnabled: true, - scaleEnabled: true, - minScale: _minScale, - maxScale: _maxScale, - transformationController: _controller, - onInteractionEnd: _onInteractionEnd, - child: SizedBox.expand( - child: isInitialized - ? GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: _onTap, - onSecondaryTap: _onTap, - child: getMainViewWidget(context), - ) - : getBusyIndicator(), - ), - ), - ), - ), - ); - } -} diff --git a/lib/viewers/direct_archive_video_viewer.dart b/lib/viewers/direct_archive_video_viewer.dart deleted file mode 100644 index 0d394e7..0000000 --- a/lib/viewers/direct_archive_video_viewer.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; -import 'package:netr/config.dart'; -import 'package:netr/helpers/stream_camera_helper.dart'; -import 'package:netr/viewers/direct_video_viewer.dart'; - -class DirectArchiveVideoViewerHome extends DirectVideoViewerHome { - const DirectArchiveVideoViewerHome(StreamCameraHelper streamCameraHelper, - selectedVideoCamera, location, this.archiveDateTime, callback, - {Key? key}) - : super( - streamCameraHelper, - selectedVideoCamera, - 'archive', - location, - callback, - key: key, - ); - - final DateTime archiveDateTime; - - @override - DirectArchiveVideoViewerHomeState createState() => - DirectArchiveVideoViewerHomeState(); -} - -class DirectArchiveVideoViewerHomeState - extends DirectVideoViewerHomeState { - @override - String getPath() { - return properties['cameras'][selectedVideoCamera]['archive']['path'] + - DateFormat("yyyyMMdd'T'kkmm'00z'").format(widget.archiveDateTime); - } - - @override - String getHost(String camera) { - return properties['cameras'][camera]['archive']['access-points'] - [widget.location]['host']; - } - - @override - int getPort(String camera) { - return properties['cameras'][camera]['archive']['access-points'] - [widget.location]['port']; - } -} diff --git a/lib/viewers/direct_video_viewer.dart b/lib/viewers/direct_video_viewer.dart deleted file mode 100644 index fd203f0..0000000 --- a/lib/viewers/direct_video_viewer.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:netr/config.dart'; -import 'package:netr/viewers/video_viewer.dart'; - -class DirectVideoViewerHome extends VideoViewerHome { - const DirectVideoViewerHome( - super.streamCameraHelper, - super.selectedVideoCamera, - super.selectedVideoQuality, - super.location, - super.callback, - {super.key}); - - @override - DirectVideoViewerHomeState createState() => DirectVideoViewerHomeState(); -} - -class DirectVideoViewerHomeState - extends VideoViewerHomeState { - @override - void initState() { - super.initState(); - setState(() { - isInitialized = true; - }); - } - - @override - String getHost(String camera) { - return properties['cameras'][camera]['streams']['access-points'] - [widget.location]['host']; - } - - @override - int getPort(String camera) { - return properties['cameras'][camera]['streams']['access-points'] - [widget.location]['port']; - } -} diff --git a/lib/viewers/picture_historical_viewer.dart b/lib/viewers/picture_historical_viewer.dart deleted file mode 100644 index 176227d..0000000 --- a/lib/viewers/picture_historical_viewer.dart +++ /dev/null @@ -1,231 +0,0 @@ -import 'dart:async'; -import 'dart:developer'; - -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; -import 'package:netr/tool.dart'; -import 'package:netr/viewers/base_viewer.dart'; -import 'package:netr/helpers/historical_photo_camera_helper.dart'; -import 'package:window_manager/window_manager.dart'; - -class PictureHistoricalViewerHome extends BaseViewer { - const PictureHistoricalViewerHome( - this.historicalPhotoCameraHelper, - this.currentDateTime, - this.index, - selectedVideoCamera, - selectedVideoQuality, - location, - callback, - {Key? key}) - : super(selectedVideoCamera, selectedVideoQuality, location, callback, - key: key); - - final HistoricalPhotoCameraHelper historicalPhotoCameraHelper; - final DateTime currentDateTime; - final int index; - - @override - PictureHistoricalViewerHomeState createState() => - PictureHistoricalViewerHomeState(); -} - -class PictureHistoricalViewerHomeState - extends BaseViewerState { - DateTime? _currentDateTime; - int? _index; - String? _imageUrl; - int _frequency = 15; - bool _isPlayingForward = false; - bool _isPlayingBackward = false; - - @override - void initState() { - super.initState(); - if (isDesktopPlatform()) { - _initWindow(); - } - - _currentDateTime = widget.currentDateTime; - _index = widget.index; - _frequency = - widget.historicalPhotoCameraHelper.getFrequency(selectedVideoCamera!); - _setImageUrl(_currentDateTime!); - } - - Future _initWindow() async { - await windowManager.setTitleBarStyle(TitleBarStyle.hidden); - await windowManager.maximize(); - } - - Future _setImageUrl(DateTime oldDateTime) async { - var url = await widget.historicalPhotoCameraHelper.getHistoricalImageUrl( - _currentDateTime!, - selectedVideoCamera!, - _index!, - widget.selectedVideoQuality); - if (url == null) { - showSnackBar(context, - 'No such image: ${toDisplayText(selectedVideoCamera!)} [${DateFormat("yyyy-MM-dd-HH:mm").format(_currentDateTime!)}]'); - _currentDateTime = oldDateTime; - return false; - } - _imageUrl = url; - log('Image url: $_imageUrl'); - setState(() { - isInitialized = true; - }); - return true; - } - - @override - void dispose() { - _isPlayingBackward = false; - _isPlayingForward = false; - - if (isDesktopPlatform()) { - windowManager.unmaximize(); - windowManager.setTitleBarStyle(TitleBarStyle.normal); - windowManager.center(); - } - - super.dispose(); - } - - @override - Widget getMainViewWidget(BuildContext context) { - return Image.network(_imageUrl!); - } - - @override - List getNavigators(BuildContext context) { - List navigators = []; - if (!_isPlayingBackward && !_isPlayingForward) { - navigators.add(getPreviousButton(context)); - navigators.add(getNextButton(context)); - navigators.add(createNavigatorButton(Icons.fast_rewind, () { - Navigator.pop(context); - _changeImage(const Duration(days: 1), false); - })); - navigators.add(createNavigatorButton(Icons.fast_forward, () { - Navigator.pop(context); - _changeImage(const Duration(days: 1), true); - })); - } - if (_isPlayingBackward) { - navigators.add(createNavigatorButton(Icons.pause, () { - Navigator.pop(context); - _isPlayingForward = false; - _isPlayingBackward = false; - })); - } else { - navigators.add(createNavigatorButton(Icons.skip_previous, () { - Navigator.pop(context); - _isPlayingForward = false; - _isPlayingBackward = true; - _changeImageTimed( - Duration(minutes: _frequency), false, const Duration(seconds: 5)); - })); - } - if (_isPlayingForward) { - navigators.add(createNavigatorButton(Icons.pause, () { - Navigator.pop(context); - _isPlayingForward = false; - _isPlayingBackward = false; - })); - } else { - navigators.add(createNavigatorButton(Icons.skip_next, () { - Navigator.pop(context); - _isPlayingBackward = false; - _isPlayingForward = true; - _changeImageTimed( - Duration(minutes: _frequency), true, const Duration(seconds: 5)); - })); - } - return navigators; - } - - Future _changeImageTimed( - Duration duration, bool add, Duration repeatAfter) async { - if (!_isPlayingBackward && !_isPlayingForward) { - setState(() {}); - return; - } - - if (!await _changeImage(duration, add)) { - setState(() { - _isPlayingForward = false; - _isPlayingBackward = false; - }); - return; - } - - if (add && _isPlayingForward || !add && _isPlayingBackward) { - Timer(repeatAfter, () { - _changeImageTimed(duration, add, repeatAfter); - }); - } - } - - Future _changeImage(Duration duration, bool add) async { - DateTime oldDateTime = _currentDateTime!; - _currentDateTime = add - ? _currentDateTime?.add(duration) - : _currentDateTime?.subtract(duration); - return await _setImageUrl(oldDateTime); - } - - @override - Future next() async { - _changeImage(Duration(minutes: _frequency), true); - } - - @override - Future previous() async { - _changeImage(Duration(minutes: _frequency), false); - } - - @override - Widget getSelectionView() { - List dateTimes = []; - DateTime now = DateTime.now(); - now = DateTime(now.year, now.month, now.day, now.hour, - now.minute - now.minute % _frequency, 0); - DateTime oldest = now.subtract(const Duration(days: 2)); - oldest = DateTime(oldest.year, oldest.month, oldest.day, 0, 0, 0); - - while (!now.isBefore(oldest)) { - dateTimes.add(now); - now = now.subtract(Duration(minutes: _frequency)); - } - - bool first = true; - List dateTimeWidgets = []; - for (DateTime now in dateTimes) { - if (first || (now.hour == 23 && now.minute == 45)) { - first = false; - dateTimeWidgets.add( - Text( - DateFormat('EE, dd/LL').format(now), - style: getPopupInfoStyle(), - ), - ); - } - - dateTimeWidgets.add(createButton( - DateFormat('KK:mm a').format(now), - () { - Navigator.pop(context); - DateTime oldDateTime = _currentDateTime!; - _currentDateTime = now; - _setImageUrl(oldDateTime); - }, - getPopupItemStyle(), - )); - } - - return ListView( - children: dateTimeWidgets, - ); - } -} diff --git a/lib/viewers/picture_viewer.dart b/lib/viewers/picture_viewer.dart deleted file mode 100644 index b6a28bc..0000000 --- a/lib/viewers/picture_viewer.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:developer'; - -import 'package:flutter/material.dart'; -import 'package:netr/helpers/photo_camera_helper.dart'; -import 'package:netr/tool.dart'; -import 'package:netr/viewers/base_camera_viewer.dart'; -import 'package:window_manager/window_manager.dart'; - -class PictureViewerHome extends BaseCameraViewer { - const PictureViewerHome(this.photoCameraHelper, selectedVideoCamera, - selectedVideoQuality, location, callback, {Key? key}) - : super(selectedVideoCamera, selectedVideoQuality, location, callback, - key: key); - - final PhotoCameraHelper photoCameraHelper; - - @override - PictureViewerHomeState createState() => PictureViewerHomeState(); -} - -class PictureViewerHomeState - extends BaseCameraViewerState { - String? _imageUrl; - - @override - void initState() { - super.initState(); - if (isDesktopPlatform()) { - _initWindow(); - } - setImageUrl(); - lockScreen(); - } - - Future _initWindow() async { - await windowManager.setTitleBarStyle(TitleBarStyle.hidden); - await windowManager.maximize(); - } - - void setImageUrl() async { - _imageUrl = - await widget.photoCameraHelper.getImageUrl(selectedVideoCamera!); - log('Image url: $_imageUrl'); - setState(() { - isInitialized = true; - }); - } - - @override - void dispose() { - if (isDesktopPlatform()) { - windowManager.unmaximize(); - windowManager.setTitleBarStyle(TitleBarStyle.normal); - windowManager.center(); - } - - unlockScreen(); - super.dispose(); - } - - @override - Future initCameraConnection() async { - _imageUrl = - await widget.photoCameraHelper.getImageUrl(selectedVideoCamera!); - setState(() {}); - } - - Widget getRefreshButton(context) { - return createNavigatorButton(Icons.refresh, () async { - Navigator.pop(context); - showSnackBar(context, 'Trying to reload image data'); - await widget.photoCameraHelper.reload(); - setState(() {}); - }); - } - - @override - List getCameras() { - return widget.photoCameraHelper.getCameras(widget.selectedVideoQuality); - } - - @override - Widget getMainViewWidget(BuildContext context) { - return Image.network(_imageUrl!); - } - - @override - List getNavigators(BuildContext context) { - List navigators = []; - navigators.add(getPreviousButton(context)); - navigators.add(getNextButton(context)); - navigators.add(getRefreshButton(context)); - return navigators; - } -} diff --git a/lib/viewers/ssh_archive_video_viewer.dart b/lib/viewers/ssh_archive_video_viewer.dart deleted file mode 100644 index d080e77..0000000 --- a/lib/viewers/ssh_archive_video_viewer.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; -import 'package:netr/config.dart'; -import 'package:netr/helpers/stream_camera_helper.dart'; -import 'package:netr/viewers/ssh_video_viewer.dart'; - -class SshArchiveVideoViewerHome extends SshVideoViewerHome { - const SshArchiveVideoViewerHome(StreamCameraHelper streamCameraHelper, - selectedVideoCamera, location, this.archiveDateTime, callback, - {Key? key}) - : super( - streamCameraHelper, - selectedVideoCamera, - 'archive', - location, - callback, - key: key, - ); - - final DateTime archiveDateTime; - - @override - SshArchiveVideoViewerHomeState createState() => - SshArchiveVideoViewerHomeState(); -} - -class SshArchiveVideoViewerHomeState - extends SshVideoViewerHomeState { - @override - String getPath() { - return properties['cameras'][selectedVideoCamera]['archive']['path'] + - DateFormat("yyyyMMdd'T'kkmm'00z'").format(widget.archiveDateTime); - } - - @override - String getRemoteHost() { - return properties['cameras'][selectedVideoCamera]['archive'] - ['access-points'][widget.location]['host']; - } - - @override - int getRemotePort() { - return properties['cameras'][selectedVideoCamera]['archive'] - ['access-points'][widget.location]['port']; - } -} diff --git a/lib/viewers/ssh_video_viewer.dart b/lib/viewers/ssh_video_viewer.dart deleted file mode 100644 index 67abe13..0000000 --- a/lib/viewers/ssh_video_viewer.dart +++ /dev/null @@ -1,173 +0,0 @@ -import 'dart:developer'; -import 'dart:io'; - -import 'package:dartssh2_plus/dartssh2.dart'; -import 'package:netr/config.dart'; -import 'package:netr/ssh/netr_ssh_forward_channel.dart'; -import 'package:netr/tool.dart'; -import 'package:netr/viewers/video_viewer.dart'; - -class SshVideoViewerHome extends VideoViewerHome { - const SshVideoViewerHome(super.streamCameraHelper, super.selectedVideoCamera, - super.selectedVideoQuality, super.location, super.callback, - {super.key}); - - @override - SshVideoViewerHomeState createState() => SshVideoViewerHomeState(); -} - -class SshVideoViewerHomeState - extends VideoViewerHomeState { - int _serverSocketPort = 0; - SSHClient? _remoteSshClient; - ServerSocket? _serverSocket; - - @override - void initState() { - super.initState(); - _initSsh(); - } - - @override - void dispose() { - super.dispose(); - - if (_serverSocket != null) { - _serverSocket!.close(); - } - - if (_remoteSshClient != null) { - _remoteSshClient!.close(); - } - } - - void _initSsh() async { - await _startSshConnectionAndForwardPort(context); - setState(() { - isInitialized = true; - }); - } - - @override - String getHost(String camera) { - return 'localhost'; - } - - @override - int getPort(String camera) { - return _serverSocketPort; - } - - String getRemoteHost() { - return properties['cameras'][selectedVideoCamera]['streams'] - ['access-points'][widget.location]['host']; - } - - int getRemotePort() { - return properties['cameras'][selectedVideoCamera]['streams'] - ['access-points'][widget.location]['port']; - } - - Future _startSshConnectionAndForwardPort(context) async { - String rHost = getRemoteHost(); - String rPort = getRemotePort().toString(); - - if (!await _startSshConnection(context)) { - return false; - } - return await _forwardSshPort(context, rHost, rPort); - } - - Future _startSshConnection(context) async { - if (_remoteSshClient != null) { - return false; - } - - String host = properties['ssh'][widget.location]['host']; - String port = properties['ssh'][widget.location]['port']; - String user = properties['ssh'][widget.location]['user']; - String privateKey = properties['ssh'][widget.location]['privateKey']; - print('SSH connect to $user@$host:$port'); - print(privateKey); - _remoteSshClient = SSHClient(await SSHSocket.connect(host, int.parse(port)), - username: user, identities: [...SSHKeyPair.fromPem(privateKey)], - onUserauthBanner: (String banner) { - log("SSH Banner: $banner"); - }); - - return true; - } - - Future _forwardSshPort(context, String rHost, String rPort) async { - if (_remoteSshClient == null) { - showSnackBar(context, 'Remote connection not established'); - return false; - } - - _serverSocket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0); - _serverSocketPort = _serverSocket?.port ?? 0; - _processIncomingConnections(context, rHost, rPort); - return true; - } - - Future _processIncomingConnections( - context, String rHost, String rPort) async { - if (_serverSocket == null) { - return; - } - - int port = int.parse(rPort); - - await for (final socket in _serverSocket!) { - print("Remote host:port == $rHost:$rPort"); - final SSHForwardChannel? forward = - await _remoteSshClient?.forwardLocal(rHost, port); - if (forward == null) { - showSnackBar(context, 'Failure to establish remote ssh channel'); - return; - } - - forward.stream.cast>().pipe(socket); - Test t = Test(forward.sink); - //socket.pipe(forward.sink); - socket.pipe(t); - //showSnackBar(context, 'Ssh pipe established'); - } - - _stopSshConnection(context); - } - - Future _stopSshConnection(context) async { - if (_remoteSshClient == null) { - return; - } - - _remoteSshClient?.close(); - await _remoteSshClient?.done; - _remoteSshClient = null; - } - - Future _closeServerSocket() async { - if (_serverSocket == null) { - return; - } - - await _serverSocket?.close(); - _serverSocket = null; - } - - @override - Future finishCameraConnection() async { - await _closeServerSocket(); - await Future.delayed(const Duration(seconds: 1)); - } - - @override - Future initCameraConnection() async { - if (!await _startSshConnectionAndForwardPort(context)) { - showSnackBar(context, 'Failed in establishing remote connection'); - } - - await super.initCameraConnection(); - } -} diff --git a/lib/viewers/video_viewer.dart b/lib/viewers/video_viewer.dart deleted file mode 100644 index ee189ab..0000000 --- a/lib/viewers/video_viewer.dart +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2024-26 Neeraj Jakhar - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -import 'dart:developer'; - -import 'package:flutter/material.dart'; -import 'package:netr/config.dart'; -import 'package:netr/controllers/media_kit_controller.dart'; -import 'package:netr/controllers/video_player_controller_interface.dart'; -import 'package:netr/helpers/stream_camera_helper.dart'; -import 'package:netr/tool.dart'; -import 'package:netr/viewers/base_camera_viewer.dart'; -import 'package:netr/widgets/media_kit_player.dart'; -import 'package:window_manager/window_manager.dart'; - -abstract class VideoViewerHome extends BaseCameraViewer { - const VideoViewerHome(this.streamCameraHelper, selectedVideoCamera, - selectedVideoQuality, location, callback, - {Key? key}) - : super( - selectedVideoCamera, - selectedVideoQuality, - location, - callback, - key: key, - ); - - final StreamCameraHelper streamCameraHelper; -} - -abstract class VideoViewerHomeState - extends BaseCameraViewerState with WidgetsBindingObserver { - late VideoPlayerControllerInterface videoPlayerController; - OverlayEntry? entry; - double bufferPercentage = -1; - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addObserver(this); - if (isDesktopPlatform()) { - _initWindow(); - } - } - - Future _initWindow() async { - await windowManager.setFullScreen(true); - } - - @override - void dispose() { - if (isDesktopPlatform()) { - _restoreWindow(); - } - - WidgetsBinding.instance.removeObserver(this); - videoPlayerController.removeListener(); - videoPlayerController.dispose(); - super.dispose(); - } - - Future _restoreWindow() async { - await windowManager.setFullScreen(false); - await windowManager.center(); - } - - String getHost(String camera); - - int getPort(String camera); - - String getPath() { - return properties['cameras'][selectedVideoCamera]['streams']['paths'] - [widget.selectedVideoQuality]; - } - - String getStreamUrl(camera) { - String protocol, user, password, path; - String host = getHost(camera); - int port = getPort(camera); - - protocol = 'rtsp'; - user = properties['cameras'][camera]['user']; - password = properties['cameras'][camera]['password']; - path = getPath(); - - String url = '$protocol://'; - if (user.isNotEmpty && password.isNotEmpty) { - url += '${Uri.encodeComponent(user)}:${Uri.encodeComponent(password)}@'; - } - - url += '$host:$port$path'; - - return url; - } - - void _showMessage(context, message) { - showSnackBar(context, message); - } - - VideoPlayerControllerInterface getVideoPlayerControllerInternal(String url) { - VideoPlayerControllerInterface videoPlayerController = - MediaKitController(url, autoPlay: true); - - videoPlayerController.addListener(() { - _showMessage(context, - 'Remote streaming url for ${toDisplayText(selectedVideoCamera!)}: $url'); - }, (double bufferingProgress) { - if (bufferPercentage < 0) { - _showMessage(context, 'Buffering ...'); - } - - if (bufferingProgress == 100) { - bufferPercentage = -1; - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - } - - bufferPercentage = bufferingProgress; - }, () { - lockScreen(); - _showMessage(context, 'Started playing'); - }, () { - unlockScreen(); - _showMessage(context, 'Stopped playing'); - }, (error) { - _showMessage(context, 'Play error: $error'); - }); - - return videoPlayerController; - } - - VideoPlayerControllerInterface getVlcPlayerController() { - String url = getStreamUrl(selectedVideoCamera); - log('Url: $url'); - - return getVideoPlayerControllerInternal(url); - } - - @override - Future backButtonCleanup(context) async { - if (videoPlayerController.isInitialized()) { - bool? isPlaying = await videoPlayerController.isPlaying(); - if (isPlaying != null && isPlaying) { - await videoPlayerController.stop(); - } - } - - await finishCameraConnection(); - unlockScreen(); - } - - Widget getPlayButton(context) { - return createNavigatorButton(Icons.play_arrow, () async { - Navigator.pop(context); - try { - await videoPlayerController.play(); - } on Exception catch (_) { - showSnackBar(context, 'Error during play: $_'); - } - }); - } - - Widget getStopButton(context) { - return createNavigatorButton(Icons.stop, () async { - Navigator.pop(context); - try { - await videoPlayerController.stop(); - } on Exception catch (_) { - showSnackBar(context, 'Error during stop: $_'); - } - }); - } - - @override - Future togglePlay() async { - bool isPlaying = await videoPlayerController.isPlaying() ?? false; - if (isPlaying) { - videoPlayerController.stop(); - } else { - videoPlayerController.play(); - } - } - - @override - List getCameras() { - return widget.streamCameraHelper.getCameras(widget.selectedVideoQuality); - } - - @override - void initializeViewer(BuildContext context) { - if (isInitialized) { - videoPlayerController = getVlcPlayerController(); - } - } - - @override - Future initCameraConnection() async { - if (isInitialized) { - await videoPlayerController - .setMediaFromNetwork(getStreamUrl(selectedVideoCamera)); - } - } - - @override - List getNavigators(BuildContext context) { - List navigators = []; - navigators.add(getPlayButton(context)); - navigators.add(getStopButton(context)); - navigators.add(getPreviousButton(context)); - navigators.add(getNextButton(context)); - return navigators; - } - - @override - Widget getMainViewWidget(BuildContext context) { - return MediaKitVideoPlayer( - videoPlayerController: videoPlayerController as MediaKitController, - ); - } - - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - switch (state) { - case AppLifecycleState.inactive: - case AppLifecycleState.paused: - case AppLifecycleState.detached: - case AppLifecycleState.hidden: - close(); - break; - - case AppLifecycleState.resumed: - break; - } - } -} diff --git a/lib/viewers/vlc_direct_archive_video_viewer.dart b/lib/viewers/vlc_direct_archive_video_viewer.dart deleted file mode 100644 index beb091a..0000000 --- a/lib/viewers/vlc_direct_archive_video_viewer.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:netr/controllers/vlc_remote_controller.dart'; -import 'package:netr/helpers/stream_camera_helper.dart'; -import 'package:netr/viewers/direct_archive_video_viewer.dart'; -import 'package:netr/tool.dart'; - -class VlcDirectArchiveVideoViewerHome extends DirectArchiveVideoViewerHome { - const VlcDirectArchiveVideoViewerHome(StreamCameraHelper streamCameraHelper, - selectedVideoCamera, location, archiveDateTime, callback, - {super.key}) - : super( - streamCameraHelper, - selectedVideoCamera, - location, - archiveDateTime, - callback, - ); - - @override - VlcDirectArchiveVideoViewerHomeState createState() => - VlcDirectArchiveVideoViewerHomeState(); -} - -class VlcDirectArchiveVideoViewerHomeState - extends DirectArchiveVideoViewerHomeState { - @override - Widget build(BuildContext context) { - initializeViewer(context); - List navigators = []; - navigators.add(createIconButton(Icons.power, () {})); - navigators.addAll(getNavigators(context)); - navigators.add(getBackButton(context)); - - return Scaffold( - body: Center( - child: Column( - children: navigators, - ))); - } - - @override - VlcRemoteController getVideoPlayerControllerInternal(String url) { - VlcRemoteController vlcRemoteController = VlcRemoteController.network(url); - - return vlcRemoteController; - } -} diff --git a/lib/viewers/vlc_direct_video_viewer.dart b/lib/viewers/vlc_direct_video_viewer.dart deleted file mode 100644 index 54ee01a..0000000 --- a/lib/viewers/vlc_direct_video_viewer.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:netr/controllers/vlc_remote_controller.dart'; -import 'package:netr/viewers/direct_video_viewer.dart'; -import 'package:netr/tool.dart'; - -class VlcDirectVideoViewerHome extends DirectVideoViewerHome { - const VlcDirectVideoViewerHome( - super.streamCameraHelper, - super.selectedVideoCamera, - super.selectedVideoQuality, - super.location, - super.callback, - {super.key}); - - @override - VlcDirectVideoViewerHomeState createState() => - VlcDirectVideoViewerHomeState(); -} - -class VlcDirectVideoViewerHomeState - extends DirectVideoViewerHomeState { - @override - Widget build(BuildContext context) { - initializeViewer(context); - List navigators = []; - navigators.add(createIconButton(Icons.power, () {})); - navigators.addAll(getNavigators(context)); - navigators.add(getBackButton(context)); - - return Scaffold( - body: Center( - child: Column( - children: navigators, - ))); - } - - @override - VlcRemoteController getVideoPlayerControllerInternal(String url) { - VlcRemoteController vlcRemoteController = VlcRemoteController.network(url); - - return vlcRemoteController; - } -} diff --git a/lib/widgets/media_kit_player.dart b/lib/widgets/media_kit_player.dart deleted file mode 100644 index 0e1f6b4..0000000 --- a/lib/widgets/media_kit_player.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:media_kit_video/media_kit_video.dart'; -import 'package:flutter/material.dart'; -import 'package:netr/controllers/media_kit_controller.dart'; - -class MediaKitVideoPlayer extends StatefulWidget { - const MediaKitVideoPlayer({super.key, required this.videoPlayerController}); - - final MediaKitController videoPlayerController; - - @override - State createState() => _MediaKitVideoPlayerState(); -} - -class _MediaKitVideoPlayerState extends State { - @override - void dispose() { - super.dispose(); - widget.videoPlayerController.stop(); - widget.videoPlayerController.dispose(); - } - - @override - Widget build(BuildContext context) { - return Video( - controller: widget.videoPlayerController.controller, - controls: null, - //player: widget.videoPlayerController.player, - //scale: 1.0, - //showControls: false, - ); - } -} diff --git a/pubspec.yaml b/pubspec.yaml index a985c50..7907818 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -97,7 +97,6 @@ flutter: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg assets: - - images/vlc_icon.png - icons/netr.png - icons/eye.png diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index 06167db..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:netr/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/version.dart b/version.dart deleted file mode 100644 index e57de55..0000000 --- a/version.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -void main() { - File('pubspec.yaml') - .openRead() - .transform(utf8.decoder) - .transform(const LineSplitter()) - .forEach((line) { - final versionRegex = RegExp(r'^version:\s*([.0-9]+)\+([0-9]+)\s*$'); - if (versionRegex.hasMatch(line)) { - final match = versionRegex.firstMatch(line); - print('${match![1]}.${match[2]}'); - } - }); -}