Merge pull request #1740 from evoL/evol/push-ylnpzyzxqnsx
feat: improved UX around video playback
This commit is contained in:
commit
336aaf57f7
3 changed files with 61 additions and 48 deletions
|
|
@ -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;
|
|
||||||
final networkUri = _networkUri;
|
|
||||||
if (kIsWeb && networkUri != null && _chewieManager == null) {
|
|
||||||
_chewieManager ??= ChewieController(
|
|
||||||
videoPlayerController:
|
|
||||||
VideoPlayerController.networkUrl(Uri.parse(networkUri)),
|
|
||||||
autoPlay: true,
|
|
||||||
autoInitialize: true,
|
|
||||||
);
|
|
||||||
} else if (!kIsWeb && tmpFile != null && _chewieManager == null) {
|
|
||||||
_chewieManager ??= ChewieController(
|
|
||||||
useRootNavigator: false,
|
|
||||||
videoPlayerController: VideoPlayerController.file(tmpFile),
|
|
||||||
autoPlay: true,
|
|
||||||
autoInitialize: true,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
_videoPlayerController = videoPlayerController;
|
||||||
|
|
||||||
|
await videoPlayerController.initialize();
|
||||||
|
|
||||||
|
// Create a ChewieController on top.
|
||||||
|
_chewieController = ChewieController(
|
||||||
|
videoPlayerController: videoPlayerController,
|
||||||
|
useRootNavigator: !kIsWeb,
|
||||||
|
autoPlay: 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(
|
||||||
|
|
|
||||||
34
pubspec.lock
34
pubspec.lock
|
|
@ -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…
Add table
Add a link
Reference in a new issue