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;
String? videoUrl;
String? audioUrl;
late Duration defaultST;
late Duration defaultST = Duration.zero;
// 亮度
double? brightness;
// 默认记录历史记录

View File

@@ -75,8 +75,8 @@ class PlPlayerController {
final Rx<String> _direction = 'horizontal'.obs;
final Rx<BoxFit> _videoFit = Rx(videoFitType.first['attr']);
final Rx<String> _videoFitDesc = Rx(videoFitType.first['desc']);
final Rx<BoxFit> _videoFit = Rx(videoFitType[1]['attr']);
final Rx<String> _videoFitDesc = Rx(videoFitType[1]['desc']);
late StreamSubscription<DataStatus> _dataListenerForVideoFit;
late StreamSubscription<DataStatus> _dataListenerForEnterFullscreen;
@@ -116,12 +116,12 @@ class PlPlayerController {
// final Durations durations;
static List<Map<String, dynamic>> 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<void> 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;

View File

@@ -415,19 +415,32 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
),
/// 画面比例
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<BoxFit>(
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<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),
),
);
}).toList();
},
child: Text(
"${PlPlayerController.videoFitType[plPlayerController.videoFit.value.index]['desc']}",
style: const TextStyle(color: Colors.white, fontSize: 13),
),
),
),