From 2dffbfd697efbd2ca04f23eec116d1fc0e14d4f0 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka <45696119+bdlukaa@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:14:50 -0300 Subject: [PATCH 1/3] feat: create unity_video_player_flutter --- .../unity_video_player/CHANGELOG.md | 3 -- .../unity_video_player/LICENSE | 1 - .../unity_video_player/pubspec.yaml | 2 + .../unity_video_player_flutter/.gitignore | 29 ++++++++++++++ .../unity_video_player_flutter/.metadata | 10 +++++ .../unity_video_player_flutter/README.md | 1 + .../analysis_options.yaml | 4 ++ .../lib/unity_video_player_flutter.dart | 7 ++++ .../unity_video_player_flutter/pubspec.yaml | 25 ++++++++++++ .../unity_video_player_main/LICENSE | 1 - .../unity_video_player_main/README.md | 40 +------------------ 11 files changed, 79 insertions(+), 44 deletions(-) delete mode 100644 packages/unity_video_player/unity_video_player/CHANGELOG.md delete mode 100644 packages/unity_video_player/unity_video_player/LICENSE create mode 100644 packages/unity_video_player/unity_video_player_flutter/.gitignore create mode 100644 packages/unity_video_player/unity_video_player_flutter/.metadata create mode 100644 packages/unity_video_player/unity_video_player_flutter/README.md create mode 100644 packages/unity_video_player/unity_video_player_flutter/analysis_options.yaml create mode 100644 packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart create mode 100644 packages/unity_video_player/unity_video_player_flutter/pubspec.yaml delete mode 100644 packages/unity_video_player/unity_video_player_main/LICENSE diff --git a/packages/unity_video_player/unity_video_player/CHANGELOG.md b/packages/unity_video_player/unity_video_player/CHANGELOG.md deleted file mode 100644 index 17139a01..00000000 --- a/packages/unity_video_player/unity_video_player/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.1 - -* Initial implementation diff --git a/packages/unity_video_player/unity_video_player/LICENSE b/packages/unity_video_player/unity_video_player/LICENSE deleted file mode 100644 index ba75c69f..00000000 --- a/packages/unity_video_player/unity_video_player/LICENSE +++ /dev/null @@ -1 +0,0 @@ -TODO: Add your license here. diff --git a/packages/unity_video_player/unity_video_player/pubspec.yaml b/packages/unity_video_player/unity_video_player/pubspec.yaml index 4b06d331..a2a4a8f2 100644 --- a/packages/unity_video_player/unity_video_player/pubspec.yaml +++ b/packages/unity_video_player/unity_video_player/pubspec.yaml @@ -33,3 +33,5 @@ flutter: default_package: unity_video_player_main windows: default_package: unity_video_player_main + web: + default_package: unity_video_player_main diff --git a/packages/unity_video_player/unity_video_player_flutter/.gitignore b/packages/unity_video_player/unity_video_player_flutter/.gitignore new file mode 100644 index 00000000..ac5aa989 --- /dev/null +++ b/packages/unity_video_player/unity_video_player_flutter/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/packages/unity_video_player/unity_video_player_flutter/.metadata b/packages/unity_video_player/unity_video_player_flutter/.metadata new file mode 100644 index 00000000..5512c947 --- /dev/null +++ b/packages/unity_video_player/unity_video_player_flutter/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "6cf9ab02baecddfa3daf0c1498e62b9dc617970d" + channel: "master" + +project_type: package diff --git a/packages/unity_video_player/unity_video_player_flutter/README.md b/packages/unity_video_player/unity_video_player_flutter/README.md new file mode 100644 index 00000000..1ed088a7 --- /dev/null +++ b/packages/unity_video_player/unity_video_player_flutter/README.md @@ -0,0 +1 @@ +`unity_video_player` imeplementation with `video_player` \ No newline at end of file diff --git a/packages/unity_video_player/unity_video_player_flutter/analysis_options.yaml b/packages/unity_video_player/unity_video_player_flutter/analysis_options.yaml new file mode 100644 index 00000000..a5744c1c --- /dev/null +++ b/packages/unity_video_player/unity_video_player_flutter/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart b/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart new file mode 100644 index 00000000..4404c60d --- /dev/null +++ b/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart @@ -0,0 +1,7 @@ +library unity_video_player_flutter; + +/// A Calculator. +class Calculator { + /// Returns [value] plus 1. + int addOne(int value) => value + 1; +} diff --git a/packages/unity_video_player/unity_video_player_flutter/pubspec.yaml b/packages/unity_video_player/unity_video_player_flutter/pubspec.yaml new file mode 100644 index 00000000..2fa2a498 --- /dev/null +++ b/packages/unity_video_player/unity_video_player_flutter/pubspec.yaml @@ -0,0 +1,25 @@ +name: unity_video_player_flutter +description: "unity_video_player implementation with video_player" +version: 0.0.1 +homepage: + +publish_to: "none" + +environment: + sdk: '>=3.3.0-149.0.dev <4.0.0' + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + unity_video_player_platform_interface: + path: ../unity_video_player_platform_interface/ + video_player: ^2.8.1 + flutterpi_gstreamer_video_player: ^0.1.1+1 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^3.0.0 + +flutter: diff --git a/packages/unity_video_player/unity_video_player_main/LICENSE b/packages/unity_video_player/unity_video_player_main/LICENSE deleted file mode 100644 index ba75c69f..00000000 --- a/packages/unity_video_player/unity_video_player_main/LICENSE +++ /dev/null @@ -1 +0,0 @@ -TODO: Add your license here. diff --git a/packages/unity_video_player/unity_video_player_main/README.md b/packages/unity_video_player/unity_video_player_main/README.md index 02fe8eca..b63191bb 100644 --- a/packages/unity_video_player/unity_video_player_main/README.md +++ b/packages/unity_video_player/unity_video_player_main/README.md @@ -1,39 +1 @@ - - -TODO: Put a short description of the package here that helps potential users -know whether this package might be useful for them. - -## Features - -TODO: List what your package can do. Maybe include images, gifs, or videos. - -## Getting started - -TODO: List prerequisites and provide or point to information on how to -start using the package. - -## Usage - -TODO: Include short and useful examples for package users. Add longer examples -to `/example` folder. - -```dart -const like = 'sample'; -``` - -## Additional information - -TODO: Tell users more about the package: where to find more information, how to -contribute to the package, how to file issues, what response they can expect -from the package authors, and more. +`unity_video_player` implementation with `media_kit` \ No newline at end of file From 9ef3b4c1059dbf900aa6e0d2bde339639e5c9724 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka <45696119+bdlukaa@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:39:31 -0300 Subject: [PATCH 2/3] feat: implement UnityVideoPlayerFlutter --- .../lib/unity_video_player_flutter.dart | 237 +++++++++++++++++- 1 file changed, 233 insertions(+), 4 deletions(-) diff --git a/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart b/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart index 4404c60d..d4f82739 100644 --- a/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart +++ b/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart @@ -1,7 +1,236 @@ library unity_video_player_flutter; -/// A Calculator. -class Calculator { - /// Returns [value] plus 1. - int addOne(int value) => value + 1; +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterpi_gstreamer_video_player/flutterpi_gstreamer_video_player.dart'; +import 'package:video_player/video_player.dart'; +import 'package:unity_video_player_platform_interface/unity_video_player_platform_interface.dart'; + +class UnityVideoPlayerFlutterInterface extends UnityVideoPlayerInterface { + /// Registers this class as the default instance of [UnityVideoPlayerInterface]. + static void registerWith() { + UnityVideoPlayerInterface.instance = UnityVideoPlayerFlutterInterface(); + } + + @override + Future initialize() async { + FlutterpiVideoPlayer.registerWith(); + } + + @override + UnityVideoPlayer createPlayer({ + int? width, + int? height, + bool enableCache = false, + RTSPProtocol? rtspProtocol, + VoidCallback? onReload, + String? title, + }) { + final player = UnityVideoPlayerFlutter( + width: width, + height: height, + enableCache: enableCache, + title: title, + ); + UnityVideoPlayerInterface.registerPlayer(player); + return player; + } + + @override + Widget createVideoView({ + Key? key, + required covariant UnityVideoPlayerFlutter player, + UnityVideoFit fit = UnityVideoFit.contain, + UnityVideoPaneBuilder? paneBuilder, + UnityVideoBuilder? videoBuilder, + Color color = const Color(0xFF000000), + }) { + videoBuilder ??= (context, video) => video; + + return Builder(builder: (context) { + return Stack(children: [ + Positioned.fill( + child: videoBuilder!( + context, + ColoredBox( + color: color, + child: player.player == null + ? const SizedBox.expand() + : VideoPlayer(player.player!), + ), + ), + ), + if (paneBuilder != null) + Positioned.fill( + child: Material( + type: MaterialType.transparency, + child: paneBuilder(context, player), + ), + ), + ]); + }); + } +} + +class UnityVideoPlayerFlutter extends UnityVideoPlayer { + VideoPlayerController? player; + + final _videoStream = StreamController.broadcast(); + + UnityVideoPlayerFlutter({ + super.width, + super.height, + bool enableCache = false, + RTSPProtocol? rtspProtocol, + String? title, + }); + + @override + String? get dataSource => player?.dataSource; + + @override + Stream get onError => _videoStream.stream + .where((v) => v.errorDescription != null) + .map((e) => e.errorDescription!); + + @override + Duration get duration => player?.value.duration ?? Duration.zero; + + @override + Stream get onDurationUpdate => + _videoStream.stream.map((_) => duration); + + @override + Duration get currentPos => player?.value.position ?? Duration.zero; + + @override + Stream get onCurrentPosUpdate => + _videoStream.stream.map((_) => currentPos); + + @override + bool get isBuffering => player?.value.isBuffering ?? false; + + @override + Duration get currentBuffer => + player?.value.buffered.last.end ?? Duration.zero; + + @override + Stream get onBufferUpdate => + _videoStream.stream.map((_) => currentBuffer); + + @override + bool get isSeekable => duration > Duration.zero; + + @override + Stream get onBufferStateUpdate => + _videoStream.stream.map((_) => isBuffering); + + @override + bool get isPlaying => player?.value.isPlaying ?? false; + + @override + Stream get onPlayingStateUpdate => + _videoStream.stream.map((_) => isPlaying); + + @override + Future setDataSource(String url, {bool autoPlay = true}) async { + if (url == dataSource) return Future.value(); + debugPrint('Playing $url'); + + if (player != null) { + await player?.dispose(); + } + + player = VideoPlayerController.networkUrl(Uri.parse(url)); + await player!.initialize(); + notifyListeners(); + player!.addListener(() { + _videoStream.add(player!.value); + }); + if (autoPlay) { + await player!.play(); + } + } + + @override + Future setMultipleDataSource(List url, {bool autoPlay = true}) { + throw UnsupportedError( + 'setMultipleDataSource is not supported on this platform', + ); + } + + // Volume in media kit goes from 0 to 100 + @override + Future setVolume(double volume) async => + await player?.setVolume(volume); + + @override + double get volume => (player?.value.volume ?? 0.0); + + @override + Stream get volumeStream => _videoStream.stream.map((_) => volume); + + @override + double get fps => 0.0; + @override + Stream get fpsStream => + throw UnsupportedError('Fps is not implemented on this platform'); + + @override + double get aspectRatio => player?.value.aspectRatio ?? 1.0; + + @override + Future setSpeed(double speed) async => + await player?.setPlaybackSpeed(speed); + @override + Future seekTo(Duration position) async => + await player?.seekTo(position); + + @override + Future setSize(Size size) => Future.value(); + + @override + Future start() async => await player?.play(); + + @override + Future pause() async => await player?.pause(); + + @override + Future release() async { + if (!kIsWeb && Platform.isLinux) { + await pause(); + await Future.delayed(const Duration(milliseconds: 150)); + } + } + + @override + Future reset() async { + await pause(); + await seekTo(Duration.zero); + } + + @override + Future resetCrop() => crop(-1, -1, -1); + + /// Crops the current video into a box at the given row and column + @override + Future crop(int row, int col, int size) async { + throw UnsupportedError('Cropping is not implemented on this platform'); + } + + @override + bool get isCropped { + throw UnsupportedError('Cropping is not implemented on this platform'); + } + + @override + Future dispose() async { + await release(); + await super.dispose(); + await _videoStream.close(); + UnityVideoPlayerInterface.unregisterPlayer(this); + } } From 81413259cb6eca0abc5c9b336e63cf73db6424f5 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Mon, 25 Dec 2023 12:52:16 -0300 Subject: [PATCH 3/3] feat: register gstreamer interface on a pi environment --- README.md | 2 +- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + .../unity_video_player/pubspec.yaml | 4 +- .../unity_video_player_flutter/README.md | 4 +- .../lib/unity_video_player_flutter.dart | 7 +- .../unity_video_player_flutter/pubspec.yaml | 2 + pubspec.lock | 75 ++++++++++++++++++- 7 files changed, 90 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 007a9771..0a405d0f 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ flutter build [linux|windows|macos|android|ios] The automated build process is done using GitHub Actions. You may find the workflow [here](.github/workflows/main.yml). The workflow builds the app for all supported platforms & uploads the artifacts to the release page. -On Linux, a Flutter executable with different environment variables is used to build the app for different distributions. This tells the app how the system is configured and how it should install updates. To run for Linux, you need to provide the following environment variables based on your system, where `[DISTRO_ENV]` can be `appimage` (AppImage), `deb` (Debian), `rpm` (RedHat) or `tar.gz` (Tarball). +On Linux, a Flutter executable with different environment variables is used to build the app for different distributions. This tells the app how the system is configured and how it should install updates. To run for Linux, you need to provide the following environment variables based on your system, where `[DISTRO_ENV]` can be `appimage` (AppImage), `deb` (Debian), `rpm` (RedHat), `tar.gz` (Tarball) or `pi` (Raspberry Pi). ```bash flutter run --dart-define-from-file=linux/env/[DISTRO_ENV].json diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index fa1aec86..6dbc1bb5 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -19,6 +19,7 @@ import screen_brightness_macos import screen_retriever import system_date_time_format import url_launcher_macos +import video_player_avfoundation import wakelock_plus import window_manager @@ -37,6 +38,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) SystemDateTimeFormatPlugin.register(with: registry.registrar(forPlugin: "SystemDateTimeFormatPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/packages/unity_video_player/unity_video_player/pubspec.yaml b/packages/unity_video_player/unity_video_player/pubspec.yaml index a2a4a8f2..f8c8ac98 100644 --- a/packages/unity_video_player/unity_video_player/pubspec.yaml +++ b/packages/unity_video_player/unity_video_player/pubspec.yaml @@ -14,6 +14,8 @@ dependencies: sdk: flutter unity_video_player_main: path: ../unity_video_player_main + unity_video_player_flutter: + path: ../unity_video_player_flutter dev_dependencies: flutter_test: @@ -30,7 +32,7 @@ flutter: macos: default_package: unity_video_player_main linux: - default_package: unity_video_player_main + default_package: unity_video_player_flutter windows: default_package: unity_video_player_main web: diff --git a/packages/unity_video_player/unity_video_player_flutter/README.md b/packages/unity_video_player/unity_video_player_flutter/README.md index 1ed088a7..6d8f7f72 100644 --- a/packages/unity_video_player/unity_video_player_flutter/README.md +++ b/packages/unity_video_player/unity_video_player_flutter/README.md @@ -1 +1,3 @@ -`unity_video_player` imeplementation with `video_player` \ No newline at end of file +`unity_video_player` imeplementation with `video_player`. + +This was created to be used in the Raspberry Pi, but it should work on any platform. \ No newline at end of file diff --git a/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart b/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart index d4f82739..09999a61 100644 --- a/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart +++ b/packages/unity_video_player/unity_video_player_flutter/lib/unity_video_player_flutter.dart @@ -6,13 +6,18 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutterpi_gstreamer_video_player/flutterpi_gstreamer_video_player.dart'; +import 'package:unity_video_player_main/unity_video_player_main.dart'; import 'package:video_player/video_player.dart'; import 'package:unity_video_player_platform_interface/unity_video_player_platform_interface.dart'; class UnityVideoPlayerFlutterInterface extends UnityVideoPlayerInterface { /// Registers this class as the default instance of [UnityVideoPlayerInterface]. static void registerWith() { - UnityVideoPlayerInterface.instance = UnityVideoPlayerFlutterInterface(); + if ('pi' case const String.fromEnvironment('linux_environment')) { + UnityVideoPlayerInterface.instance = UnityVideoPlayerFlutterInterface(); + return; + } + UnityVideoPlayerInterface.instance = UnityVideoPlayerMediaKitInterface(); } @override diff --git a/packages/unity_video_player/unity_video_player_flutter/pubspec.yaml b/packages/unity_video_player/unity_video_player_flutter/pubspec.yaml index 2fa2a498..fa3f833f 100644 --- a/packages/unity_video_player/unity_video_player_flutter/pubspec.yaml +++ b/packages/unity_video_player/unity_video_player_flutter/pubspec.yaml @@ -14,6 +14,8 @@ dependencies: sdk: flutter unity_video_player_platform_interface: path: ../unity_video_player_platform_interface/ + unity_video_player_main: + path: ../unity_video_player_main video_player: ^2.8.1 flutterpi_gstreamer_video_player: ^0.1.1+1 diff --git a/pubspec.lock b/pubspec.lock index 4c097288..81dd4979 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -161,6 +161,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" dbus: dependency: transitive description: @@ -349,6 +357,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutterpi_gstreamer_video_player: + dependency: transitive + description: + name: flutterpi_gstreamer_video_player + sha256: "1f70015783e8a9c4805ee1590d351131bf83853a53fc6bc7b93c3a325804f061" + url: "https://pub.dev" + source: hosted + version: "0.1.1+1" get_it: dependency: transitive description: @@ -389,6 +405,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + html: + dependency: transitive + description: + name: html + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" + source: hosted + version: "0.15.4" http: dependency: "direct main" description: @@ -958,6 +982,13 @@ packages: relative: true source: path version: "0.0.1" + unity_video_player_flutter: + dependency: transitive + description: + path: "packages/unity_video_player/unity_video_player_flutter" + relative: true + source: path + version: "0.0.1" unity_video_player_main: dependency: transitive description: @@ -1076,6 +1107,46 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + video_player: + dependency: transitive + description: + name: video_player + sha256: e16f0a83601a78d165dabc17e4dac50997604eb9e4cc76e10fa219046b70cef3 + url: "https://pub.dev" + source: hosted + version: "2.8.1" + video_player_android: + dependency: transitive + description: + name: video_player_android + sha256: "3fe89ab07fdbce786e7eb25b58532d6eaf189ceddc091cb66cba712f8d9e8e55" + url: "https://pub.dev" + source: hosted + version: "2.4.10" + video_player_avfoundation: + dependency: transitive + description: + name: video_player_avfoundation + sha256: "01a57940e1dabc8769ccd457c4ae9ea50274e7d5a7617f7820dae5fe1d8436ae" + url: "https://pub.dev" + source: hosted + version: "2.5.3" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + sha256: be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a + url: "https://pub.dev" + source: hosted + version: "6.2.1" + video_player_web: + dependency: transitive + description: + name: video_player_web + sha256: ab7a462b07d9ca80bed579e30fb3bce372468f1b78642e0911b10600f2c5cb5b + url: "https://pub.dev" + source: hosted + version: "2.1.2" vm_service: dependency: transitive description: @@ -1173,5 +1244,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.3.0-149.0.dev <4.0.0" + flutter: ">=3.16.0"