From 6e425b01d299e7e8fa9b129dfef0127c17af7a70 Mon Sep 17 00:00:00 2001 From: orz12 Date: Sat, 2 Mar 2024 12:52:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AD=97=E5=B9=95=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/models/video/play/subtitle.dart | 23 +++++++++++++++++++ lib/pages/setting/play_setting.dart | 31 +++++++++++++++++++++++++ lib/plugin/pl_player/controller.dart | 34 +++++++++++++++++++++------- lib/utils/storage.dart | 1 + 4 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 lib/models/video/play/subtitle.dart diff --git a/lib/models/video/play/subtitle.dart b/lib/models/video/play/subtitle.dart new file mode 100644 index 00000000..0c92b544 --- /dev/null +++ b/lib/models/video/play/subtitle.dart @@ -0,0 +1,23 @@ +enum SubtitlePreference { off, on, withoutAi } + +extension SubtitlePreferenceDesc on SubtitlePreference { + static final List _descList = [ + '默认不显示字幕', + '选择第一个可用字幕', + '跳过自动生成(ai)字幕,选择第一个可用字幕' + ]; + get description => _descList[index]; +} + +extension SubtitlePreferenceCode on SubtitlePreference { + static final List _codeList = ['off', 'on', 'withoutAi']; + get code => _codeList[index]; + + static SubtitlePreference? fromCode(String code) { + final index = _codeList.indexOf(code); + if (index != -1) { + return SubtitlePreference.values[index]; + } + return null; + } +} diff --git a/lib/pages/setting/play_setting.dart b/lib/pages/setting/play_setting.dart index f54e4dc6..1af808c7 100644 --- a/lib/pages/setting/play_setting.dart +++ b/lib/pages/setting/play_setting.dart @@ -9,6 +9,7 @@ import 'package:PiliPalaX/plugin/pl_player/index.dart'; import 'package:PiliPalaX/services/service_locator.dart'; import 'package:PiliPalaX/utils/storage.dart'; +import '../../models/video/play/subtitle.dart'; import 'widgets/switch_item.dart'; class PlaySetting extends StatefulWidget { @@ -23,6 +24,7 @@ class _PlaySettingState extends State { late dynamic defaultVideoQa; late dynamic defaultAudioQa; late dynamic defaultDecode; + late String defaultSubtitlePreference; late int defaultFullScreenMode; late int defaultBtmProgressBehavior; @@ -39,6 +41,8 @@ class _PlaySettingState extends State { defaultValue: FullScreenMode.values.first.code); defaultBtmProgressBehavior = setting.get(SettingBoxKey.btmProgressBehavior, defaultValue: BtmProgresBehavior.values.first.code); + defaultSubtitlePreference = setting.get(SettingBoxKey.subtitlePreference, + defaultValue: SubtitlePreference.values.first.code); } @override @@ -91,6 +95,33 @@ class _PlaySettingState extends State { setKey: SettingBoxKey.enableQuickDouble, defaultVal: true, ), + ListTile( + dense: false, + title: Text('自动启用字幕', style: titleStyle), + subtitle: Text( + '当前选择偏好:' + '${SubtitlePreferenceCode.fromCode(defaultSubtitlePreference)!.description}', + style: subTitleStyle), + onTap: () async { + String? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog( + title: '字幕选择偏好', + value: setting.get(SettingBoxKey.subtitlePreference, + defaultValue: SubtitlePreference.values.first.code), + values: SubtitlePreference.values.map((e) { + return {'title': e.description, 'value': e.code}; + }).toList()); + }, + ); + if (result != null) { + setting.put(SettingBoxKey.subtitlePreference, result); + defaultSubtitlePreference = result; + setState(() {}); + } + }, + ), const SetSwitchItem( title: '自动全屏', subTitle: '视频开始播放时进入全屏', diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index cc263661..22324f2b 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -22,6 +22,8 @@ import 'package:PiliPalaX/utils/feed_back.dart'; import 'package:PiliPalaX/utils/storage.dart'; import 'package:screen_brightness/screen_brightness.dart'; import 'package:universal_platform/universal_platform.dart'; + +import '../../models/video/play/subtitle.dart'; // import 'package:wakelock_plus/wakelock_plus.dart'; Box videoStorage = GStrorage.video; @@ -379,9 +381,6 @@ class PlPlayerController { // 获取视频时长 00:00 _duration.value = duration ?? _videoPlayerController!.state.duration; updateDurationSecond(); - if (videoType.value != 'live') { - refreshSubtitles(); - } // 数据加载完成 dataStatus.status.value = DataStatus.loaded; @@ -390,6 +389,25 @@ class PlPlayerController { startListeners(); } await _initializePlayer(seekTo: seekTo, duration: _duration.value); + if (videoType.value != 'live') { + refreshSubtitles().then((value) { + if (_vttSubtitles.isNotEmpty){ + String preference = setting.get(SettingBoxKey.subtitlePreference, + defaultValue: SubtitlePreference.values.first.index); + if (preference == 'on') { + setSubtitle(vttSubtitles[1]); + } else if (preference == 'withoutAi') { + for (int i = 1; i < _vttSubtitles.length; i++) { + if (_vttSubtitles[i]['language']!.startsWith('ai')) { + continue; + } + setSubtitle(vttSubtitles[i]); + break; + } + } + } + }); + } bool autoEnterFullcreen = setting.get(SettingBoxKey.enableAutoEnter, defaultValue: false); if (autoEnterFullcreen && _isFirstTime) { @@ -1095,7 +1113,7 @@ class PlPlayerController { } } - void refreshSubtitles() async { + Future refreshSubtitles() async { _vttSubtitles.clear(); Map res = await VideoHttp.subtitlesJson(bvid: _bvid, cid: _cid); if (!res["status"]) { @@ -1105,10 +1123,10 @@ class PlPlayerController { return; } _vttSubtitles.value = await VideoHttp.vttSubtitles(res["data"]); - if (_vttSubtitles.isEmpty) { - // SmartDialog.showToast('字幕均加载失败'); - return; - } + // if (_vttSubtitles.isEmpty) { + // SmartDialog.showToast('字幕均加载失败'); + // } + return; } // 设定字幕轨道 diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index cb2d1018..3be46e2f 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -95,6 +95,7 @@ class SettingBoxKey { enableCDN = 'enableCDN', autoPiP = 'autoPiP', enableAutoLongPressSpeed = 'enableAutoLongPressSpeed', + subtitlePreference = 'subtitlePreference', // youtube 双击快进快退 enableQuickDouble = 'enableQuickDouble',