opt ua

opt subtitle

opt playertype

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-07-26 18:41:11 +08:00
parent a05ecd020b
commit 3a78ead3a6
28 changed files with 218 additions and 221 deletions

View File

@@ -290,15 +290,6 @@ class Request {
token.cancel("cancelled"); token.cancel("cancelled");
} }
static String headerUa({String type = 'mob'}) {
return switch (type) {
'mob' =>
'Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Mobile Safari/537.36',
_ =>
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15',
};
}
static String responseDecoder( static String responseDecoder(
List<int> responseBytes, List<int> responseBytes,
RequestOptions options, RequestOptions options,

View File

@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/http/api.dart'; import 'package:PiliPlus/http/api.dart';
import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/ua_type.dart';
import 'package:PiliPlus/models/common/live_search_type.dart'; import 'package:PiliPlus/models/common/live_search_type.dart';
import 'package:PiliPlus/models_new/live/live_area_list/area_item.dart'; import 'package:PiliPlus/models_new/live/live_area_list/area_item.dart';
import 'package:PiliPlus/models_new/live/live_area_list/area_list.dart'; import 'package:PiliPlus/models_new/live/live_area_list/area_list.dart';
@@ -114,7 +115,7 @@ class LiveHttp {
options: Options( options: Options(
headers: { headers: {
'referer': 'https://live.bilibili.com/$roomId', 'referer': 'https://live.bilibili.com/$roomId',
'user-agent': Request.headerUa(type: 'pc'), 'user-agent': UaType.pc.ua,
}, },
), ),
); );

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/http/api.dart';
import 'package:PiliPlus/http/constants.dart'; import 'package:PiliPlus/http/constants.dart';
import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/ua_type.dart';
import 'package:PiliPlus/models/common/member/contribute_type.dart'; import 'package:PiliPlus/models/common/member/contribute_type.dart';
import 'package:PiliPlus/models/dynamics/result.dart'; import 'package:PiliPlus/models/dynamics/result.dart';
import 'package:PiliPlus/models/member/info.dart'; import 'package:PiliPlus/models/member/info.dart';
@@ -280,7 +281,7 @@ class MemberHttp {
headers: { headers: {
'origin': 'https://space.bilibili.com', 'origin': 'https://space.bilibili.com',
'referer': 'https://space.bilibili.com/$mid/dynamic', 'referer': 'https://space.bilibili.com/$mid/dynamic',
'user-agent': Request.headerUa(type: 'pc'), 'user-agent': UaType.pc.ua,
}, },
), ),
); );
@@ -352,7 +353,7 @@ class MemberHttp {
queryParameters: params, queryParameters: params,
options: Options( options: Options(
headers: { headers: {
HttpHeaders.userAgentHeader: Request.headerUa(type: 'pc'), HttpHeaders.userAgentHeader: UaType.pc.ua,
HttpHeaders.refererHeader: '${HttpString.spaceBaseUrl}/$mid', HttpHeaders.refererHeader: '${HttpString.spaceBaseUrl}/$mid',
'origin': HttpString.spaceBaseUrl, 'origin': HttpString.spaceBaseUrl,
}, },

11
lib/http/ua_type.dart Normal file
View File

@@ -0,0 +1,11 @@
enum UaType {
mob(
'Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Mobile Safari/537.36',
),
pc(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15',
);
final String ua;
const UaType(this.ua);
}

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/http/api.dart';
import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/login.dart'; import 'package:PiliPlus/http/login.dart';
import 'package:PiliPlus/http/ua_type.dart';
import 'package:PiliPlus/models/common/account_type.dart'; import 'package:PiliPlus/models/common/account_type.dart';
import 'package:PiliPlus/models/home/rcmd/result.dart'; import 'package:PiliPlus/models/home/rcmd/result.dart';
import 'package:PiliPlus/models/model_hot_video_item.dart'; import 'package:PiliPlus/models/model_hot_video_item.dart';
@@ -367,7 +368,7 @@ class VideoHttp {
headers: { headers: {
'origin': 'https://www.bilibili.com', 'origin': 'https://www.bilibili.com',
'referer': 'https://www.bilibili.com/bangumi/play/ss$seasonId', 'referer': 'https://www.bilibili.com/bangumi/play/ss$seasonId',
'user-agent': Request.headerUa(type: 'pc'), 'user-agent': UaType.pc.ua,
}, },
), ),
); );
@@ -395,7 +396,7 @@ class VideoHttp {
headers: { headers: {
'origin': 'https://www.bilibili.com', 'origin': 'https://www.bilibili.com',
'referer': 'https://www.bilibili.com/video/$bvid', 'referer': 'https://www.bilibili.com/video/$bvid',
'user-agent': Request.headerUa(type: 'pc'), 'user-agent': UaType.pc.ua,
}, },
), ),
); );
@@ -593,7 +594,7 @@ class VideoHttp {
'extend_content': jsonEncode({ 'extend_content': jsonEncode({
"entity": "user", "entity": "user",
"entity_id": mid, "entity_id": mid,
'fp': Request.headerUa(type: 'pc'), 'fp': UaType.pc.ua,
}), }),
'csrf': Accounts.main.csrf, 'csrf': Accounts.main.csrf,
}, },
@@ -602,7 +603,7 @@ class VideoHttp {
headers: { headers: {
'origin': 'https://space.bilibili.com', 'origin': 'https://space.bilibili.com',
'referer': 'https://space.bilibili.com/$mid/dynamic', 'referer': 'https://space.bilibili.com/$mid/dynamic',
'user-agent': Request.headerUa(type: 'pc'), 'user-agent': UaType.pc.ua,
}, },
), ),
); );

View File

@@ -0,0 +1,13 @@
enum SettingType {
privacySetting('隐私设置'),
recommendSetting('推荐流设置'),
videoSetting('音视频设置'),
playSetting('播放器设置'),
styleSetting('外观设置'),
extraSetting('其它设置'),
webdavSetting('WebDAV 设置'),
about('关于');
final String title;
const SettingType(this.title);
}

View File

@@ -1,21 +1,9 @@
enum SubtitlePrefType { off, on, withoutAi, auto } enum SubtitlePrefType {
off('默认不显示字幕'),
on('优先选择非自动生成(ai)字幕'),
withoutAi('跳过自动生成(ai)字幕,选择第一个可用字幕'),
auto('静音时等同第二项,非静音时等同第三项');
extension SubtitlePrefTypeExt on SubtitlePrefType { final String desc;
String get description => const [ const SubtitlePrefType(this.desc);
'默认不显示字幕',
'优先选择非自动生成(ai)字幕',
'跳过自动生成(ai)字幕,选择第一个可用字幕',
'静音时等同第二项,非静音时等同第三项',
][index];
static const List<String> _codeList = ['off', 'on', 'withoutAi', 'auto'];
String get code => _codeList[index];
static SubtitlePrefType? fromCode(String code) {
final index = _codeList.indexOf(code);
if (index != -1) {
return SubtitlePrefType.values[index];
}
return null;
}
} }

View File

@@ -31,7 +31,7 @@ abstract class CommonIntroController extends GetxController {
Future queryVideoInFolder(); Future queryVideoInFolder();
Future<void> actionFavVideo({String type = 'choose'}); Future<void> actionFavVideo({bool isQuick = false});
late final enableQuickFav = Pref.enableQuickFav; late final enableQuickFav = Pref.enableQuickFav;
int? quickFavId; int? quickFavId;
@@ -54,7 +54,7 @@ abstract class CommonIntroController extends GetxController {
} }
// 收藏 // 收藏
void showFavBottomSheet(BuildContext context, {type = 'tap'}) { void showFavBottomSheet(BuildContext context, {bool isLongPress = false}) {
if (!accountService.isLogin.value) { if (!accountService.isLogin.value) {
SmartDialog.showToast('账号未登录'); SmartDialog.showToast('账号未登录');
return; return;
@@ -63,12 +63,12 @@ abstract class CommonIntroController extends GetxController {
// 点按 收藏至默认文件夹 // 点按 收藏至默认文件夹
// 长按选择文件夹 // 长按选择文件夹
if (enableQuickFav) { if (enableQuickFav) {
if (type == 'tap') { if (!isLongPress) {
actionFavVideo(type: 'default'); actionFavVideo(isQuick: true);
} else { } else {
PageUtils.showFavBottomSheet(context: context, ctr: this); PageUtils.showFavBottomSheet(context: context, ctr: this);
} }
} else if (type != 'longPress') { } else if (!isLongPress) {
PageUtils.showFavBottomSheet(context: context, ctr: this); PageUtils.showFavBottomSheet(context: context, ctr: this);
} }
} }

View File

@@ -93,7 +93,7 @@ class DynamicsController extends GetxController
} }
late bool isQuerying = false; late bool isQuerying = false;
Future<void> queryFollowUp({String type = 'init'}) async { Future<void> queryFollowUp() async {
if (isQuerying) return; if (isQuerying) return;
isQuerying = true; isQuerying = true;
if (!accountService.isLogin.value) { if (!accountService.isLogin.value) {

View File

@@ -36,7 +36,7 @@ class LiveRoomController extends GetxController {
// 静音状态 // 静音状态
RxBool volumeOff = false.obs; RxBool volumeOff = false.obs;
PlPlayerController plPlayerController = PlPlayerController.getInstance( PlPlayerController plPlayerController = PlPlayerController.getInstance(
videoType: 'live', isLive: true,
); );
Rx<RoomInfoH5Data?> roomInfoH5 = Rx<RoomInfoH5Data?>(null); Rx<RoomInfoH5Data?> roomInfoH5 = Rx<RoomInfoH5Data?>(null);
@@ -80,7 +80,7 @@ class LiveRoomController extends GetxController {
}, },
), ),
autoplay: true, autoplay: true,
direction: isPortrait.value ? 'vertical' : 'horizontal', isVertical: isPortrait.value,
); );
} }

View File

@@ -143,7 +143,7 @@ class LiveHeaderControl extends StatelessWidget {
if ((await floating.isPipAvailable) == true) { if ((await floating.isPipAvailable) == true) {
plPlayerController.hiddenControls(false); plPlayerController.hiddenControls(false);
floating.enable( floating.enable(
plPlayerController.direction.value == 'vertical' plPlayerController.isVertical
? const EnableManual( ? const EnableManual(
aspectRatio: Rational.vertical(), aspectRatio: Rational.vertical(),
) )

View File

@@ -95,22 +95,22 @@ List<SettingsModel> get playSettings => [
title: '自动启用字幕', title: '自动启用字幕',
leading: const Icon(Icons.closed_caption_outlined), leading: const Icon(Icons.closed_caption_outlined),
getSubtitle: () => getSubtitle: () =>
'当前选择偏好:${SubtitlePrefTypeExt.fromCode(Pref.subtitlePreference)!.description}', '当前选择偏好:${SubtitlePrefType.values[Pref.subtitlePreferenceV2].desc}',
onTap: (setState) async { onTap: (setState) async {
String? result = await showDialog( int? result = await showDialog(
context: Get.context!, context: Get.context!,
builder: (context) { builder: (context) {
return SelectDialog<String>( return SelectDialog<int>(
title: '字幕选择偏好', title: '字幕选择偏好',
value: Pref.subtitlePreference, value: Pref.subtitlePreferenceV2,
values: SubtitlePrefType.values values: SubtitlePrefType.values
.map((e) => (e.code, e.description)) .map((e) => (e.index, e.desc))
.toList(), .toList(),
); );
}, },
); );
if (result != null) { if (result != null) {
await GStorage.setting.put(SettingBoxKey.subtitlePreference, result); await GStorage.setting.put(SettingBoxKey.subtitlePreferenceV2, result);
setState(); setState();
} }
}, },

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/http/login.dart'; import 'package:PiliPlus/http/login.dart';
import 'package:PiliPlus/models/common/setting_type.dart';
import 'package:PiliPlus/pages/about/view.dart'; import 'package:PiliPlus/pages/about/view.dart';
import 'package:PiliPlus/pages/login/controller.dart'; import 'package:PiliPlus/pages/login/controller.dart';
import 'package:PiliPlus/pages/setting/extra_setting.dart'; import 'package:PiliPlus/pages/setting/extra_setting.dart';
@@ -18,14 +19,12 @@ import 'package:get/get.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
class _SettingsModel { class _SettingsModel {
final String name; final SettingType type;
final String title;
final String? subtitle; final String? subtitle;
final IconData icon; final IconData icon;
const _SettingsModel({ const _SettingsModel({
required this.name, required this.type,
required this.title,
this.subtitle, this.subtitle,
required this.icon, required this.icon,
}); });
@@ -39,55 +38,47 @@ class SettingPage extends StatefulWidget {
} }
class _SettingPageState extends State<SettingPage> { class _SettingPageState extends State<SettingPage> {
late String _type = 'privacySetting'; late SettingType _type = SettingType.privacySetting;
final RxBool _noAccount = Accounts.accountMode.isEmpty.obs; final RxBool _noAccount = Accounts.accountMode.isEmpty.obs;
bool get _isPortrait => context.orientation == Orientation.portrait; late bool _isPortrait;
final List<_SettingsModel> _items = [ final List<_SettingsModel> _items = [
const _SettingsModel( const _SettingsModel(
name: 'privacySetting', type: SettingType.privacySetting,
title: '隐私设置',
subtitle: '黑名单、无痕模式', subtitle: '黑名单、无痕模式',
icon: Icons.privacy_tip_outlined, icon: Icons.privacy_tip_outlined,
), ),
const _SettingsModel( const _SettingsModel(
name: 'recommendSetting', type: SettingType.recommendSetting,
title: '推荐流设置',
subtitle: '推荐来源web/app、刷新保留内容、过滤器', subtitle: '推荐来源web/app、刷新保留内容、过滤器',
icon: Icons.explore_outlined, icon: Icons.explore_outlined,
), ),
const _SettingsModel( const _SettingsModel(
name: 'videoSetting', type: SettingType.videoSetting,
title: '音视频设置',
subtitle: '画质、音质、解码、缓冲、音频输出等', subtitle: '画质、音质、解码、缓冲、音频输出等',
icon: Icons.video_settings_outlined, icon: Icons.video_settings_outlined,
), ),
const _SettingsModel( const _SettingsModel(
name: 'playSetting', type: SettingType.playSetting,
title: '播放器设置',
subtitle: '双击/长按、全屏、后台播放、弹幕、字幕、底部进度条等', subtitle: '双击/长按、全屏、后台播放、弹幕、字幕、底部进度条等',
icon: Icons.touch_app_outlined, icon: Icons.touch_app_outlined,
), ),
const _SettingsModel( const _SettingsModel(
name: 'styleSetting', type: SettingType.styleSetting,
title: '外观设置',
subtitle: '横屏适配(平板)、侧栏、列宽、首页、动态红点、主题、字号、图片、帧率等', subtitle: '横屏适配(平板)、侧栏、列宽、首页、动态红点、主题、字号、图片、帧率等',
icon: Icons.style_outlined, icon: Icons.style_outlined,
), ),
const _SettingsModel( const _SettingsModel(
name: 'extraSetting', type: SettingType.extraSetting,
title: '其它设置',
subtitle: '震动、搜索、收藏、ai、评论、动态、代理、更新检查等', subtitle: '震动、搜索、收藏、ai、评论、动态、代理、更新检查等',
icon: Icons.extension_outlined, icon: Icons.extension_outlined,
), ),
const _SettingsModel( const _SettingsModel(
name: 'webdavSetting', type: SettingType.webdavSetting,
title: 'WebDAV 设置',
icon: MdiIcons.databaseCogOutline, icon: MdiIcons.databaseCogOutline,
), ),
const _SettingsModel( const _SettingsModel(
name: 'about', type: SettingType.about,
title: '关于',
icon: Icons.info_outline, icon: Icons.info_outline,
), ),
]; ];
@@ -95,21 +86,10 @@ class _SettingPageState extends State<SettingPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
_isPortrait = context.orientation == Orientation.portrait;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: _isPortrait title: _isPortrait ? const Text('设置') : Text(_type.title),
? const Text('设置')
: Text(switch (_type) {
'privacySetting' => '隐私设置',
'recommendSetting' => '推荐流设置',
'videoSetting' => '音视频设置',
'playSetting' => '播放器设置',
'styleSetting' => '外观设置',
'extraSetting' => '其它设置',
'webdavSetting' => 'WebDAV 设置',
'about' => '关于',
_ => '设置',
}),
), ),
body: _isPortrait body: _isPortrait
? _buildList(theme) ? _buildList(theme)
@@ -136,21 +116,28 @@ class _SettingPageState extends State<SettingPage> {
removeLeft: true, removeLeft: true,
removeTop: true, removeTop: true,
child: switch (_type) { child: switch (_type) {
'privacySetting' => const PrivacySetting( SettingType.privacySetting => const PrivacySetting(
showAppBar: false, showAppBar: false,
), ),
'recommendSetting' => const RecommendSetting( SettingType.recommendSetting => const RecommendSetting(
showAppBar: false, showAppBar: false,
), ),
'videoSetting' => const VideoSetting(showAppBar: false), SettingType.videoSetting => const VideoSetting(
'playSetting' => const PlaySetting(showAppBar: false),
'styleSetting' => const StyleSetting(showAppBar: false),
'extraSetting' => const ExtraSetting(showAppBar: false),
'webdavSetting' => const WebDavSettingPage(
showAppBar: false, showAppBar: false,
), ),
'about' => const AboutPage(showAppBar: false), SettingType.playSetting => const PlaySetting(
_ => const SizedBox.shrink(), showAppBar: false,
),
SettingType.styleSetting => const StyleSetting(
showAppBar: false,
),
SettingType.extraSetting => const ExtraSetting(
showAppBar: false,
),
SettingType.webdavSetting => const WebDavSettingPage(
showAppBar: false,
),
SettingType.about => const AboutPage(showAppBar: false),
}, },
), ),
), ),
@@ -159,20 +146,20 @@ class _SettingPageState extends State<SettingPage> {
); );
} }
void _toPage(String name) { void _toPage(SettingType type) {
if (_isPortrait) { if (_isPortrait) {
Get.toNamed('/$name'); Get.toNamed('/${type.name}');
} else { } else {
_type = name; _type = type;
setState(() {}); setState(() {});
} }
} }
Color? _getTileColor(ThemeData theme, String name) { Color? _getTileColor(ThemeData theme, SettingType type) {
if (_isPortrait) { if (_isPortrait) {
return null; return null;
} else { } else {
return name == _type ? theme.colorScheme.onInverseSurface : null; return type == _type ? theme.colorScheme.onInverseSurface : null;
} }
} }
@@ -188,10 +175,10 @@ class _SettingPageState extends State<SettingPage> {
.sublist(0, _items.length - 1) .sublist(0, _items.length - 1)
.map( .map(
(item) => ListTile( (item) => ListTile(
tileColor: _getTileColor(theme, item.name), tileColor: _getTileColor(theme, item.type),
onTap: () => _toPage(item.name), onTap: () => _toPage(item.type),
leading: Icon(item.icon), leading: Icon(item.icon),
title: Text(item.title, style: titleStyle), title: Text(item.type.title, style: titleStyle),
subtitle: item.subtitle == null subtitle: item.subtitle == null
? null ? null
: Text(item.subtitle!, style: subTitleStyle), : Text(item.subtitle!, style: subTitleStyle),
@@ -212,10 +199,10 @@ class _SettingPageState extends State<SettingPage> {
), ),
), ),
ListTile( ListTile(
tileColor: _getTileColor(theme, _items.last.name), tileColor: _getTileColor(theme, _items.last.type),
onTap: () => _toPage(_items.last.name), onTap: () => _toPage(_items.last.type),
leading: Icon(_items.last.icon), leading: Icon(_items.last.icon),
title: Text(_items.last.title, style: titleStyle), title: Text(_items.last.type.title, style: titleStyle),
), ),
SizedBox(height: MediaQuery.paddingOf(context).bottom + 80), SizedBox(height: MediaQuery.paddingOf(context).bottom + 80),
], ],

View File

@@ -18,6 +18,7 @@ import 'package:PiliPlus/models/common/sponsor_block/segment_model.dart';
import 'package:PiliPlus/models/common/sponsor_block/segment_type.dart'; import 'package:PiliPlus/models/common/sponsor_block/segment_type.dart';
import 'package:PiliPlus/models/common/sponsor_block/skip_type.dart'; import 'package:PiliPlus/models/common/sponsor_block/skip_type.dart';
import 'package:PiliPlus/models/common/video/audio_quality.dart'; import 'package:PiliPlus/models/common/video/audio_quality.dart';
import 'package:PiliPlus/models/common/video/subtitle_pref_type.dart';
import 'package:PiliPlus/models/common/video/video_decode_type.dart'; import 'package:PiliPlus/models/common/video/video_decode_type.dart';
import 'package:PiliPlus/models/common/video/video_quality.dart'; import 'package:PiliPlus/models/common/video/video_quality.dart';
import 'package:PiliPlus/models/video/play/url.dart'; import 'package:PiliPlus/models/video/play/url.dart';
@@ -69,7 +70,7 @@ class VideoDetailController extends GetxController
final heroTag = Get.arguments['heroTag']; final heroTag = Get.arguments['heroTag'];
final RxString cover = ''.obs; final RxString cover = ''.obs;
// 视频类型 默认投稿视频 // 视频类型 默认投稿视频
final videoType = Get.arguments['videoType'] ?? SearchType.video; final SearchType videoType = Get.arguments['videoType'] ?? SearchType.video;
/// tabs相关配置 /// tabs相关配置
late TabController tabCtr; late TabController tabCtr;
@@ -122,7 +123,7 @@ class VideoDetailController extends GetxController
StreamSubscription<Duration>? positionSubscription; StreamSubscription<Duration>? positionSubscription;
late final scrollKey = GlobalKey<ExtendedNestedScrollViewState>(); late final scrollKey = GlobalKey<ExtendedNestedScrollViewState>();
late final RxString direction = 'horizontal'.obs; late final RxBool isVertical = false.obs;
late final RxDouble scrollRatio = 0.0.obs; late final RxDouble scrollRatio = 0.0.obs;
late final ScrollController scrollCtr = ScrollController() late final ScrollController scrollCtr = ScrollController()
..addListener(scrollListener); ..addListener(scrollListener);
@@ -150,21 +151,17 @@ class VideoDetailController extends GetxController
} }
void setVideoHeight() { void setVideoHeight() {
String direction = firstVideo.width != null && firstVideo.height != null final isVertical = firstVideo.width != null && firstVideo.height != null
? firstVideo.width! > firstVideo.height! ? firstVideo.width! < firstVideo.height!
? 'horizontal' : false;
: 'vertical'
: 'horizontal';
if (!scrollCtr.hasClients) { if (!scrollCtr.hasClients) {
videoHeight = direction == 'vertical' ? maxVideoHeight : minVideoHeight; videoHeight = isVertical ? maxVideoHeight : minVideoHeight;
this.direction.value = direction; this.isVertical.value = isVertical;
return; return;
} }
if (this.direction.value != direction) { if (this.isVertical.value != isVertical) {
this.direction.value = direction; this.isVertical.value = isVertical;
double videoHeight = direction == 'vertical' double videoHeight = isVertical ? maxVideoHeight : minVideoHeight;
? maxVideoHeight
: minVideoHeight;
if (this.videoHeight != videoHeight) { if (this.videoHeight != videoHeight) {
if (videoHeight > this.videoHeight) { if (videoHeight > this.videoHeight) {
// current minVideoHeight // current minVideoHeight
@@ -1140,7 +1137,7 @@ class VideoDetailController extends GetxController
? null ? null
: Duration(milliseconds: data.timeLength!)), : Duration(milliseconds: data.timeLength!)),
// 宽>高 水平 否则 垂直 // 宽>高 水平 否则 垂直
direction: direction.value, isVertical: isVertical.value,
bvid: bvid, bvid: bvid,
cid: cid.value, cid: cid.value,
autoplay: autoplay ?? autoPlay.value, autoplay: autoplay ?? autoPlay.value,
@@ -1562,12 +1559,13 @@ class VideoDetailController extends GetxController
int idx = 0; int idx = 0;
subtitles.value = playInfo.subtitle!.subtitles!; subtitles.value = playInfo.subtitle!.subtitles!;
String preference = Pref.subtitlePreference; SubtitlePrefType preference =
if (preference != 'off') { SubtitlePrefType.values[Pref.subtitlePreferenceV2];
if (preference != SubtitlePrefType.off) {
idx = subtitles.indexWhere((i) => !i.lan!.startsWith('ai')) + 1; idx = subtitles.indexWhere((i) => !i.lan!.startsWith('ai')) + 1;
if (idx == 0) { if (idx == 0) {
if (preference == 'on' || if (preference == SubtitlePrefType.on ||
(preference == 'auto' && (preference == SubtitlePrefType.auto &&
(await FlutterVolumeController.getVolume() ?? 0) <= 0)) { (await FlutterVolumeController.getVolume() ?? 0) <= 0)) {
idx = 1; idx = 1;
} }

View File

@@ -34,7 +34,7 @@ class PgcIntroController extends CommonIntroController {
? int.tryParse(Get.parameters['epId']!) ? int.tryParse(Get.parameters['epId']!)
: null; : null;
late dynamic type = late final String pgcType =
Get.parameters['type'] == '1' || Get.parameters['type'] == '4' Get.parameters['type'] == '1' || Get.parameters['type'] == '4'
? '追番' ? '追番'
: '追剧'; : '追剧';
@@ -139,9 +139,9 @@ class PgcIntroController extends CommonIntroController {
// (取消)收藏 pgc // (取消)收藏 pgc
@override @override
Future<void> actionFavVideo({String type = 'choose'}) async { Future<void> actionFavVideo({bool isQuick = false}) async {
// 收藏至默认文件夹 // 收藏至默认文件夹
if (type == 'default') { if (isQuick) {
SmartDialog.showLoading(msg: '请求中'); SmartDialog.showLoading(msg: '请求中');
queryVideoInFolder().then((res) async { queryVideoInFolder().then((res) async {
if (res['status']) { if (res['status']) {

View File

@@ -176,7 +176,8 @@ class _PgcIntroPageState extends State<PgcIntroPage>
if (isFollowed) { if (isFollowed) {
showPgcFollowDialog( showPgcFollowDialog(
context: context, context: context,
type: pgcIntroController.type, type:
pgcIntroController.pgcType,
followStatus: followStatus, followStatus: followStatus,
onUpdateStatus: (followStatus) { onUpdateStatus: (followStatus) {
if (followStatus == -1) { if (followStatus == -1) {
@@ -195,8 +196,8 @@ class _PgcIntroPageState extends State<PgcIntroPage>
}, },
child: Text( child: Text(
isFollowed isFollowed
? '${pgcIntroController.type}' ? '${pgcIntroController.pgcType}'
: '${pgcIntroController.type}', : pgcIntroController.pgcType,
), ),
); );
}, },
@@ -317,7 +318,7 @@ class _PgcIntroPageState extends State<PgcIntroPage>
onTap: () => pgcIntroController.showFavBottomSheet(context), onTap: () => pgcIntroController.showFavBottomSheet(context),
onLongPress: () => pgcIntroController.showFavBottomSheet( onLongPress: () => pgcIntroController.showFavBottomSheet(
context, context,
type: 'longPress', isLongPress: true,
), ),
selectStatus: pgcIntroController.hasFav.value, selectStatus: pgcIntroController.hasFav.value,
semanticsLabel: '收藏', semanticsLabel: '收藏',

View File

@@ -358,9 +358,9 @@ class VideoIntroController extends CommonIntroController with ReloadMixin {
// (取消)收藏 // (取消)收藏
@override @override
Future<void> actionFavVideo({String type = 'choose'}) async { Future<void> actionFavVideo({bool isQuick = false}) async {
// 收藏至默认文件夹 // 收藏至默认文件夹
if (type == 'default') { if (isQuick) {
SmartDialog.showLoading(msg: '请求中'); SmartDialog.showLoading(msg: '请求中');
queryVideoInFolder().then((res) async { queryVideoInFolder().then((res) async {
if (res['status']) { if (res['status']) {

View File

@@ -579,7 +579,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
onTap: () => videoIntroController.showFavBottomSheet(context), onTap: () => videoIntroController.showFavBottomSheet(context),
onLongPress: () => videoIntroController.showFavBottomSheet( onLongPress: () => videoIntroController.showFavBottomSheet(
context, context,
type: 'longPress', isLongPress: true,
), ),
selectStatus: videoIntroController.hasFav.value, selectStatus: videoIntroController.hasFav.value,
semanticsLabel: '收藏', semanticsLabel: '收藏',

View File

@@ -940,8 +940,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
final double width = size.width; final double width = size.width;
final double height = size.height; final double height = size.height;
final padding = MediaQuery.paddingOf(context); final padding = MediaQuery.paddingOf(context);
if (enableVerticalExpand && if (enableVerticalExpand && videoDetailController.isVertical.value) {
videoDetailController.direction.value == 'vertical') {
final double videoHeight = final double videoHeight =
height - (removeSafeArea ? 0 : padding.vertical); height - (removeSafeArea ? 0 : padding.vertical);
final double videoWidth = videoHeight * 9 / 16; final double videoWidth = videoHeight * 9 / 16;
@@ -1026,8 +1025,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
final double width = size.width; final double width = size.width;
final double height = size.height; final double height = size.height;
final padding = MediaQuery.paddingOf(context); final padding = MediaQuery.paddingOf(context);
if (enableVerticalExpand && if (enableVerticalExpand && videoDetailController.isVertical.value) {
videoDetailController.direction.value == 'vertical') {
final double videoHeight = height - (removeSafeArea ? 0 : padding.top); final double videoHeight = height - (removeSafeArea ? 0 : padding.top);
final double videoWidth = videoHeight * 9 / 16; final double videoWidth = videoHeight * 9 / 16;
return Row( return Row(

View File

@@ -2342,7 +2342,7 @@ class HeaderControlState extends State<HeaderControl> {
onTap: () => videoIntroController onTap: () => videoIntroController
.showFavBottomSheet(context), .showFavBottomSheet(context),
onLongPress: () => videoIntroController onLongPress: () => videoIntroController
.showFavBottomSheet(context, type: 'longPress'), .showFavBottomSheet(context, isLongPress: true),
selectStatus: videoIntroController.hasFav.value, selectStatus: videoIntroController.hasFav.value,
semanticsLabel: '收藏', semanticsLabel: '收藏',
needAnim: true, needAnim: true,
@@ -2442,7 +2442,7 @@ class HeaderControlState extends State<HeaderControl> {
onTap: () => onTap: () =>
pgcIntroController.showFavBottomSheet(context), pgcIntroController.showFavBottomSheet(context),
onLongPress: () => pgcIntroController onLongPress: () => pgcIntroController
.showFavBottomSheet(context, type: 'longPress'), .showFavBottomSheet(context, isLongPress: true),
selectStatus: pgcIntroController.hasFav.value, selectStatus: pgcIntroController.hasFav.value,
semanticsLabel: '收藏', semanticsLabel: '收藏',
needAnim: true, needAnim: true,

View File

@@ -1,6 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/http/ua_type.dart';
import 'package:PiliPlus/models/common/webview_menu_type.dart'; import 'package:PiliPlus/models/common/webview_menu_type.dart';
import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/accounts/account.dart'; import 'package:PiliPlus/utils/accounts/account.dart';
@@ -22,7 +22,7 @@ class WebviewPage extends StatefulWidget {
// note // note
final int? oid; final int? oid;
final String? title; final String? title;
final String? uaType; final UaType? uaType;
@override @override
State<WebviewPage> createState() => _WebviewPageState(); State<WebviewPage> createState() => _WebviewPageState();
@@ -30,7 +30,8 @@ class WebviewPage extends StatefulWidget {
class _WebviewPageState extends State<WebviewPage> { class _WebviewPageState extends State<WebviewPage> {
late final String _url = widget.url ?? Get.parameters['url'] ?? ''; late final String _url = widget.url ?? Get.parameters['url'] ?? '';
late final uaType = widget.uaType ?? Get.parameters['uaType'] ?? 'mob'; late final UaType uaType =
widget.uaType ?? UaType.values.byName(Get.parameters['uaType'] ?? 'mob');
final RxString title = ''.obs; final RxString title = ''.obs;
final RxDouble progress = 1.0.obs; final RxDouble progress = 1.0.obs;
bool? _inApp; bool? _inApp;
@@ -158,7 +159,7 @@ class _WebviewPageState extends State<WebviewPage> {
useHybridComposition: false, useHybridComposition: false,
algorithmicDarkeningAllowed: true, algorithmicDarkeningAllowed: true,
useShouldOverrideUrlLoading: true, useShouldOverrideUrlLoading: true,
userAgent: Request.headerUa(type: uaType), userAgent: uaType.ua,
mixedContentMode: MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW, mixedContentMode: MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW,
), ),
initialUrlRequest: URLRequest( initialUrlRequest: URLRequest(

View File

@@ -93,9 +93,9 @@ class PlPlayerController {
final RxBool _controlsLock = false.obs; final RxBool _controlsLock = false.obs;
final RxBool _isFullScreen = false.obs; final RxBool _isFullScreen = false.obs;
// 默认投稿视频格式 // 默认投稿视频格式
static final RxString _videoType = 'archive'.obs; bool _isLive = false;
final RxString _direction = 'horizontal'.obs; bool _isVertical = false;
final Rx<BoxFit> _videoFit = Rx(BoxFit.contain); final Rx<BoxFit> _videoFit = Rx(BoxFit.contain);
late StreamSubscription<DataStatus> _dataListenerForVideoFit; late StreamSubscription<DataStatus> _dataListenerForVideoFit;
@@ -241,12 +241,12 @@ class PlPlayerController {
RxBool get isFullScreen => _isFullScreen; RxBool get isFullScreen => _isFullScreen;
/// 全屏方向 /// 全屏方向
RxString get direction => _direction; bool get isVertical => _isVertical;
RxInt get playerCount => _playerCount; RxInt get playerCount => _playerCount;
/// ///
RxString get videoType => _videoType; bool get isLive => _isLive;
/// 弹幕开关 /// 弹幕开关
RxBool enableShowDanmaku = Pref.enableShowDanmaku.obs; RxBool enableShowDanmaku = Pref.enableShowDanmaku.obs;
@@ -467,7 +467,8 @@ class PlPlayerController {
Box video = GStorage.video; Box video = GStorage.video;
// 添加一个私有构造函数 // 添加一个私有构造函数
PlPlayerController._() { PlPlayerController._({bool isLive = false}) {
_isLive = isLive;
if (!Accounts.get(AccountType.heartbeat).isLogin || Pref.historyPause) { if (!Accounts.get(AccountType.heartbeat).isLogin || Pref.historyPause) {
enableHeart = false; enableHeart = false;
} }
@@ -492,13 +493,10 @@ class PlPlayerController {
} }
// 获取实例 传参 // 获取实例 传参
static PlPlayerController getInstance({ static PlPlayerController getInstance({bool isLive = false}) {
String videoType = 'archive',
}) {
// 如果实例尚未创建,则创建一个新实例 // 如果实例尚未创建,则创建一个新实例
_instance ??= PlPlayerController._(); _instance ??= PlPlayerController._(isLive: isLive);
_instance!._playerCount.value += 1; _instance!._playerCount.value += 1;
_videoType.value = videoType;
return _instance!; return _instance!;
} }
@@ -520,7 +518,7 @@ class PlPlayerController {
int? height, int? height,
Duration? duration, Duration? duration,
// 方向 // 方向
String? direction, bool? isVertical,
// 记录历史记录 // 记录历史记录
String bvid = '', String bvid = '',
int cid = 0, int cid = 0,
@@ -544,7 +542,7 @@ class PlPlayerController {
// 初始化数据加载状态 // 初始化数据加载状态
dataStatus.status.value = DataStatus.loading; dataStatus.status.value = DataStatus.loading;
// 初始化全屏方向 // 初始化全屏方向
_direction.value = direction ?? 'horizontal'; _isVertical = isVertical ?? false;
_bvid = bvid; _bvid = bvid;
_cid = cid; _cid = cid;
_epid = epid; _epid = epid;
@@ -697,12 +695,8 @@ class PlPlayerController {
configuration: PlayerConfiguration( configuration: PlayerConfiguration(
// 默认缓冲 4M 大小 // 默认缓冲 4M 大小
bufferSize: Pref.expandBuffer bufferSize: Pref.expandBuffer
? (videoType.value == 'live' ? (isLive ? 64 * 1024 * 1024 : 32 * 1024 * 1024)
? 64 * 1024 * 1024 : (isLive ? 16 * 1024 * 1024 : 4 * 1024 * 1024),
: 32 * 1024 * 1024)
: (videoType.value == 'live'
? 16 * 1024 * 1024
: 4 * 1024 * 1024),
), ),
); );
var pp = player.platform as NativePlayer; var pp = player.platform as NativePlayer;
@@ -833,7 +827,7 @@ class PlPlayerController {
Future<void> _initializePlayer() async { Future<void> _initializePlayer() async {
if (_instance == null) return; if (_instance == null) return;
// 设置倍速 // 设置倍速
if (videoType.value == 'live') { if (isLive) {
await setPlaybackSpeed(1.0); await setPlaybackSpeed(1.0);
} else { } else {
if (_videoPlayerController?.state.rate != _playbackSpeed.value) { if (_videoPlayerController?.state.rate != _playbackSpeed.value) {
@@ -891,7 +885,7 @@ class PlPlayerController {
videoPlayerServiceHandler.onStatusChange( videoPlayerServiceHandler.onStatusChange(
playerStatus.status.value, playerStatus.status.value,
isBuffering.value, isBuffering.value,
videoType.value == 'live', isLive,
); );
/// 触发回调事件 /// 触发回调事件
@@ -941,12 +935,12 @@ class PlPlayerController {
videoPlayerServiceHandler.onStatusChange( videoPlayerServiceHandler.onStatusChange(
playerStatus.status.value, playerStatus.status.value,
event, event,
videoType.value == 'live', isLive,
); );
}), }),
videoPlayerController!.stream.error.listen((String event) { videoPlayerController!.stream.error.listen((String event) {
// 直播的错误提示没有参考价值,均不予显示 // 直播的错误提示没有参考价值,均不予显示
if (videoType.value == 'live') return; if (isLive) return;
if (event.startsWith("Failed to open https://") || if (event.startsWith("Failed to open https://") ||
event.startsWith("Can not open external file https://") || event.startsWith("Can not open external file https://") ||
//tcp: ffurl_read returned 0xdfb9b0bb //tcp: ffurl_read returned 0xdfb9b0bb
@@ -957,11 +951,12 @@ class PlPlayerController {
const Duration(milliseconds: 10000), const Duration(milliseconds: 10000),
() { () {
Future.delayed(const Duration(milliseconds: 3000), () async { Future.delayed(const Duration(milliseconds: 3000), () async {
if (kDebugMode) { // if (kDebugMode) {
debugPrint("isBuffering.value: ${isBuffering.value}"); // debugPrint("isBuffering.value: ${isBuffering.value}");
} // }
if (kDebugMode) // if (kDebugMode) {
debugPrint("_buffered.value: ${_buffered.value}"); // debugPrint("_buffered.value: ${_buffered.value}");
// }
if (isBuffering.value && _buffered.value == Duration.zero) { if (isBuffering.value && _buffered.value == Duration.zero) {
SmartDialog.showToast( SmartDialog.showToast(
'视频链接打开失败,重试中', '视频链接打开失败,重试中',
@@ -998,7 +993,7 @@ class PlPlayerController {
videoPlayerServiceHandler.onStatusChange( videoPlayerServiceHandler.onStatusChange(
event, event,
isBuffering.value, isBuffering.value,
videoType.value == 'live', isLive,
); );
}), }),
onPositionChanged.listen((Duration event) { onPositionChanged.listen((Duration event) {
@@ -1286,7 +1281,7 @@ class PlPlayerController {
}); });
} }
// fill不应该在竖屏视频生效 // fill不应该在竖屏视频生效
} else if (attr == BoxFit.fill && direction.value == 'vertical') { } else if (attr == BoxFit.fill && isVertical) {
attr = BoxFit.contain; attr = BoxFit.contain;
} }
_videoFit.value = attr; _videoFit.value = attr;
@@ -1312,7 +1307,7 @@ class PlPlayerController {
/// 设置长按倍速状态 live模式下禁用 /// 设置长按倍速状态 live模式下禁用
Future<void> setLongPressStatus(bool val) async { Future<void> setLongPressStatus(bool val) async {
if (videoType.value == 'live') { if (isLive) {
return; return;
} }
if (controlsLock.value) { if (controlsLock.value) {
@@ -1376,10 +1371,9 @@ class PlPlayerController {
return; return;
} }
if (mode == FullScreenMode.vertical || if (mode == FullScreenMode.vertical ||
(mode == FullScreenMode.auto && direction.value == 'vertical') || (mode == FullScreenMode.auto && isVertical) ||
(mode == FullScreenMode.ratio && (mode == FullScreenMode.ratio &&
(Get.height / Get.width < 1.25 || (Get.height / Get.width < 1.25 || isVertical))) {
direction.value == 'vertical'))) {
await verticalScreenForTwoSeconds(); await verticalScreenForTwoSeconds();
} else { } else {
await landScape(); await landScape();
@@ -1445,7 +1439,7 @@ class PlPlayerController {
return; return;
} }
} }
if (videoType.value == 'live') { if (isLive) {
return; return;
} }
bool isComplete = bool isComplete =
@@ -1512,9 +1506,9 @@ class PlPlayerController {
..put(SettingBoxKey.subtitleFontWeight, subtitleFontWeight); ..put(SettingBoxKey.subtitleFontWeight, subtitleFontWeight);
} }
Future<void> dispose({String type = 'single'}) async { Future<void> dispose() async {
// 每次减1最后销毁 // 每次减1最后销毁
if (type == 'single' && playerCount.value > 1) { if (playerCount.value > 1) {
_playerCount.value -= 1; _playerCount.value -= 1;
_heartDuration = 0; _heartDuration = 0;
if (!Get.previousRoute.startsWith('/video')) { if (!Get.previousRoute.startsWith('/video')) {

View File

@@ -0,0 +1 @@
enum DoubleTapType { left, center, right }

View File

@@ -0,0 +1,10 @@
// ignore_for_file: constant_identifier_names
enum GestureType {
left,
center,
right,
horizontal,
center_up,
center_down,
}

View File

@@ -16,8 +16,10 @@ import 'package:PiliPlus/pages/video/introduction/ugc/controller.dart';
import 'package:PiliPlus/plugin/pl_player/controller.dart'; import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/plugin/pl_player/models/bottom_control_type.dart'; import 'package:PiliPlus/plugin/pl_player/models/bottom_control_type.dart';
import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart'; import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
import 'package:PiliPlus/plugin/pl_player/models/double_tap_type.dart';
import 'package:PiliPlus/plugin/pl_player/models/duration.dart'; import 'package:PiliPlus/plugin/pl_player/models/duration.dart';
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart'; import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
import 'package:PiliPlus/plugin/pl_player/models/gesture_type.dart';
import 'package:PiliPlus/plugin/pl_player/utils.dart'; import 'package:PiliPlus/plugin/pl_player/utils.dart';
import 'package:PiliPlus/plugin/pl_player/widgets/app_bar_ani.dart'; import 'package:PiliPlus/plugin/pl_player/widgets/app_bar_ani.dart';
import 'package:PiliPlus/plugin/pl_player/widgets/backward_seek.dart'; import 'package:PiliPlus/plugin/pl_player/widgets/backward_seek.dart';
@@ -110,7 +112,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
late final RxBool showRestoreScaleBtn = false.obs; late final RxBool showRestoreScaleBtn = false.obs;
Offset _initialFocalPoint = Offset.zero; Offset _initialFocalPoint = Offset.zero;
String? _gestureType; GestureType? _gestureType;
//播放器放缩 //播放器放缩
bool interacting = false; bool interacting = false;
@@ -138,20 +140,20 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
} }
void doubleTapFuc(String type) { void doubleTapFuc(DoubleTapType type) {
if (!plPlayerController.enableQuickDouble) { if (!plPlayerController.enableQuickDouble) {
onDoubleTapCenter(); onDoubleTapCenter();
return; return;
} }
switch (type) { switch (type) {
case 'left': case DoubleTapType.left:
// 双击左边区域 👈 // 双击左边区域 👈
onDoubleTapSeekBackward(); onDoubleTapSeekBackward();
break; break;
case 'center': case DoubleTapType.center:
onDoubleTapCenter(); onDoubleTapCenter();
break; break;
case 'right': case DoubleTapType.right:
// 双击右边区域 👈 // 双击右边区域 👈
onDoubleTapSeekForward(); onDoubleTapSeekForward();
break; break;
@@ -770,7 +772,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
if (cumulativeDelta.distance < 1) return; if (cumulativeDelta.distance < 1) return;
if (cumulativeDelta.dx.abs() > if (cumulativeDelta.dx.abs() >
3 * cumulativeDelta.dy.abs()) { 3 * cumulativeDelta.dy.abs()) {
_gestureType = 'horizontal'; _gestureType = GestureType.horizontal;
} else if (cumulativeDelta.dy.abs() > } else if (cumulativeDelta.dy.abs() >
3 * cumulativeDelta.dx.abs()) { 3 * cumulativeDelta.dx.abs()) {
if (!plPlayerController.enableSlideVolumeBrightness && if (!plPlayerController.enableSlideVolumeBrightness &&
@@ -787,19 +789,19 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
return; return;
} }
// 左边区域 // 左边区域
_gestureType = 'left'; _gestureType = GestureType.left;
} else if (tapPosition < sectionWidth * 2) { } else if (tapPosition < sectionWidth * 2) {
if (!plPlayerController.enableSlideFS) { if (!plPlayerController.enableSlideFS) {
return; return;
} }
// 全屏 // 全屏
_gestureType = 'center'; _gestureType = GestureType.center;
} else { } else {
if (!plPlayerController.enableSlideVolumeBrightness) { if (!plPlayerController.enableSlideVolumeBrightness) {
return; return;
} }
// 右边区域 // 右边区域
_gestureType = 'right'; _gestureType = GestureType.right;
} }
} else { } else {
return; return;
@@ -808,9 +810,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Offset delta = details.focalPointDelta; Offset delta = details.focalPointDelta;
if (_gestureType == 'horizontal') { if (_gestureType == GestureType.horizontal) {
// live模式下禁用 // live模式下禁用
if (plPlayerController.videoType.value == 'live') return; if (plPlayerController.isLive) return;
final int curSliderPosition = final int curSliderPosition =
plPlayerController.sliderPosition.value.inMilliseconds; plPlayerController.sliderPosition.value.inMilliseconds;
@@ -884,14 +886,14 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
} catch (_) {} } catch (_) {}
} }
} else if (_gestureType == 'left') { } else if (_gestureType == GestureType.left) {
// 左边区域 👈 // 左边区域 👈
final double level = maxHeight * 3; final double level = maxHeight * 3;
final double brightness = final double brightness =
_brightnessValue.value - delta.dy / level; _brightnessValue.value - delta.dy / level;
final double result = brightness.clamp(0.0, 1.0); final double result = brightness.clamp(0.0, 1.0);
setBrightness(result); setBrightness(result);
} else if (_gestureType == 'center') { } else if (_gestureType == GestureType.center) {
// 全屏 // 全屏
const double threshold = 2.5; // 滑动阈值 const double threshold = 2.5; // 滑动阈值
double cumulativeDy = double cumulativeDy =
@@ -902,7 +904,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
if (cumulativeDy > threshold) { if (cumulativeDy > threshold) {
_gestureType = 'center_down'; _gestureType = GestureType.center_down;
if (isFullScreen ^ if (isFullScreen ^
plPlayerController.fullScreenGestureReverse) { plPlayerController.fullScreenGestureReverse) {
fullScreenTrigger( fullScreenTrigger(
@@ -911,7 +913,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
// if (kDebugMode) debugPrint('center_down:$cumulativeDy'); // if (kDebugMode) debugPrint('center_down:$cumulativeDy');
} else if (cumulativeDy < -threshold) { } else if (cumulativeDy < -threshold) {
_gestureType = 'center_up'; _gestureType = GestureType.center_up;
if (!isFullScreen ^ if (!isFullScreen ^
plPlayerController.fullScreenGestureReverse) { plPlayerController.fullScreenGestureReverse) {
fullScreenTrigger( fullScreenTrigger(
@@ -920,7 +922,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
// if (kDebugMode) debugPrint('center_up:$cumulativeDy'); // if (kDebugMode) debugPrint('center_up:$cumulativeDy');
} }
} else if (_gestureType == 'right') { } else if (_gestureType == GestureType.right) {
// 右边区域 // 右边区域
final double level = maxHeight * 0.5; final double level = maxHeight * 0.5;
EasyThrottle.throttle( EasyThrottle.throttle(
@@ -975,25 +977,25 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
final double tapPosition = details.localPosition.dx; final double tapPosition = details.localPosition.dx;
final double sectionWidth = maxWidth / 3; final double sectionWidth = maxWidth / 3;
late String gestureType; late GestureType gestureType;
if (tapPosition < sectionWidth) { if (tapPosition < sectionWidth) {
if (!plPlayerController.enableSlideVolumeBrightness) { if (!plPlayerController.enableSlideVolumeBrightness) {
return; return;
} }
// 左边区域 // 左边区域
gestureType = 'left'; gestureType = GestureType.left;
} else if (tapPosition < sectionWidth * 2) { } else if (tapPosition < sectionWidth * 2) {
if (!plPlayerController.enableSlideFS) { if (!plPlayerController.enableSlideFS) {
return; return;
} }
// 全屏 // 全屏
gestureType = 'center'; gestureType = GestureType.center;
} else { } else {
if (!plPlayerController.enableSlideVolumeBrightness) { if (!plPlayerController.enableSlideVolumeBrightness) {
return; return;
} }
// 右边区域 // 右边区域
gestureType = 'right'; gestureType = GestureType.right;
} }
if (_gestureType != null && _gestureType != gestureType) { if (_gestureType != null && _gestureType != gestureType) {
@@ -1001,14 +1003,14 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
_gestureType = gestureType; _gestureType = gestureType;
if (_gestureType == 'left') { if (_gestureType == GestureType.left) {
// 左边区域 👈 // 左边区域 👈
final double level = maxHeight * 3; final double level = maxHeight * 3;
final double brightness = final double brightness =
_brightnessValue.value - details.delta.dy / level; _brightnessValue.value - details.delta.dy / level;
final double result = brightness.clamp(0.0, 1.0); final double result = brightness.clamp(0.0, 1.0);
setBrightness(result); setBrightness(result);
} else if (_gestureType == 'center') { } else if (_gestureType == GestureType.center) {
// 全屏 // 全屏
const double threshold = 2.5; // 滑动阈值 const double threshold = 2.5; // 滑动阈值
double cumulativeDy = double cumulativeDy =
@@ -1019,7 +1021,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
if (cumulativeDy > threshold) { if (cumulativeDy > threshold) {
_gestureType = 'center_down'; _gestureType = GestureType.center_down;
if (isFullScreen ^ if (isFullScreen ^
plPlayerController.fullScreenGestureReverse) { plPlayerController.fullScreenGestureReverse) {
fullScreenTrigger( fullScreenTrigger(
@@ -1028,7 +1030,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
// if (kDebugMode) debugPrint('center_down:$cumulativeDy'); // if (kDebugMode) debugPrint('center_down:$cumulativeDy');
} else if (cumulativeDy < -threshold) { } else if (cumulativeDy < -threshold) {
_gestureType = 'center_up'; _gestureType = GestureType.center_up;
if (!isFullScreen ^ if (!isFullScreen ^
plPlayerController.fullScreenGestureReverse) { plPlayerController.fullScreenGestureReverse) {
fullScreenTrigger( fullScreenTrigger(
@@ -1037,7 +1039,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
// if (kDebugMode) debugPrint('center_up:$cumulativeDy'); // if (kDebugMode) debugPrint('center_up:$cumulativeDy');
} }
} else if (_gestureType == 'right') { } else if (_gestureType == GestureType.right) {
// 右边区域 // 右边区域
final double level = maxHeight * 0.5; final double level = maxHeight * 0.5;
EasyThrottle.throttle( EasyThrottle.throttle(
@@ -1065,19 +1067,19 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
if (plPlayerController.controlsLock.value) { if (plPlayerController.controlsLock.value) {
return; return;
} }
if (plPlayerController.videoType.value == 'live') { if (plPlayerController.isLive) {
doubleTapFuc('center'); doubleTapFuc(DoubleTapType.center);
return; return;
} }
final double tapPosition = details.localPosition.dx; final double tapPosition = details.localPosition.dx;
final double sectionWidth = maxWidth / 4; final double sectionWidth = maxWidth / 4;
String type = 'left'; DoubleTapType type;
if (tapPosition < sectionWidth) { if (tapPosition < sectionWidth) {
type = 'left'; type = DoubleTapType.left;
} else if (tapPosition < sectionWidth * 3) { } else if (tapPosition < sectionWidth * 3) {
type = 'center'; type = DoubleTapType.center;
} else { } else {
type = 'right'; type = DoubleTapType.right;
} }
doubleTapFuc(type); doubleTapFuc(type);
}, },
@@ -1426,7 +1428,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
} }
if (plPlayerController.videoType.value == 'live') { if (plPlayerController.isLive) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
@@ -1551,9 +1553,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
SafeArea( SafeArea(
child: Obx( child: Obx(
() => Visibility( () => Visibility(
visible: visible: !plPlayerController.isLive && isFullScreen,
plPlayerController.videoType.value != 'live' &&
isFullScreen,
child: Align( child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: FractionalTranslation( child: FractionalTranslation(
@@ -1895,7 +1895,7 @@ Widget buildSeekPreviewWidget(PlPlayerController plPlayerController) {
try { try {
double scale = double scale =
plPlayerController.isFullScreen.value && plPlayerController.isFullScreen.value &&
plPlayerController.direction.value == 'horizontal' !plPlayerController.isVertical
? 4 ? 4
: 2.5; : 2.5;
// offset // offset

View File

@@ -134,7 +134,7 @@ class SettingBoxKey {
directExitOnBack = 'directExitOnBack', directExitOnBack = 'directExitOnBack',
quickFavId = 'quickFavId'; quickFavId = 'quickFavId';
static const String subtitlePreference = 'subtitlePreference', static const String subtitlePreferenceV2 = 'subtitlePreferenceV2',
enableDragSubtitle = 'enableDragSubtitle', enableDragSubtitle = 'enableDragSubtitle',
subtitlePaddingH = 'subtitlePaddingH', subtitlePaddingH = 'subtitlePaddingH',
subtitlePaddingB = 'subtitlePaddingB', subtitlePaddingB = 'subtitlePaddingB',

View File

@@ -186,9 +186,9 @@ class Pref {
defaultValue: BtmProgressBehavior.alwaysShow.index, defaultValue: BtmProgressBehavior.alwaysShow.index,
); );
static String get subtitlePreference => _setting.get( static int get subtitlePreferenceV2 => _setting.get(
SettingBoxKey.subtitlePreference, SettingBoxKey.subtitlePreferenceV2,
defaultValue: SubtitlePrefType.off.code, defaultValue: SubtitlePrefType.off.index,
); );
static bool get useRelativeSlide => static bool get useRelativeSlide =>

View File

@@ -3,6 +3,7 @@ import 'dart:io' show Platform;
import 'package:PiliPlus/build_config.dart'; import 'package:PiliPlus/build_config.dart';
import 'package:PiliPlus/http/api.dart'; import 'package:PiliPlus/http/api.dart';
import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/ua_type.dart';
import 'package:PiliPlus/utils/accounts/account.dart'; import 'package:PiliPlus/utils/accounts/account.dart';
import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage.dart';
@@ -22,7 +23,7 @@ class Update {
final res = await Request().get( final res = await Request().get(
Api.latestApp, Api.latestApp,
options: Options( options: Options(
headers: {'user-agent': Request.headerUa()}, headers: {'user-agent': UaType.mob.ua},
extra: {'account': NoAccount()}, extra: {'account': NoAccount()},
), ),
); );