opt: video boxfit option

Closes #69

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2024-12-29 18:57:53 +08:00
parent 836f1a9b06
commit 43583be6da
3 changed files with 77 additions and 61 deletions

View File

@@ -197,7 +197,7 @@ class VideoDetailController extends GetxController
late AudioItem firstAudio; late AudioItem firstAudio;
String? videoUrl; String? videoUrl;
String? audioUrl; String? audioUrl;
late Duration defaultST; late Duration defaultST = Duration.zero;
// 亮度 // 亮度
double? brightness; double? brightness;
// 默认记录历史记录 // 默认记录历史记录

View File

@@ -75,8 +75,8 @@ class PlPlayerController {
final Rx<String> _direction = 'horizontal'.obs; final Rx<String> _direction = 'horizontal'.obs;
final Rx<BoxFit> _videoFit = Rx(videoFitType.first['attr']); final Rx<BoxFit> _videoFit = Rx(videoFitType[1]['attr']);
final Rx<String> _videoFitDesc = Rx(videoFitType.first['desc']); final Rx<String> _videoFitDesc = Rx(videoFitType[1]['desc']);
late StreamSubscription<DataStatus> _dataListenerForVideoFit; late StreamSubscription<DataStatus> _dataListenerForVideoFit;
late StreamSubscription<DataStatus> _dataListenerForEnterFullscreen; late StreamSubscription<DataStatus> _dataListenerForEnterFullscreen;
@@ -116,12 +116,12 @@ class PlPlayerController {
// final Durations durations; // final Durations durations;
static List<Map<String, dynamic>> videoFitType = [ static List<Map<String, dynamic>> videoFitType = [
{'attr': BoxFit.fill, 'desc': '拉伸', 'toast': '拉伸至播放器尺寸,将产生变形(竖屏改为自动)'},
{'attr': BoxFit.contain, 'desc': '自动', 'toast': '缩放至播放器尺寸,保留黑边'}, {'attr': BoxFit.contain, 'desc': '自动', 'toast': '缩放至播放器尺寸,保留黑边'},
{'attr': BoxFit.cover, '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.fitWidth, 'desc': '等宽', 'toast': '缩放至撑满播放器宽度'},
{'attr': BoxFit.fitHeight, 'desc': '等高', 'toast': '缩放至撑满播放器高度'},
{'attr': BoxFit.none, 'desc': '原始', 'toast': '不缩放,以视频原始尺寸显示'},
{'attr': BoxFit.scaleDown, 'desc': '限制', 'toast': '仅超出时缩小至播放器尺寸'}, {'attr': BoxFit.scaleDown, 'desc': '限制', 'toast': '仅超出时缩小至播放器尺寸'},
]; ];
@@ -1019,47 +1019,50 @@ class PlPlayerController {
} }
/// Toggle Change the videofit accordingly /// Toggle Change the videofit accordingly
void toggleVideoFit() { void toggleVideoFit(BoxFit value) {
showDialog( _videoFit.value = videoFitType[value.index]['attr'];
context: Get.context!, _videoFitDesc.value = videoFitType[value.index]['desc'];
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(); setVideoFit();
Get.back(); // showDialog(
}, // context: Get.context!,
child: Text(i['desc']), // builder: (context) {
), // return AlertDialog(
] else ...[ // title: const Text('视频尺寸'),
FilledButton.tonal( // content: StatefulBuilder(builder: (context, StateSetter setState) {
onPressed: () async { // return Wrap(
_videoFit.value = i['attr']; // alignment: WrapAlignment.start,
_videoFitDesc.value = i['desc']; // spacing: 8,
setVideoFit(); // runSpacing: 2,
Get.back(); // children: [
}, // for (var i in videoFitType) ...[
child: Text(i['desc']), // 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 /// 缓存fit
@@ -1073,7 +1076,7 @@ class PlPlayerController {
/// 读取fit /// 读取fit
Future<void> getVideoFit() async { Future<void> getVideoFit() async {
int fitValue = video.get(VideoBoxKey.cacheVideoFit, defaultValue: 0); int fitValue = video.get(VideoBoxKey.cacheVideoFit, defaultValue: 1);
var attr = videoFitType[fitValue]['attr']; var attr = videoFitType[fitValue]['attr'];
// 由于none与scaleDown涉及视频原始尺寸需要等待视频加载后再设置否则尺寸会变为0出现错误; // 由于none与scaleDown涉及视频原始尺寸需要等待视频加载后再设置否则尺寸会变为0出现错误;
if (attr == BoxFit.none || attr == BoxFit.scaleDown) { if (attr == BoxFit.none || attr == BoxFit.scaleDown) {
@@ -1083,7 +1086,7 @@ class PlPlayerController {
if (status == DataStatus.loaded) { if (status == DataStatus.loaded) {
_dataListenerForVideoFit.cancel(); _dataListenerForVideoFit.cancel();
int fitValue = int fitValue =
video.get(VideoBoxKey.cacheVideoFit, defaultValue: 0); video.get(VideoBoxKey.cacheVideoFit, defaultValue: 1);
var attr = videoFitType[fitValue]['attr']; var attr = videoFitType[fitValue]['attr'];
if (attr == BoxFit.none || attr == BoxFit.scaleDown) { if (attr == BoxFit.none || attr == BoxFit.scaleDown) {
_videoFit.value = attr; _videoFit.value = attr;

View File

@@ -415,19 +415,32 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
), ),
/// 画面比例 /// 画面比例
BottomControlType.fit: SizedBox( BottomControlType.fit: Container(
width: isFullScreen ? 42 : 35,
height: 30, height: 30,
child: TextButton( margin: const EdgeInsets.symmetric(horizontal: 10),
onPressed: () => plPlayerController.toggleVideoFit(), alignment: Alignment.center,
style: ButtonStyle( child: PopupMenuButton<BoxFit>(
padding: WidgetStateProperty.all(EdgeInsets.zero), onSelected: (BoxFit value) {
), plPlayerController.toggleVideoFit(value);
child: Obx( },
() => Text( initialValue: plPlayerController.videoFit.value,
plPlayerController.videoFitDEsc.value, color: Colors.black.withOpacity(0.8),
itemBuilder: (BuildContext context) {
return BoxFit.values.map((BoxFit boxFit) {
return PopupMenuItem<BoxFit>(
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), 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),
), ),
), ),
), ),