From 43583be6daa8dae08db0fa097508d0aa478824e0 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Sun, 29 Dec 2024 18:57:53 +0800 Subject: [PATCH] opt: video boxfit option Closes #69 Signed-off-by: bggRGjQaUbCoE --- lib/pages/video/detail/controller.dart | 2 +- lib/plugin/pl_player/controller.dart | 99 +++++++++++++------------- lib/plugin/pl_player/view.dart | 37 ++++++---- 3 files changed, 77 insertions(+), 61 deletions(-) diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index aed82f2a..3eaeb80e 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -197,7 +197,7 @@ class VideoDetailController extends GetxController late AudioItem firstAudio; String? videoUrl; String? audioUrl; - late Duration defaultST; + late Duration defaultST = Duration.zero; // 亮度 double? brightness; // 默认记录历史记录 diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index f3585ab8..4e7a5a24 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -75,8 +75,8 @@ class PlPlayerController { final Rx _direction = 'horizontal'.obs; - final Rx _videoFit = Rx(videoFitType.first['attr']); - final Rx _videoFitDesc = Rx(videoFitType.first['desc']); + final Rx _videoFit = Rx(videoFitType[1]['attr']); + final Rx _videoFitDesc = Rx(videoFitType[1]['desc']); late StreamSubscription _dataListenerForVideoFit; late StreamSubscription _dataListenerForEnterFullscreen; @@ -116,12 +116,12 @@ class PlPlayerController { // final Durations durations; static List> videoFitType = [ + {'attr': BoxFit.fill, 'desc': '拉伸', 'toast': '拉伸至播放器尺寸,将产生变形(竖屏改为自动)'}, {'attr': BoxFit.contain, 'desc': '自动', 'toast': '缩放至播放器尺寸,保留黑边'}, {'attr': BoxFit.cover, 'desc': '裁剪', 'toast': '缩放至填满播放器,裁剪超出部分'}, - {'attr': BoxFit.fill, 'desc': '拉伸', 'toast': '拉伸至播放器尺寸,将产生变形(竖屏改为自动)'}, - {'attr': BoxFit.none, 'desc': '原始', 'toast': '不缩放,以视频原始尺寸显示'}, - {'attr': BoxFit.fitHeight, 'desc': '等高', 'toast': '缩放至撑满播放器高度'}, {'attr': BoxFit.fitWidth, 'desc': '等宽', 'toast': '缩放至撑满播放器宽度'}, + {'attr': BoxFit.fitHeight, 'desc': '等高', 'toast': '缩放至撑满播放器高度'}, + {'attr': BoxFit.none, 'desc': '原始', 'toast': '不缩放,以视频原始尺寸显示'}, {'attr': BoxFit.scaleDown, 'desc': '限制', 'toast': '仅超出时缩小至播放器尺寸'}, ]; @@ -1019,47 +1019,50 @@ class PlPlayerController { } /// Toggle Change the videofit accordingly - void toggleVideoFit() { - showDialog( - context: Get.context!, - builder: (context) { - return AlertDialog( - title: const Text('视频尺寸'), - content: StatefulBuilder(builder: (context, StateSetter setState) { - return Wrap( - alignment: WrapAlignment.start, - spacing: 8, - runSpacing: 2, - children: [ - for (var i in videoFitType) ...[ - if (_videoFit.value == i['attr']) ...[ - FilledButton( - onPressed: () async { - _videoFit.value = i['attr']; - _videoFitDesc.value = i['desc']; - setVideoFit(); - Get.back(); - }, - child: Text(i['desc']), - ), - ] else ...[ - FilledButton.tonal( - onPressed: () async { - _videoFit.value = i['attr']; - _videoFitDesc.value = i['desc']; - setVideoFit(); - Get.back(); - }, - child: Text(i['desc']), - ), - ] - ] - ], - ); - }), - ); - }, - ); + void toggleVideoFit(BoxFit value) { + _videoFit.value = videoFitType[value.index]['attr']; + _videoFitDesc.value = videoFitType[value.index]['desc']; + setVideoFit(); + // showDialog( + // context: Get.context!, + // builder: (context) { + // return AlertDialog( + // title: const Text('视频尺寸'), + // content: StatefulBuilder(builder: (context, StateSetter setState) { + // return Wrap( + // alignment: WrapAlignment.start, + // spacing: 8, + // runSpacing: 2, + // children: [ + // for (var i in videoFitType) ...[ + // if (_videoFit.value == i['attr']) ...[ + // FilledButton( + // onPressed: () async { + // _videoFit.value = i['attr']; + // _videoFitDesc.value = i['desc']; + // setVideoFit(); + // Get.back(); + // }, + // child: Text(i['desc']), + // ), + // ] else ...[ + // FilledButton.tonal( + // onPressed: () async { + // _videoFit.value = i['attr']; + // _videoFitDesc.value = i['desc']; + // setVideoFit(); + // Get.back(); + // }, + // child: Text(i['desc']), + // ), + // ] + // ] + // ], + // ); + // }), + // ); + // }, + // ); } /// 缓存fit @@ -1073,7 +1076,7 @@ class PlPlayerController { /// 读取fit Future getVideoFit() async { - int fitValue = video.get(VideoBoxKey.cacheVideoFit, defaultValue: 0); + int fitValue = video.get(VideoBoxKey.cacheVideoFit, defaultValue: 1); var attr = videoFitType[fitValue]['attr']; // 由于none与scaleDown涉及视频原始尺寸,需要等待视频加载后再设置,否则尺寸会变为0,出现错误; if (attr == BoxFit.none || attr == BoxFit.scaleDown) { @@ -1083,7 +1086,7 @@ class PlPlayerController { if (status == DataStatus.loaded) { _dataListenerForVideoFit.cancel(); int fitValue = - video.get(VideoBoxKey.cacheVideoFit, defaultValue: 0); + video.get(VideoBoxKey.cacheVideoFit, defaultValue: 1); var attr = videoFitType[fitValue]['attr']; if (attr == BoxFit.none || attr == BoxFit.scaleDown) { _videoFit.value = attr; diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index e0a6c926..98ac5888 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -415,19 +415,32 @@ class _PLVideoPlayerState extends State ), /// 画面比例 - BottomControlType.fit: SizedBox( - width: isFullScreen ? 42 : 35, + BottomControlType.fit: Container( height: 30, - child: TextButton( - onPressed: () => plPlayerController.toggleVideoFit(), - style: ButtonStyle( - padding: WidgetStateProperty.all(EdgeInsets.zero), - ), - child: Obx( - () => Text( - plPlayerController.videoFitDEsc.value, - style: const TextStyle(color: Colors.white, fontSize: 13), - ), + margin: const EdgeInsets.symmetric(horizontal: 10), + alignment: Alignment.center, + child: PopupMenuButton( + onSelected: (BoxFit value) { + plPlayerController.toggleVideoFit(value); + }, + initialValue: plPlayerController.videoFit.value, + color: Colors.black.withOpacity(0.8), + itemBuilder: (BuildContext context) { + return BoxFit.values.map((BoxFit boxFit) { + return PopupMenuItem( + height: 35, + padding: const EdgeInsets.only(left: 30), + value: boxFit, + child: Text( + "${PlPlayerController.videoFitType[boxFit.index]['desc']}", + style: const TextStyle(color: Colors.white, fontSize: 13), + ), + ); + }).toList(); + }, + child: Text( + "${PlPlayerController.videoFitType[plPlayerController.videoFit.value.index]['desc']}", + style: const TextStyle(color: Colors.white, fontSize: 13), ), ), ),