mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: 字幕展示逻辑
This commit is contained in:
23
lib/models/video/play/subtitle.dart
Normal file
23
lib/models/video/play/subtitle.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
enum SubtitlePreference { off, on, withoutAi }
|
||||||
|
|
||||||
|
extension SubtitlePreferenceDesc on SubtitlePreference {
|
||||||
|
static final List<String> _descList = [
|
||||||
|
'默认不显示字幕',
|
||||||
|
'选择第一个可用字幕',
|
||||||
|
'跳过自动生成(ai)字幕,选择第一个可用字幕'
|
||||||
|
];
|
||||||
|
get description => _descList[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SubtitlePreferenceCode on SubtitlePreference {
|
||||||
|
static final List<String> _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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import 'package:PiliPalaX/plugin/pl_player/index.dart';
|
|||||||
import 'package:PiliPalaX/services/service_locator.dart';
|
import 'package:PiliPalaX/services/service_locator.dart';
|
||||||
import 'package:PiliPalaX/utils/storage.dart';
|
import 'package:PiliPalaX/utils/storage.dart';
|
||||||
|
|
||||||
|
import '../../models/video/play/subtitle.dart';
|
||||||
import 'widgets/switch_item.dart';
|
import 'widgets/switch_item.dart';
|
||||||
|
|
||||||
class PlaySetting extends StatefulWidget {
|
class PlaySetting extends StatefulWidget {
|
||||||
@@ -23,6 +24,7 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
late dynamic defaultVideoQa;
|
late dynamic defaultVideoQa;
|
||||||
late dynamic defaultAudioQa;
|
late dynamic defaultAudioQa;
|
||||||
late dynamic defaultDecode;
|
late dynamic defaultDecode;
|
||||||
|
late String defaultSubtitlePreference;
|
||||||
late int defaultFullScreenMode;
|
late int defaultFullScreenMode;
|
||||||
late int defaultBtmProgressBehavior;
|
late int defaultBtmProgressBehavior;
|
||||||
|
|
||||||
@@ -39,6 +41,8 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
defaultValue: FullScreenMode.values.first.code);
|
defaultValue: FullScreenMode.values.first.code);
|
||||||
defaultBtmProgressBehavior = setting.get(SettingBoxKey.btmProgressBehavior,
|
defaultBtmProgressBehavior = setting.get(SettingBoxKey.btmProgressBehavior,
|
||||||
defaultValue: BtmProgresBehavior.values.first.code);
|
defaultValue: BtmProgresBehavior.values.first.code);
|
||||||
|
defaultSubtitlePreference = setting.get(SettingBoxKey.subtitlePreference,
|
||||||
|
defaultValue: SubtitlePreference.values.first.code);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -91,6 +95,33 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
setKey: SettingBoxKey.enableQuickDouble,
|
setKey: SettingBoxKey.enableQuickDouble,
|
||||||
defaultVal: true,
|
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<String>(
|
||||||
|
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(
|
const SetSwitchItem(
|
||||||
title: '自动全屏',
|
title: '自动全屏',
|
||||||
subTitle: '视频开始播放时进入全屏',
|
subTitle: '视频开始播放时进入全屏',
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import 'package:PiliPalaX/utils/feed_back.dart';
|
|||||||
import 'package:PiliPalaX/utils/storage.dart';
|
import 'package:PiliPalaX/utils/storage.dart';
|
||||||
import 'package:screen_brightness/screen_brightness.dart';
|
import 'package:screen_brightness/screen_brightness.dart';
|
||||||
import 'package:universal_platform/universal_platform.dart';
|
import 'package:universal_platform/universal_platform.dart';
|
||||||
|
|
||||||
|
import '../../models/video/play/subtitle.dart';
|
||||||
// import 'package:wakelock_plus/wakelock_plus.dart';
|
// import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
|
|
||||||
Box videoStorage = GStrorage.video;
|
Box videoStorage = GStrorage.video;
|
||||||
@@ -379,9 +381,6 @@ class PlPlayerController {
|
|||||||
// 获取视频时长 00:00
|
// 获取视频时长 00:00
|
||||||
_duration.value = duration ?? _videoPlayerController!.state.duration;
|
_duration.value = duration ?? _videoPlayerController!.state.duration;
|
||||||
updateDurationSecond();
|
updateDurationSecond();
|
||||||
if (videoType.value != 'live') {
|
|
||||||
refreshSubtitles();
|
|
||||||
}
|
|
||||||
// 数据加载完成
|
// 数据加载完成
|
||||||
dataStatus.status.value = DataStatus.loaded;
|
dataStatus.status.value = DataStatus.loaded;
|
||||||
|
|
||||||
@@ -390,6 +389,25 @@ class PlPlayerController {
|
|||||||
startListeners();
|
startListeners();
|
||||||
}
|
}
|
||||||
await _initializePlayer(seekTo: seekTo, duration: _duration.value);
|
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 =
|
bool autoEnterFullcreen =
|
||||||
setting.get(SettingBoxKey.enableAutoEnter, defaultValue: false);
|
setting.get(SettingBoxKey.enableAutoEnter, defaultValue: false);
|
||||||
if (autoEnterFullcreen && _isFirstTime) {
|
if (autoEnterFullcreen && _isFirstTime) {
|
||||||
@@ -1095,7 +1113,7 @@ class PlPlayerController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshSubtitles() async {
|
Future refreshSubtitles() async {
|
||||||
_vttSubtitles.clear();
|
_vttSubtitles.clear();
|
||||||
Map res = await VideoHttp.subtitlesJson(bvid: _bvid, cid: _cid);
|
Map res = await VideoHttp.subtitlesJson(bvid: _bvid, cid: _cid);
|
||||||
if (!res["status"]) {
|
if (!res["status"]) {
|
||||||
@@ -1105,10 +1123,10 @@ class PlPlayerController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_vttSubtitles.value = await VideoHttp.vttSubtitles(res["data"]);
|
_vttSubtitles.value = await VideoHttp.vttSubtitles(res["data"]);
|
||||||
if (_vttSubtitles.isEmpty) {
|
// if (_vttSubtitles.isEmpty) {
|
||||||
// SmartDialog.showToast('字幕均加载失败');
|
// SmartDialog.showToast('字幕均加载失败');
|
||||||
return;
|
// }
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设定字幕轨道
|
// 设定字幕轨道
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ class SettingBoxKey {
|
|||||||
enableCDN = 'enableCDN',
|
enableCDN = 'enableCDN',
|
||||||
autoPiP = 'autoPiP',
|
autoPiP = 'autoPiP',
|
||||||
enableAutoLongPressSpeed = 'enableAutoLongPressSpeed',
|
enableAutoLongPressSpeed = 'enableAutoLongPressSpeed',
|
||||||
|
subtitlePreference = 'subtitlePreference',
|
||||||
|
|
||||||
// youtube 双击快进快退
|
// youtube 双击快进快退
|
||||||
enableQuickDouble = 'enableQuickDouble',
|
enableQuickDouble = 'enableQuickDouble',
|
||||||
|
|||||||
Reference in New Issue
Block a user