diff --git a/lib/pages/setting/pages/play_speed_set.dart b/lib/pages/setting/pages/play_speed_set.dart new file mode 100644 index 00000000..c5eb70e6 --- /dev/null +++ b/lib/pages/setting/pages/play_speed_set.dart @@ -0,0 +1,304 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:hive/hive.dart'; +import 'package:pilipala/plugin/pl_player/models/play_speed.dart'; +import 'package:pilipala/utils/storage.dart'; + +class PlaySpeedPage extends StatefulWidget { + const PlaySpeedPage({super.key}); + + @override + State createState() => _PlaySpeedPageState(); +} + +class _PlaySpeedPageState extends State { + Box videoStorage = GStrorage.video; + late double playSpeedDefault; + late double longPressSpeedDefault; + late List customSpeedsList; + List> sheetMenu = [ + { + 'id': 1, + 'title': '设置为默认倍速', + 'leading': const Icon( + Icons.speed, + size: 21, + ), + }, + { + 'id': 2, + 'title': '设置为默认长按倍速', + 'leading': const Icon( + Icons.speed_sharp, + size: 21, + ), + }, + { + 'id': -1, + 'title': '删除该项', + 'leading': const Icon( + Icons.delete_outline, + size: 21, + ), + }, + ]; + + @override + void initState() { + super.initState(); + // 默认倍速 + playSpeedDefault = + videoStorage.get(VideoBoxKey.playSpeedDefault, defaultValue: 1.0); + // 默认长按倍速 + longPressSpeedDefault = + videoStorage.get(VideoBoxKey.longPressSpeedDefault, defaultValue: 2.0); + // 自定义倍速 + customSpeedsList = + videoStorage.get(VideoBoxKey.customSpeedsList, defaultValue: []); + } + + // 添加自定义倍速 + void onAddSpeed() { + double customSpeed = 1.0; + SmartDialog.show( + useSystem: true, + animationType: SmartAnimationType.centerFade_otherSlide, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('添加倍速'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // const Text('输入你想要的视频倍速,例如:1.0'), + const SizedBox(height: 12), + TextField( + keyboardType: TextInputType.number, + decoration: InputDecoration( + labelText: '自定义倍速', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(6.0), + ), + ), + onChanged: (e) { + customSpeed = double.parse(e); + }, + ), + ], + ), + actions: [ + TextButton( + onPressed: () => SmartDialog.dismiss(), + child: const Text('取消'), + ), + TextButton( + onPressed: () async { + customSpeedsList.add(customSpeed); + await videoStorage.put( + VideoBoxKey.customSpeedsList, customSpeedsList); + setState(() {}); + SmartDialog.dismiss(); + }, + child: const Text('确认添加'), + ) + ], + ); + }, + ); + } + + // 设定倍速弹窗 + void showBottomSheet(type, i) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (BuildContext context) { + return Container( + padding: const EdgeInsets.only(top: 10), + child: ListView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + //重要 + itemCount: sheetMenu.length, + itemBuilder: (BuildContext context, int index) { + return ListTile( + onTap: () { + Navigator.pop(context); + menuAction(type, i, sheetMenu[index]['id']); + }, + minLeadingWidth: 0, + iconColor: Theme.of(context).colorScheme.onSurface, + leading: sheetMenu[index]['leading'], + title: Text( + sheetMenu[index]['title'], + style: Theme.of(context).textTheme.titleSmall, + ), + ); + }, + ), + ); + }, + ); + } + + // + void menuAction(type, index, id) async { + double chooseSpeed = 1.0; + if (type == 'system' && id == -1) { + SmartDialog.showToast('系统预设倍速不支持删除'); + return; + } + // 获取当前选中的倍速值 + if (type == 'system') { + chooseSpeed = PlaySpeed.values[index].value; + } else { + chooseSpeed = customSpeedsList[index]; + } + // 设置 + if (id == 1) { + // 设置默认倍速 + playSpeedDefault = chooseSpeed; + videoStorage.put(VideoBoxKey.playSpeedDefault, playSpeedDefault); + } else if (id == 2) { + // 设置默认长按倍速 + longPressSpeedDefault = chooseSpeed; + videoStorage.put( + VideoBoxKey.longPressSpeedDefault, longPressSpeedDefault); + } else if (id == -1) { + if (customSpeedsList[index] == playSpeedDefault) { + playSpeedDefault = 1.0; + videoStorage.put(VideoBoxKey.playSpeedDefault, playSpeedDefault); + } + if (customSpeedsList[index] == longPressSpeedDefault) { + longPressSpeedDefault = 2.0; + videoStorage.put( + VideoBoxKey.longPressSpeedDefault, longPressSpeedDefault); + } + customSpeedsList.removeAt(index); + await videoStorage.put(VideoBoxKey.customSpeedsList, customSpeedsList); + } + setState(() {}); + SmartDialog.showToast('操作成功'); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + elevation: 0, + scrolledUnderElevation: 0, + titleSpacing: 0, + centerTitle: false, + title: Text( + '倍速设置', + style: Theme.of(context).textTheme.titleMedium, + ), + ), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: + const EdgeInsets.only(left: 14, right: 14, top: 6, bottom: 0), + child: Text( + '点击下方按钮设置默认(长按)倍速', + style: TextStyle(color: Theme.of(context).colorScheme.outline), + ), + ), + ListTile( + dense: false, + title: const Text('默认倍速'), + subtitle: Text(playSpeedDefault.toString()), + ), + ListTile( + dense: false, + title: const Text('默认长按倍速'), + subtitle: Text(longPressSpeedDefault.toString()), + ), + Padding( + padding: const EdgeInsets.only( + left: 14, + right: 14, + bottom: 10, + top: 20, + ), + child: Text( + '系统预设倍速', + style: Theme.of(context).textTheme.titleMedium, + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 18, + right: 18, + bottom: 30, + ), + child: Wrap( + alignment: WrapAlignment.start, + spacing: 8, + runSpacing: 2, + children: [ + for (var i in PlaySpeed.values) ...[ + FilledButton.tonal( + onPressed: () => showBottomSheet('system', i.index), + child: Text(i.description), + ), + ] + ], + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 14, + right: 14, + ), + child: Row( + children: [ + Text( + '自定义倍速', + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(width: 12), + TextButton( + onPressed: () => onAddSpeed(), + child: const Text('添加'), + ) + ], + )), + Padding( + padding: EdgeInsets.only( + left: 18, + right: 18, + bottom: MediaQuery.of(context).padding.bottom + 40, + ), + child: customSpeedsList.isNotEmpty + ? Wrap( + alignment: WrapAlignment.start, + spacing: 8, + runSpacing: 2, + children: [ + for (int i = 0; i < customSpeedsList.length; i++) ...[ + FilledButton.tonal( + onPressed: () => showBottomSheet('custom', i), + child: Text(customSpeedsList[i].toString()), + ), + ] + ], + ) + : SizedBox( + height: 80, + child: Center( + child: Text( + '未添加', + style: TextStyle( + color: Theme.of(context).colorScheme.outline), + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/setting/play_setting.dart b/lib/pages/setting/play_setting.dart index a51bc22a..cc3f3b88 100644 --- a/lib/pages/setting/play_setting.dart +++ b/lib/pages/setting/play_setting.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/models/video/play/quality.dart'; import 'package:pilipala/plugin/pl_player/index.dart'; @@ -54,6 +55,12 @@ class _PlaySettingState extends State { ), body: ListView( children: [ + ListTile( + dense: false, + onTap: () => Get.toNamed('/playSpeedSet'), + title: Text('倍速设置', style: titleStyle), + trailing: const Icon(Icons.arrow_forward_ios, size: 17), + ), const SetSwitchItem( title: '开启1080P', subTitle: '免登录查看1080P视频', diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index bc525fa3..cbf08162 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -215,8 +215,6 @@ class VideoDetailController extends GetxController direction: (firstVideo.width! - firstVideo.height!) > 0 ? 'horizontal' : 'vertical', - // 默认1倍速 - speed: 1.0, bvid: bvid, cid: cid.value, enableHeart: enableHeart, diff --git a/lib/pages/video/detail/widgets/header_control.dart b/lib/pages/video/detail/widgets/header_control.dart index a0ca8601..e1e94bd9 100644 --- a/lib/pages/video/detail/widgets/header_control.dart +++ b/lib/pages/video/detail/widgets/header_control.dart @@ -41,11 +41,14 @@ class _HeaderControlState extends State { TextStyle titleStyle = const TextStyle(fontSize: 14); Size get preferredSize => const Size(double.infinity, kToolbarHeight); Box localCache = GStrorage.localCache; + Box videoStorage = GStrorage.video; + late List speedsList; @override void initState() { super.initState(); videoInfo = widget.videoDetailCtr!.data; + speedsList = widget.controller!.speedsList; } /// 设置面板 @@ -184,21 +187,25 @@ class _HeaderControlState extends State { builder: (context) { return AlertDialog( title: const Text('播放速度'), - contentPadding: const EdgeInsets.fromLTRB(0, 20, 0, 20), content: StatefulBuilder(builder: (context, StateSetter setState) { - return Column( - mainAxisSize: MainAxisSize.min, + return Wrap( + alignment: WrapAlignment.start, + spacing: 8, + runSpacing: 2, children: [ - Text('$currentSpeed倍'), - Slider( - min: PlaySpeed.values.first.value, - max: PlaySpeed.values.last.value, - value: currentSpeed, - divisions: PlaySpeed.values.length - 1, - label: '${currentSpeed}x', - onChanged: (double val) => - {setState(() => currentSpeed = val)}, - ) + for (var i in speedsList) ...[ + if (i == currentSpeed) ...[ + FilledButton( + onPressed: () => {setState(() => currentSpeed = i)}, + child: Text(i.toString()), + ), + ] else ...[ + FilledButton.tonal( + onPressed: () => {setState(() => currentSpeed = i)}, + child: Text(i.toString()), + ), + ] + ] ], ); }), diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 9b3a4445..df1d9eae 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -55,6 +55,7 @@ class PlPlayerController { final Rx _playerCount = Rx(0); final Rx _playbackSpeed = 1.0.obs; + final Rx _longPressSpeed = 2.0.obs; final Rx _currentVolume = 1.0.obs; final Rx _currentBrightness = 0.0.obs; @@ -127,6 +128,9 @@ class PlPlayerController { /// 视频播放速度 double get playbackSpeed => _playbackSpeed.value; + // 长按倍速 + double get longPressSpeed => _longPressSpeed.value; + /// 视频缓冲 Rx get buffered => _buffered; Stream get onBufferedChanged => _buffered.stream; @@ -209,6 +213,7 @@ class PlPlayerController { late double opacityVal; late double fontSizeVal; late double danmakuSpeedVal; + late List speedsList; // 播放顺序相关 PlayRepeat playRepeat = PlayRepeat.pause; @@ -236,6 +241,17 @@ class PlPlayerController { videoStorage.get(VideoBoxKey.playRepeat, defaultValue: PlayRepeat.pause.value), ); + _playbackSpeed.value = + videoStorage.get(VideoBoxKey.playSpeedDefault, defaultValue: 1.0); + _longPressSpeed.value = + videoStorage.get(VideoBoxKey.longPressSpeedDefault, defaultValue: 2.0); + List speedsListTemp = + videoStorage.get(VideoBoxKey.customSpeedsList, defaultValue: []); + speedsList = List.from(speedsListTemp); + for (var i in PlaySpeed.values) { + speedsList.add(i.value); + } + // _playerEventSubs = onPlayerStatusChanged.listen((PlayerStatus status) { // if (status == PlayerStatus.playing) { // WakelockPlus.enable(); @@ -293,7 +309,7 @@ class PlPlayerController { _autoPlay = autoplay; _looping = looping; // 初始化视频倍速 - _playbackSpeed.value = speed; + // _playbackSpeed.value = speed; // 初始化数据加载状态 dataStatus.status.value = DataStatus.loading; // 初始化全屏方向 @@ -774,11 +790,10 @@ class PlPlayerController { return; } _doubleSpeedStatus.value = val; - double currentSpeed = playbackSpeed; if (val) { - setPlaybackSpeed(currentSpeed * 2); + setPlaybackSpeed(longPressSpeed); } else { - setPlaybackSpeed(currentSpeed / 2); + setPlaybackSpeed(playbackSpeed); } } diff --git a/lib/plugin/pl_player/models/play_speed.dart b/lib/plugin/pl_player/models/play_speed.dart index 5ccb91a4..533e0254 100644 --- a/lib/plugin/pl_player/models/play_speed.dart +++ b/lib/plugin/pl_player/models/play_speed.dart @@ -9,35 +9,18 @@ enum PlaySpeed { onePointSevenFive, two, - twoPointTwoFive, - twoPointFive, - twoPointSevenFive, - - twhree, - threePointTwoFive, - threePointFive, - threePointSevenFive, - - four, } extension PlaySpeedExtension on PlaySpeed { static final List _descList = [ - '0.25倍', - '0.5倍', - '0.75倍', - '正常速度', - '1.25倍', - '1.5倍', - '2.0倍', - '2.25倍', - '2.5倍', - '2.75倍', - '3.0倍', - '3.25倍', - '3.5倍', - '3.75倍', - '4.0倍' + '0.25', + '0.5', + '0.75', + '正常', + '1.25', + '1.5', + '1.75', + '2.0', ]; get description => _descList[index]; @@ -50,14 +33,6 @@ extension PlaySpeedExtension on PlaySpeed { 1.5, 1.75, 2.0, - 2.25, - 2.5, - 2.75, - 3.0, - 3.25, - 3.5, - 3.75, - 4.0, ]; get value => _valueList[index]; get defaultValue => _valueList[3]; diff --git a/lib/router/app_pages.dart b/lib/router/app_pages.dart index 536eba89..7b701b92 100644 --- a/lib/router/app_pages.dart +++ b/lib/router/app_pages.dart @@ -27,6 +27,7 @@ import 'package:pilipala/pages/setting/extra_setting.dart'; import 'package:pilipala/pages/setting/pages/color_select.dart'; import 'package:pilipala/pages/setting/pages/display_mode.dart'; import 'package:pilipala/pages/setting/pages/font_size_select.dart'; +import 'package:pilipala/pages/setting/pages/play_speed_set.dart'; import 'package:pilipala/pages/setting/play_setting.dart'; import 'package:pilipala/pages/setting/privacy_setting.dart'; import 'package:pilipala/pages/setting/style_setting.dart'; @@ -116,6 +117,8 @@ class Routes { // 历史记录搜索 CustomGetPage( name: '/historySearch', page: () => const HistorySearchPage()), + + CustomGetPage(name: '/playSpeedSet', page: () => const PlaySpeedPage()), ]; } diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index 2f48a156..8d31726c 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -163,4 +163,10 @@ class VideoBoxKey { static const String videoSpeed = 'videoSpeed'; // 播放顺序 static const String playRepeat = 'playRepeat'; + // 默认倍速 + static const String playSpeedDefault = 'playSpeedDefault'; + // 默认长按倍速 + static const String longPressSpeedDefault = 'longPressSpeedDefault'; + // 自定义倍速集合 + static const String customSpeedsList = 'customSpeedsList'; }