mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: custom subtitle fontscale
Closes #28 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -894,6 +894,8 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
double fontSizeVal = widget.controller!.fontSizeVal;
|
double fontSizeVal = widget.controller!.fontSizeVal;
|
||||||
// 全屏字体大小
|
// 全屏字体大小
|
||||||
double fontSizeFSVal = widget.controller!.fontSizeFSVal;
|
double fontSizeFSVal = widget.controller!.fontSizeFSVal;
|
||||||
|
double subtitleFontScale = widget.controller!.subtitleFontScale.value;
|
||||||
|
double subtitleFontScaleFS = widget.controller!.subtitleFontScaleFS.value;
|
||||||
// 弹幕速度
|
// 弹幕速度
|
||||||
double danmakuDurationVal = widget.controller!.danmakuDurationVal;
|
double danmakuDurationVal = widget.controller!.danmakuDurationVal;
|
||||||
// 弹幕描边
|
// 弹幕描边
|
||||||
@@ -912,13 +914,18 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
builder: (BuildContext context, StateSetter setState) {
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
return Container(
|
return Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 580,
|
height: 600,
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||||
),
|
),
|
||||||
margin: const EdgeInsets.all(12),
|
margin: EdgeInsets.only(
|
||||||
|
left: 12,
|
||||||
|
top: 12,
|
||||||
|
right: 12,
|
||||||
|
bottom: widget.controller?.isFullScreen.value == true ? 70 : 12,
|
||||||
|
),
|
||||||
padding: const EdgeInsets.only(left: 14, right: 14),
|
padding: const EdgeInsets.only(left: 14, right: 14),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -1258,6 +1265,76 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
'字幕字体大小 ${(subtitleFontScale * 100).toStringAsFixed(1)}%'),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 0,
|
||||||
|
bottom: 6,
|
||||||
|
left: 10,
|
||||||
|
right: 10,
|
||||||
|
),
|
||||||
|
child: SliderTheme(
|
||||||
|
data: SliderThemeData(
|
||||||
|
trackShape: MSliderTrackShape(),
|
||||||
|
thumbColor: Theme.of(context).colorScheme.primary,
|
||||||
|
activeTrackColor: Theme.of(context).colorScheme.primary,
|
||||||
|
trackHeight: 10,
|
||||||
|
thumbShape: const RoundSliderThumbShape(
|
||||||
|
enabledThumbRadius: 6.0),
|
||||||
|
),
|
||||||
|
child: Slider(
|
||||||
|
min: 0.5,
|
||||||
|
max: 2.5,
|
||||||
|
value: subtitleFontScale,
|
||||||
|
divisions: 20,
|
||||||
|
label:
|
||||||
|
'${(subtitleFontScale * 100).toStringAsFixed(1)}%',
|
||||||
|
onChanged: (double val) {
|
||||||
|
subtitleFontScale = val;
|
||||||
|
widget.controller!.subtitleFontScale.value =
|
||||||
|
subtitleFontScale;
|
||||||
|
widget.controller?.putDanmakuSettings();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'全屏字幕字体大小 ${(subtitleFontScaleFS * 100).toStringAsFixed(1)}%'),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 0,
|
||||||
|
bottom: 6,
|
||||||
|
left: 10,
|
||||||
|
right: 10,
|
||||||
|
),
|
||||||
|
child: SliderTheme(
|
||||||
|
data: SliderThemeData(
|
||||||
|
trackShape: MSliderTrackShape(),
|
||||||
|
thumbColor: Theme.of(context).colorScheme.primary,
|
||||||
|
activeTrackColor: Theme.of(context).colorScheme.primary,
|
||||||
|
trackHeight: 10,
|
||||||
|
thumbShape: const RoundSliderThumbShape(
|
||||||
|
enabledThumbRadius: 6.0),
|
||||||
|
),
|
||||||
|
child: Slider(
|
||||||
|
min: 0.5,
|
||||||
|
max: 2.5,
|
||||||
|
value: subtitleFontScaleFS,
|
||||||
|
divisions: 20,
|
||||||
|
label:
|
||||||
|
'${(subtitleFontScaleFS * 100).toStringAsFixed(1)}%',
|
||||||
|
onChanged: (double val) {
|
||||||
|
subtitleFontScaleFS = val;
|
||||||
|
widget.controller!.subtitleFontScaleFS.value =
|
||||||
|
subtitleFontScaleFS;
|
||||||
|
widget.controller?.putDanmakuSettings();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
Text('弹幕时长 $danmakuDurationVal 秒'),
|
Text('弹幕时长 $danmakuDurationVal 秒'),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
|
|||||||
@@ -258,6 +258,8 @@ class PlPlayerController {
|
|||||||
double? defaultDuration;
|
double? defaultDuration;
|
||||||
late bool enableAutoLongPressSpeed = false;
|
late bool enableAutoLongPressSpeed = false;
|
||||||
late bool enableLongShowControl;
|
late bool enableLongShowControl;
|
||||||
|
RxDouble subtitleFontScale = (1.0).obs;
|
||||||
|
RxDouble subtitleFontScaleFS = (1.5).obs;
|
||||||
|
|
||||||
// 播放顺序相关
|
// 播放顺序相关
|
||||||
PlayRepeat playRepeat = PlayRepeat.pause;
|
PlayRepeat playRepeat = PlayRepeat.pause;
|
||||||
@@ -351,6 +353,8 @@ class PlPlayerController {
|
|||||||
setting.get(SettingBoxKey.danmakuFontScale, defaultValue: 1.0);
|
setting.get(SettingBoxKey.danmakuFontScale, defaultValue: 1.0);
|
||||||
// 全屏字体大小
|
// 全屏字体大小
|
||||||
fontSizeFSVal = GStorage.danmakuFontScaleFS;
|
fontSizeFSVal = GStorage.danmakuFontScaleFS;
|
||||||
|
subtitleFontScale.value = GStorage.subtitleFontScale;
|
||||||
|
subtitleFontScaleFS.value = GStorage.subtitleFontScaleFS;
|
||||||
// 弹幕时间
|
// 弹幕时间
|
||||||
danmakuDurationVal =
|
danmakuDurationVal =
|
||||||
setting.get(SettingBoxKey.danmakuDuration, defaultValue: 7.29);
|
setting.get(SettingBoxKey.danmakuDuration, defaultValue: 7.29);
|
||||||
@@ -1296,6 +1300,8 @@ class PlPlayerController {
|
|||||||
setting.put(SettingBoxKey.danmakuOpacity, opacityVal);
|
setting.put(SettingBoxKey.danmakuOpacity, opacityVal);
|
||||||
setting.put(SettingBoxKey.danmakuFontScale, fontSizeVal);
|
setting.put(SettingBoxKey.danmakuFontScale, fontSizeVal);
|
||||||
setting.put(SettingBoxKey.danmakuFontScaleFS, fontSizeFSVal);
|
setting.put(SettingBoxKey.danmakuFontScaleFS, fontSizeFSVal);
|
||||||
|
setting.put(SettingBoxKey.subtitleFontScale, subtitleFontScale.value);
|
||||||
|
setting.put(SettingBoxKey.subtitleFontScaleFS, subtitleFontScaleFS.value);
|
||||||
setting.put(SettingBoxKey.danmakuDuration, danmakuDurationVal);
|
setting.put(SettingBoxKey.danmakuDuration, danmakuDurationVal);
|
||||||
setting.put(SettingBoxKey.strokeWidth, strokeWidth);
|
setting.put(SettingBoxKey.strokeWidth, strokeWidth);
|
||||||
setting.put(SettingBoxKey.fontWeight, fontWeight);
|
setting.put(SettingBoxKey.fontWeight, fontWeight);
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
|||||||
late BangumiIntroController? bangumiIntroController;
|
late BangumiIntroController? bangumiIntroController;
|
||||||
|
|
||||||
final GlobalKey _playerKey = GlobalKey();
|
final GlobalKey _playerKey = GlobalKey();
|
||||||
|
final GlobalKey<VideoState> _key = GlobalKey<VideoState>();
|
||||||
|
|
||||||
final RxBool _mountSeekBackwardButton = false.obs;
|
final RxBool _mountSeekBackwardButton = false.obs;
|
||||||
final RxBool _mountSeekForwardButton = false.obs;
|
final RxBool _mountSeekForwardButton = false.obs;
|
||||||
final RxBool _hideSeekBackwardButton = false.obs;
|
final RxBool _hideSeekBackwardButton = false.obs;
|
||||||
@@ -529,19 +531,43 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlPlayerController get plPlayerController => widget.controller;
|
||||||
|
|
||||||
|
TextStyle get subTitleStyle => TextStyle(
|
||||||
|
height: 1.5,
|
||||||
|
fontSize: 16 *
|
||||||
|
(plPlayerController.isFullScreen.value
|
||||||
|
? plPlayerController.subtitleFontScaleFS.value
|
||||||
|
: plPlayerController.subtitleFontScale.value),
|
||||||
|
letterSpacing: 0.1,
|
||||||
|
wordSpacing: 0.1,
|
||||||
|
color: Color(0xffffffff),
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
backgroundColor: Color(0xaa000000),
|
||||||
|
);
|
||||||
|
|
||||||
|
void _updateSubtitle(double value) {
|
||||||
|
_key.currentState?.update(
|
||||||
|
subtitleViewConfiguration: SubtitleViewConfiguration(
|
||||||
|
style: subTitleStyle.copyWith(fontSize: 16 * value),
|
||||||
|
padding: const EdgeInsets.all(24.0),
|
||||||
|
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final PlPlayerController plPlayerController = widget.controller;
|
if (plPlayerController.isFullScreen.value) {
|
||||||
|
plPlayerController.subtitleFontScaleFS.listen((value) {
|
||||||
|
_updateSubtitle(value);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
plPlayerController.subtitleFontScale.listen((value) {
|
||||||
|
_updateSubtitle(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
final Color colorTheme = Theme.of(context).colorScheme.primary;
|
final Color colorTheme = Theme.of(context).colorScheme.primary;
|
||||||
const TextStyle subTitleStyle = TextStyle(
|
|
||||||
height: 1.5,
|
|
||||||
fontSize: 20.0,
|
|
||||||
letterSpacing: 0.1,
|
|
||||||
wordSpacing: 0.1,
|
|
||||||
color: Color(0xffffffff),
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
backgroundColor: Color(0xaa000000),
|
|
||||||
);
|
|
||||||
const TextStyle textStyle = TextStyle(
|
const TextStyle textStyle = TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -684,7 +710,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
|||||||
_gestureType = null;
|
_gestureType = null;
|
||||||
},
|
},
|
||||||
child: Video(
|
child: Video(
|
||||||
key: ValueKey('${plPlayerController.videoFit.value}'),
|
key: _key,
|
||||||
controller: videoController,
|
controller: videoController,
|
||||||
controls: NoVideoControls,
|
controls: NoVideoControls,
|
||||||
pauseUponEnteringBackgroundMode:
|
pauseUponEnteringBackgroundMode:
|
||||||
|
|||||||
@@ -99,6 +99,12 @@ class GStorage {
|
|||||||
static double get danmakuFontScaleFS =>
|
static double get danmakuFontScaleFS =>
|
||||||
setting.get(SettingBoxKey.danmakuFontScaleFS, defaultValue: 1.2);
|
setting.get(SettingBoxKey.danmakuFontScaleFS, defaultValue: 1.2);
|
||||||
|
|
||||||
|
static double get subtitleFontScale =>
|
||||||
|
setting.get(SettingBoxKey.subtitleFontScale, defaultValue: 1.0);
|
||||||
|
|
||||||
|
static double get subtitleFontScaleFS =>
|
||||||
|
setting.get(SettingBoxKey.subtitleFontScaleFS, defaultValue: 1.5);
|
||||||
|
|
||||||
static bool get grpcReply =>
|
static bool get grpcReply =>
|
||||||
setting.get(SettingBoxKey.grpcReply, defaultValue: true);
|
setting.get(SettingBoxKey.grpcReply, defaultValue: true);
|
||||||
|
|
||||||
@@ -302,6 +308,8 @@ class SettingBoxKey {
|
|||||||
strokeWidth = 'strokeWidth',
|
strokeWidth = 'strokeWidth',
|
||||||
fontWeight = 'fontWeight',
|
fontWeight = 'fontWeight',
|
||||||
memberTab = 'memberTab',
|
memberTab = 'memberTab',
|
||||||
|
subtitleFontScale = 'subtitleFontScale',
|
||||||
|
subtitleFontScaleFS = 'subtitleFontScaleFS',
|
||||||
|
|
||||||
// 代理host port
|
// 代理host port
|
||||||
systemProxyHost = 'systemProxyHost',
|
systemProxyHost = 'systemProxyHost',
|
||||||
|
|||||||
Reference in New Issue
Block a user