Merge pull request #1740 from evoL/evol/push-ylnpzyzxqnsx

feat: improved UX around video playback
pull/1754/head
Krille-chan 7 months ago committed by GitHub
commit 336aaf57f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -37,22 +37,34 @@ class EventVideoPlayer extends StatefulWidget {
} }
class EventVideoPlayerState extends State<EventVideoPlayer> { class EventVideoPlayerState extends State<EventVideoPlayer> {
ChewieController? _chewieManager; ChewieController? _chewieController;
VideoPlayerController? _videoPlayerController;
bool _isDownloading = false; bool _isDownloading = false;
String? _networkUri;
File? _tmpFile; // The video_player package only doesn't support Windows and Linux.
final _supportsVideoPlayer =
!PlatformInfos.isWindows && !PlatformInfos.isLinux;
void _downloadAction() async { void _downloadAction() async {
if (PlatformInfos.isDesktop) { if (!_supportsVideoPlayer) {
widget.event.saveFile(context); widget.event.saveFile(context);
return; return;
} }
setState(() => _isDownloading = true); setState(() => _isDownloading = true);
try { try {
final videoFile = await widget.event.downloadAndDecryptAttachment(); final videoFile = await widget.event.downloadAndDecryptAttachment();
// Dispose the controllers if we already have them.
_disposeControllers();
late VideoPlayerController videoPlayerController;
// Create the VideoPlayerController from the contents of videoFile.
if (kIsWeb) { if (kIsWeb) {
final blob = html.Blob([videoFile.bytes]); final blob = html.Blob([videoFile.bytes]);
_networkUri = html.Url.createObjectUrlFromBlob(blob); final networkUri = Uri.parse(html.Url.createObjectUrlFromBlob(blob));
videoPlayerController = VideoPlayerController.networkUrl(networkUri);
} else { } else {
final tempDir = await getTemporaryDirectory(); final tempDir = await getTemporaryDirectory();
final fileName = Uri.encodeComponent( final fileName = Uri.encodeComponent(
@ -62,25 +74,19 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
if (await file.exists() == false) { if (await file.exists() == false) {
await file.writeAsBytes(videoFile.bytes); await file.writeAsBytes(videoFile.bytes);
} }
_tmpFile = file; videoPlayerController = VideoPlayerController.file(file);
} }
final tmpFile = _tmpFile; _videoPlayerController = videoPlayerController;
final networkUri = _networkUri;
if (kIsWeb && networkUri != null && _chewieManager == null) { await videoPlayerController.initialize();
_chewieManager ??= ChewieController(
videoPlayerController: // Create a ChewieController on top.
VideoPlayerController.networkUrl(Uri.parse(networkUri)), _chewieController = ChewieController(
autoPlay: true, videoPlayerController: videoPlayerController,
autoInitialize: true, useRootNavigator: !kIsWeb,
);
} else if (!kIsWeb && tmpFile != null && _chewieManager == null) {
_chewieManager ??= ChewieController(
useRootNavigator: false,
videoPlayerController: VideoPlayerController.file(tmpFile),
autoPlay: true, autoPlay: true,
autoInitialize: true, autoInitialize: true,
); );
}
} on IOException catch (e) { } on IOException catch (e) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
@ -90,15 +96,20 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
} catch (e, s) { } catch (e, s) {
ErrorReporter(context, 'Unable to play video').onErrorCallback(e, s); ErrorReporter(context, 'Unable to play video').onErrorCallback(e, s);
} finally { } finally {
// Workaround for Chewie needs time to get the aspectRatio
await Future.delayed(const Duration(milliseconds: 100));
setState(() => _isDownloading = false); setState(() => _isDownloading = false);
} }
} }
void _disposeControllers() {
_chewieController?.dispose();
_videoPlayerController?.dispose();
_chewieController = null;
_videoPlayerController = null;
}
@override @override
void dispose() { void dispose() {
_chewieManager?.dispose(); _disposeControllers();
super.dispose(); super.dispose();
} }
@ -118,7 +129,7 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
const width = 300.0; const width = 300.0;
final chewieManager = _chewieManager; final chewieController = _chewieController;
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
spacing: 8, spacing: 8,
@ -128,8 +139,8 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
borderRadius: BorderRadius.circular(AppConfig.borderRadius), borderRadius: BorderRadius.circular(AppConfig.borderRadius),
child: SizedBox( child: SizedBox(
height: width, height: width,
child: chewieManager != null child: chewieController != null
? Center(child: Chewie(controller: chewieManager)) ? Center(child: Chewie(controller: chewieController))
: Stack( : Stack(
children: [ children: [
if (hasThumbnail) if (hasThumbnail)
@ -159,7 +170,9 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
strokeWidth: 2, strokeWidth: 2,
), ),
) )
: const Icon(Icons.play_circle_outlined), : _supportsVideoPlayer
? const Icon(Icons.play_circle_outlined)
: const Icon(Icons.file_download_outlined),
tooltip: _isDownloading tooltip: _isDownloading
? L10n.of(context).loadingPleaseWait ? L10n.of(context).loadingPleaseWait
: L10n.of(context).videoWithSize( : L10n.of(context).videoWithSize(

@ -178,10 +178,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: chewie name: chewie
sha256: "335df378c025588aef400c704bd71f0daea479d4cd57c471c88c056c1144e7cd" sha256: "0bf6f7692cb65f7b8f59a2a17025b9cbe8f75ab4251e66161a4fc86162475fb6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.8.5" version: "1.11.0"
cli_util: cli_util:
dependency: transitive dependency: transitive
description: description:
@ -2124,42 +2124,42 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: video_player name: video_player
sha256: "4a8c3492d734f7c39c2588a3206707a05ee80cef52e8c7f3b2078d430c84bc17" sha256: "7d78f0cfaddc8c19d4cb2d3bebe1bfef11f2103b0a03e5398b303a1bf65eeb14"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.9.2" version: "2.9.5"
video_player_android: video_player_android:
dependency: transitive dependency: transitive
description: description:
name: video_player_android name: video_player_android
sha256: ae5287ca367e206eb74d7b3dc1ce0b8912ab9a3fc0597b6a101a0a5239f229d3 sha256: ae7d4f1b41e3ac6d24dd9b9d5d6831b52d74a61bdd90a7a6262a33d8bb97c29a
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.7.9" version: "2.8.2"
video_player_avfoundation: video_player_avfoundation:
dependency: transitive dependency: transitive
description: description:
name: video_player_avfoundation name: video_player_avfoundation
sha256: cd5ab8a8bc0eab65ab0cea40304097edc46da574c8c1ecdee96f28cd8ef3792f sha256: "84b4752745eeccb6e75865c9aab39b3d28eb27ba5726d352d45db8297fbd75bc"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.6.2" version: "2.7.0"
video_player_platform_interface: video_player_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: video_player_platform_interface name: video_player_platform_interface
sha256: "229d7642ccd9f3dc4aba169609dd6b5f3f443bb4cc15b82f7785fcada5af9bbb" sha256: df534476c341ab2c6a835078066fc681b8265048addd853a1e3c78740316a844
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.3" version: "6.3.0"
video_player_web: video_player_web:
dependency: transitive dependency: transitive
description: description:
name: video_player_web name: video_player_web
sha256: "6dcdd298136523eaf7dfc31abaf0dfba9aa8a8dbc96670e87e9d42b6f2caf774" sha256: "3ef40ea6d72434edbfdba4624b90fd3a80a0740d260667d91e7ecd2d79e13476"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.4"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
@ -2172,18 +2172,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: wakelock_plus name: wakelock_plus
sha256: bf4ee6f17a2fa373ed3753ad0e602b7603f8c75af006d5b9bdade263928c0484 sha256: b90fbcc8d7bdf3b883ea9706d9d76b9978cb1dfa4351fcc8014d6ec31a493354
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.8" version: "1.2.11"
wakelock_plus_platform_interface: wakelock_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: wakelock_plus_platform_interface name: wakelock_plus_platform_interface
sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16" sha256: "70e780bc99796e1db82fe764b1e7dcb89a86f1e5b3afb1db354de50f2e41eb7a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.2"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
@ -2298,4 +2298,4 @@ packages:
version: "3.1.2" version: "3.1.2"
sdks: sdks:
dart: ">=3.7.0-0 <4.0.0" dart: ">=3.7.0-0 <4.0.0"
flutter: ">=3.24.0" flutter: ">=3.27.0"

@ -14,7 +14,7 @@ dependencies:
async: ^2.11.0 async: ^2.11.0
badges: ^3.1.2 badges: ^3.1.2
blurhash_dart: ^1.2.1 blurhash_dart: ^1.2.1
chewie: ^1.8.1 chewie: ^1.11.0
collection: ^1.18.0 collection: ^1.18.0
cross_file: ^0.3.4+2 cross_file: ^0.3.4+2
cupertino_icons: any cupertino_icons: any

Loading…
Cancel
Save