mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-16 15:16:15 +08:00
opt type
opt ua opt subtitle opt playertype Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -290,15 +290,6 @@ class Request {
|
||||
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(
|
||||
List<int> responseBytes,
|
||||
RequestOptions options,
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/http/api.dart';
|
||||
import 'package:PiliPlus/http/init.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_new/live/live_area_list/area_item.dart';
|
||||
import 'package:PiliPlus/models_new/live/live_area_list/area_list.dart';
|
||||
@@ -114,7 +115,7 @@ class LiveHttp {
|
||||
options: Options(
|
||||
headers: {
|
||||
'referer': 'https://live.bilibili.com/$roomId',
|
||||
'user-agent': Request.headerUa(type: 'pc'),
|
||||
'user-agent': UaType.pc.ua,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:PiliPlus/http/api.dart';
|
||||
import 'package:PiliPlus/http/constants.dart';
|
||||
import 'package:PiliPlus/http/init.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/dynamics/result.dart';
|
||||
import 'package:PiliPlus/models/member/info.dart';
|
||||
@@ -280,7 +281,7 @@ class MemberHttp {
|
||||
headers: {
|
||||
'origin': 'https://space.bilibili.com',
|
||||
'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,
|
||||
options: Options(
|
||||
headers: {
|
||||
HttpHeaders.userAgentHeader: Request.headerUa(type: 'pc'),
|
||||
HttpHeaders.userAgentHeader: UaType.pc.ua,
|
||||
HttpHeaders.refererHeader: '${HttpString.spaceBaseUrl}/$mid',
|
||||
'origin': HttpString.spaceBaseUrl,
|
||||
},
|
||||
|
||||
11
lib/http/ua_type.dart
Normal file
11
lib/http/ua_type.dart
Normal 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);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import 'package:PiliPlus/http/api.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/http/loading_state.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/home/rcmd/result.dart';
|
||||
import 'package:PiliPlus/models/model_hot_video_item.dart';
|
||||
@@ -367,7 +368,7 @@ class VideoHttp {
|
||||
headers: {
|
||||
'origin': 'https://www.bilibili.com',
|
||||
'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: {
|
||||
'origin': 'https://www.bilibili.com',
|
||||
'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({
|
||||
"entity": "user",
|
||||
"entity_id": mid,
|
||||
'fp': Request.headerUa(type: 'pc'),
|
||||
'fp': UaType.pc.ua,
|
||||
}),
|
||||
'csrf': Accounts.main.csrf,
|
||||
},
|
||||
@@ -602,7 +603,7 @@ class VideoHttp {
|
||||
headers: {
|
||||
'origin': 'https://space.bilibili.com',
|
||||
'referer': 'https://space.bilibili.com/$mid/dynamic',
|
||||
'user-agent': Request.headerUa(type: 'pc'),
|
||||
'user-agent': UaType.pc.ua,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
13
lib/models/common/setting_type.dart
Normal file
13
lib/models/common/setting_type.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
enum SettingType {
|
||||
privacySetting('隐私设置'),
|
||||
recommendSetting('推荐流设置'),
|
||||
videoSetting('音视频设置'),
|
||||
playSetting('播放器设置'),
|
||||
styleSetting('外观设置'),
|
||||
extraSetting('其它设置'),
|
||||
webdavSetting('WebDAV 设置'),
|
||||
about('关于');
|
||||
|
||||
final String title;
|
||||
const SettingType(this.title);
|
||||
}
|
||||
@@ -1,21 +1,9 @@
|
||||
enum SubtitlePrefType { off, on, withoutAi, auto }
|
||||
enum SubtitlePrefType {
|
||||
off('默认不显示字幕'),
|
||||
on('优先选择非自动生成(ai)字幕'),
|
||||
withoutAi('跳过自动生成(ai)字幕,选择第一个可用字幕'),
|
||||
auto('静音时等同第二项,非静音时等同第三项');
|
||||
|
||||
extension SubtitlePrefTypeExt on SubtitlePrefType {
|
||||
String get description => const [
|
||||
'默认不显示字幕',
|
||||
'优先选择非自动生成(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;
|
||||
}
|
||||
final String desc;
|
||||
const SubtitlePrefType(this.desc);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ abstract class CommonIntroController extends GetxController {
|
||||
|
||||
Future queryVideoInFolder();
|
||||
|
||||
Future<void> actionFavVideo({String type = 'choose'});
|
||||
Future<void> actionFavVideo({bool isQuick = false});
|
||||
|
||||
late final enableQuickFav = Pref.enableQuickFav;
|
||||
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) {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
return;
|
||||
@@ -63,12 +63,12 @@ abstract class CommonIntroController extends GetxController {
|
||||
// 点按 收藏至默认文件夹
|
||||
// 长按选择文件夹
|
||||
if (enableQuickFav) {
|
||||
if (type == 'tap') {
|
||||
actionFavVideo(type: 'default');
|
||||
if (!isLongPress) {
|
||||
actionFavVideo(isQuick: true);
|
||||
} else {
|
||||
PageUtils.showFavBottomSheet(context: context, ctr: this);
|
||||
}
|
||||
} else if (type != 'longPress') {
|
||||
} else if (!isLongPress) {
|
||||
PageUtils.showFavBottomSheet(context: context, ctr: this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ class DynamicsController extends GetxController
|
||||
}
|
||||
|
||||
late bool isQuerying = false;
|
||||
Future<void> queryFollowUp({String type = 'init'}) async {
|
||||
Future<void> queryFollowUp() async {
|
||||
if (isQuerying) return;
|
||||
isQuerying = true;
|
||||
if (!accountService.isLogin.value) {
|
||||
|
||||
@@ -36,7 +36,7 @@ class LiveRoomController extends GetxController {
|
||||
// 静音状态
|
||||
RxBool volumeOff = false.obs;
|
||||
PlPlayerController plPlayerController = PlPlayerController.getInstance(
|
||||
videoType: 'live',
|
||||
isLive: true,
|
||||
);
|
||||
Rx<RoomInfoH5Data?> roomInfoH5 = Rx<RoomInfoH5Data?>(null);
|
||||
|
||||
@@ -80,7 +80,7 @@ class LiveRoomController extends GetxController {
|
||||
},
|
||||
),
|
||||
autoplay: true,
|
||||
direction: isPortrait.value ? 'vertical' : 'horizontal',
|
||||
isVertical: isPortrait.value,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ class LiveHeaderControl extends StatelessWidget {
|
||||
if ((await floating.isPipAvailable) == true) {
|
||||
plPlayerController.hiddenControls(false);
|
||||
floating.enable(
|
||||
plPlayerController.direction.value == 'vertical'
|
||||
plPlayerController.isVertical
|
||||
? const EnableManual(
|
||||
aspectRatio: Rational.vertical(),
|
||||
)
|
||||
|
||||
@@ -95,22 +95,22 @@ List<SettingsModel> get playSettings => [
|
||||
title: '自动启用字幕',
|
||||
leading: const Icon(Icons.closed_caption_outlined),
|
||||
getSubtitle: () =>
|
||||
'当前选择偏好:${SubtitlePrefTypeExt.fromCode(Pref.subtitlePreference)!.description}',
|
||||
'当前选择偏好:${SubtitlePrefType.values[Pref.subtitlePreferenceV2].desc}',
|
||||
onTap: (setState) async {
|
||||
String? result = await showDialog(
|
||||
int? result = await showDialog(
|
||||
context: Get.context!,
|
||||
builder: (context) {
|
||||
return SelectDialog<String>(
|
||||
return SelectDialog<int>(
|
||||
title: '字幕选择偏好',
|
||||
value: Pref.subtitlePreference,
|
||||
value: Pref.subtitlePreferenceV2,
|
||||
values: SubtitlePrefType.values
|
||||
.map((e) => (e.code, e.description))
|
||||
.map((e) => (e.index, e.desc))
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
if (result != null) {
|
||||
await GStorage.setting.put(SettingBoxKey.subtitlePreference, result);
|
||||
await GStorage.setting.put(SettingBoxKey.subtitlePreferenceV2, result);
|
||||
setState();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
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/login/controller.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';
|
||||
|
||||
class _SettingsModel {
|
||||
final String name;
|
||||
final String title;
|
||||
final SettingType type;
|
||||
final String? subtitle;
|
||||
final IconData icon;
|
||||
|
||||
const _SettingsModel({
|
||||
required this.name,
|
||||
required this.title,
|
||||
required this.type,
|
||||
this.subtitle,
|
||||
required this.icon,
|
||||
});
|
||||
@@ -39,55 +38,47 @@ class SettingPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _SettingPageState extends State<SettingPage> {
|
||||
late String _type = 'privacySetting';
|
||||
late SettingType _type = SettingType.privacySetting;
|
||||
final RxBool _noAccount = Accounts.accountMode.isEmpty.obs;
|
||||
bool get _isPortrait => context.orientation == Orientation.portrait;
|
||||
late bool _isPortrait;
|
||||
|
||||
final List<_SettingsModel> _items = [
|
||||
const _SettingsModel(
|
||||
name: 'privacySetting',
|
||||
title: '隐私设置',
|
||||
type: SettingType.privacySetting,
|
||||
subtitle: '黑名单、无痕模式',
|
||||
icon: Icons.privacy_tip_outlined,
|
||||
),
|
||||
const _SettingsModel(
|
||||
name: 'recommendSetting',
|
||||
title: '推荐流设置',
|
||||
type: SettingType.recommendSetting,
|
||||
subtitle: '推荐来源(web/app)、刷新保留内容、过滤器',
|
||||
icon: Icons.explore_outlined,
|
||||
),
|
||||
const _SettingsModel(
|
||||
name: 'videoSetting',
|
||||
title: '音视频设置',
|
||||
type: SettingType.videoSetting,
|
||||
subtitle: '画质、音质、解码、缓冲、音频输出等',
|
||||
icon: Icons.video_settings_outlined,
|
||||
),
|
||||
const _SettingsModel(
|
||||
name: 'playSetting',
|
||||
title: '播放器设置',
|
||||
type: SettingType.playSetting,
|
||||
subtitle: '双击/长按、全屏、后台播放、弹幕、字幕、底部进度条等',
|
||||
icon: Icons.touch_app_outlined,
|
||||
),
|
||||
const _SettingsModel(
|
||||
name: 'styleSetting',
|
||||
title: '外观设置',
|
||||
type: SettingType.styleSetting,
|
||||
subtitle: '横屏适配(平板)、侧栏、列宽、首页、动态红点、主题、字号、图片、帧率等',
|
||||
icon: Icons.style_outlined,
|
||||
),
|
||||
const _SettingsModel(
|
||||
name: 'extraSetting',
|
||||
title: '其它设置',
|
||||
type: SettingType.extraSetting,
|
||||
subtitle: '震动、搜索、收藏、ai、评论、动态、代理、更新检查等',
|
||||
icon: Icons.extension_outlined,
|
||||
),
|
||||
const _SettingsModel(
|
||||
name: 'webdavSetting',
|
||||
title: 'WebDAV 设置',
|
||||
type: SettingType.webdavSetting,
|
||||
icon: MdiIcons.databaseCogOutline,
|
||||
),
|
||||
const _SettingsModel(
|
||||
name: 'about',
|
||||
title: '关于',
|
||||
type: SettingType.about,
|
||||
icon: Icons.info_outline,
|
||||
),
|
||||
];
|
||||
@@ -95,21 +86,10 @@ class _SettingPageState extends State<SettingPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
_isPortrait = context.orientation == Orientation.portrait;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: _isPortrait
|
||||
? const Text('设置')
|
||||
: Text(switch (_type) {
|
||||
'privacySetting' => '隐私设置',
|
||||
'recommendSetting' => '推荐流设置',
|
||||
'videoSetting' => '音视频设置',
|
||||
'playSetting' => '播放器设置',
|
||||
'styleSetting' => '外观设置',
|
||||
'extraSetting' => '其它设置',
|
||||
'webdavSetting' => 'WebDAV 设置',
|
||||
'about' => '关于',
|
||||
_ => '设置',
|
||||
}),
|
||||
title: _isPortrait ? const Text('设置') : Text(_type.title),
|
||||
),
|
||||
body: _isPortrait
|
||||
? _buildList(theme)
|
||||
@@ -136,21 +116,28 @@ class _SettingPageState extends State<SettingPage> {
|
||||
removeLeft: true,
|
||||
removeTop: true,
|
||||
child: switch (_type) {
|
||||
'privacySetting' => const PrivacySetting(
|
||||
SettingType.privacySetting => const PrivacySetting(
|
||||
showAppBar: false,
|
||||
),
|
||||
'recommendSetting' => const RecommendSetting(
|
||||
SettingType.recommendSetting => const RecommendSetting(
|
||||
showAppBar: false,
|
||||
),
|
||||
'videoSetting' => const VideoSetting(showAppBar: false),
|
||||
'playSetting' => const PlaySetting(showAppBar: false),
|
||||
'styleSetting' => const StyleSetting(showAppBar: false),
|
||||
'extraSetting' => const ExtraSetting(showAppBar: false),
|
||||
'webdavSetting' => const WebDavSettingPage(
|
||||
SettingType.videoSetting => const VideoSetting(
|
||||
showAppBar: false,
|
||||
),
|
||||
'about' => const AboutPage(showAppBar: false),
|
||||
_ => const SizedBox.shrink(),
|
||||
SettingType.playSetting => const PlaySetting(
|
||||
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) {
|
||||
Get.toNamed('/$name');
|
||||
Get.toNamed('/${type.name}');
|
||||
} else {
|
||||
_type = name;
|
||||
_type = type;
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
Color? _getTileColor(ThemeData theme, String name) {
|
||||
Color? _getTileColor(ThemeData theme, SettingType type) {
|
||||
if (_isPortrait) {
|
||||
return null;
|
||||
} 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)
|
||||
.map(
|
||||
(item) => ListTile(
|
||||
tileColor: _getTileColor(theme, item.name),
|
||||
onTap: () => _toPage(item.name),
|
||||
tileColor: _getTileColor(theme, item.type),
|
||||
onTap: () => _toPage(item.type),
|
||||
leading: Icon(item.icon),
|
||||
title: Text(item.title, style: titleStyle),
|
||||
title: Text(item.type.title, style: titleStyle),
|
||||
subtitle: item.subtitle == null
|
||||
? null
|
||||
: Text(item.subtitle!, style: subTitleStyle),
|
||||
@@ -212,10 +199,10 @@ class _SettingPageState extends State<SettingPage> {
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
tileColor: _getTileColor(theme, _items.last.name),
|
||||
onTap: () => _toPage(_items.last.name),
|
||||
tileColor: _getTileColor(theme, _items.last.type),
|
||||
onTap: () => _toPage(_items.last.type),
|
||||
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),
|
||||
],
|
||||
|
||||
@@ -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/skip_type.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_quality.dart';
|
||||
import 'package:PiliPlus/models/video/play/url.dart';
|
||||
@@ -69,7 +70,7 @@ class VideoDetailController extends GetxController
|
||||
final heroTag = Get.arguments['heroTag'];
|
||||
final RxString cover = ''.obs;
|
||||
// 视频类型 默认投稿视频
|
||||
final videoType = Get.arguments['videoType'] ?? SearchType.video;
|
||||
final SearchType videoType = Get.arguments['videoType'] ?? SearchType.video;
|
||||
|
||||
/// tabs相关配置
|
||||
late TabController tabCtr;
|
||||
@@ -122,7 +123,7 @@ class VideoDetailController extends GetxController
|
||||
StreamSubscription<Duration>? positionSubscription;
|
||||
|
||||
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 ScrollController scrollCtr = ScrollController()
|
||||
..addListener(scrollListener);
|
||||
@@ -150,21 +151,17 @@ class VideoDetailController extends GetxController
|
||||
}
|
||||
|
||||
void setVideoHeight() {
|
||||
String direction = firstVideo.width != null && firstVideo.height != null
|
||||
? firstVideo.width! > firstVideo.height!
|
||||
? 'horizontal'
|
||||
: 'vertical'
|
||||
: 'horizontal';
|
||||
final isVertical = firstVideo.width != null && firstVideo.height != null
|
||||
? firstVideo.width! < firstVideo.height!
|
||||
: false;
|
||||
if (!scrollCtr.hasClients) {
|
||||
videoHeight = direction == 'vertical' ? maxVideoHeight : minVideoHeight;
|
||||
this.direction.value = direction;
|
||||
videoHeight = isVertical ? maxVideoHeight : minVideoHeight;
|
||||
this.isVertical.value = isVertical;
|
||||
return;
|
||||
}
|
||||
if (this.direction.value != direction) {
|
||||
this.direction.value = direction;
|
||||
double videoHeight = direction == 'vertical'
|
||||
? maxVideoHeight
|
||||
: minVideoHeight;
|
||||
if (this.isVertical.value != isVertical) {
|
||||
this.isVertical.value = isVertical;
|
||||
double videoHeight = isVertical ? maxVideoHeight : minVideoHeight;
|
||||
if (this.videoHeight != videoHeight) {
|
||||
if (videoHeight > this.videoHeight) {
|
||||
// current minVideoHeight
|
||||
@@ -1140,7 +1137,7 @@ class VideoDetailController extends GetxController
|
||||
? null
|
||||
: Duration(milliseconds: data.timeLength!)),
|
||||
// 宽>高 水平 否则 垂直
|
||||
direction: direction.value,
|
||||
isVertical: isVertical.value,
|
||||
bvid: bvid,
|
||||
cid: cid.value,
|
||||
autoplay: autoplay ?? autoPlay.value,
|
||||
@@ -1562,12 +1559,13 @@ class VideoDetailController extends GetxController
|
||||
int idx = 0;
|
||||
subtitles.value = playInfo.subtitle!.subtitles!;
|
||||
|
||||
String preference = Pref.subtitlePreference;
|
||||
if (preference != 'off') {
|
||||
SubtitlePrefType preference =
|
||||
SubtitlePrefType.values[Pref.subtitlePreferenceV2];
|
||||
if (preference != SubtitlePrefType.off) {
|
||||
idx = subtitles.indexWhere((i) => !i.lan!.startsWith('ai')) + 1;
|
||||
if (idx == 0) {
|
||||
if (preference == 'on' ||
|
||||
(preference == 'auto' &&
|
||||
if (preference == SubtitlePrefType.on ||
|
||||
(preference == SubtitlePrefType.auto &&
|
||||
(await FlutterVolumeController.getVolume() ?? 0) <= 0)) {
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class PgcIntroController extends CommonIntroController {
|
||||
? int.tryParse(Get.parameters['epId']!)
|
||||
: null;
|
||||
|
||||
late dynamic type =
|
||||
late final String pgcType =
|
||||
Get.parameters['type'] == '1' || Get.parameters['type'] == '4'
|
||||
? '追番'
|
||||
: '追剧';
|
||||
@@ -139,9 +139,9 @@ class PgcIntroController extends CommonIntroController {
|
||||
|
||||
// (取消)收藏 pgc
|
||||
@override
|
||||
Future<void> actionFavVideo({String type = 'choose'}) async {
|
||||
Future<void> actionFavVideo({bool isQuick = false}) async {
|
||||
// 收藏至默认文件夹
|
||||
if (type == 'default') {
|
||||
if (isQuick) {
|
||||
SmartDialog.showLoading(msg: '请求中');
|
||||
queryVideoInFolder().then((res) async {
|
||||
if (res['status']) {
|
||||
|
||||
@@ -176,7 +176,8 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
||||
if (isFollowed) {
|
||||
showPgcFollowDialog(
|
||||
context: context,
|
||||
type: pgcIntroController.type,
|
||||
type:
|
||||
pgcIntroController.pgcType,
|
||||
followStatus: followStatus,
|
||||
onUpdateStatus: (followStatus) {
|
||||
if (followStatus == -1) {
|
||||
@@ -195,8 +196,8 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
||||
},
|
||||
child: Text(
|
||||
isFollowed
|
||||
? '已${pgcIntroController.type}'
|
||||
: '${pgcIntroController.type}',
|
||||
? '已${pgcIntroController.pgcType}'
|
||||
: pgcIntroController.pgcType,
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -317,7 +318,7 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
||||
onTap: () => pgcIntroController.showFavBottomSheet(context),
|
||||
onLongPress: () => pgcIntroController.showFavBottomSheet(
|
||||
context,
|
||||
type: 'longPress',
|
||||
isLongPress: true,
|
||||
),
|
||||
selectStatus: pgcIntroController.hasFav.value,
|
||||
semanticsLabel: '收藏',
|
||||
|
||||
@@ -358,9 +358,9 @@ class VideoIntroController extends CommonIntroController with ReloadMixin {
|
||||
|
||||
// (取消)收藏
|
||||
@override
|
||||
Future<void> actionFavVideo({String type = 'choose'}) async {
|
||||
Future<void> actionFavVideo({bool isQuick = false}) async {
|
||||
// 收藏至默认文件夹
|
||||
if (type == 'default') {
|
||||
if (isQuick) {
|
||||
SmartDialog.showLoading(msg: '请求中');
|
||||
queryVideoInFolder().then((res) async {
|
||||
if (res['status']) {
|
||||
|
||||
@@ -579,7 +579,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
onTap: () => videoIntroController.showFavBottomSheet(context),
|
||||
onLongPress: () => videoIntroController.showFavBottomSheet(
|
||||
context,
|
||||
type: 'longPress',
|
||||
isLongPress: true,
|
||||
),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
semanticsLabel: '收藏',
|
||||
|
||||
@@ -940,8 +940,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
final double width = size.width;
|
||||
final double height = size.height;
|
||||
final padding = MediaQuery.paddingOf(context);
|
||||
if (enableVerticalExpand &&
|
||||
videoDetailController.direction.value == 'vertical') {
|
||||
if (enableVerticalExpand && videoDetailController.isVertical.value) {
|
||||
final double videoHeight =
|
||||
height - (removeSafeArea ? 0 : padding.vertical);
|
||||
final double videoWidth = videoHeight * 9 / 16;
|
||||
@@ -1026,8 +1025,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
final double width = size.width;
|
||||
final double height = size.height;
|
||||
final padding = MediaQuery.paddingOf(context);
|
||||
if (enableVerticalExpand &&
|
||||
videoDetailController.direction.value == 'vertical') {
|
||||
if (enableVerticalExpand && videoDetailController.isVertical.value) {
|
||||
final double videoHeight = height - (removeSafeArea ? 0 : padding.top);
|
||||
final double videoWidth = videoHeight * 9 / 16;
|
||||
return Row(
|
||||
|
||||
@@ -2342,7 +2342,7 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
onTap: () => videoIntroController
|
||||
.showFavBottomSheet(context),
|
||||
onLongPress: () => videoIntroController
|
||||
.showFavBottomSheet(context, type: 'longPress'),
|
||||
.showFavBottomSheet(context, isLongPress: true),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
semanticsLabel: '收藏',
|
||||
needAnim: true,
|
||||
@@ -2442,7 +2442,7 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
onTap: () =>
|
||||
pgcIntroController.showFavBottomSheet(context),
|
||||
onLongPress: () => pgcIntroController
|
||||
.showFavBottomSheet(context, type: 'longPress'),
|
||||
.showFavBottomSheet(context, isLongPress: true),
|
||||
selectStatus: pgcIntroController.hasFav.value,
|
||||
semanticsLabel: '收藏',
|
||||
needAnim: true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/accounts/account.dart';
|
||||
@@ -22,7 +22,7 @@ class WebviewPage extends StatefulWidget {
|
||||
// note
|
||||
final int? oid;
|
||||
final String? title;
|
||||
final String? uaType;
|
||||
final UaType? uaType;
|
||||
|
||||
@override
|
||||
State<WebviewPage> createState() => _WebviewPageState();
|
||||
@@ -30,7 +30,8 @@ class WebviewPage extends StatefulWidget {
|
||||
|
||||
class _WebviewPageState extends State<WebviewPage> {
|
||||
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 RxDouble progress = 1.0.obs;
|
||||
bool? _inApp;
|
||||
@@ -158,7 +159,7 @@ class _WebviewPageState extends State<WebviewPage> {
|
||||
useHybridComposition: false,
|
||||
algorithmicDarkeningAllowed: true,
|
||||
useShouldOverrideUrlLoading: true,
|
||||
userAgent: Request.headerUa(type: uaType),
|
||||
userAgent: uaType.ua,
|
||||
mixedContentMode: MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW,
|
||||
),
|
||||
initialUrlRequest: URLRequest(
|
||||
|
||||
@@ -93,9 +93,9 @@ class PlPlayerController {
|
||||
final RxBool _controlsLock = 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);
|
||||
late StreamSubscription<DataStatus> _dataListenerForVideoFit;
|
||||
@@ -241,12 +241,12 @@ class PlPlayerController {
|
||||
RxBool get isFullScreen => _isFullScreen;
|
||||
|
||||
/// 全屏方向
|
||||
RxString get direction => _direction;
|
||||
bool get isVertical => _isVertical;
|
||||
|
||||
RxInt get playerCount => _playerCount;
|
||||
|
||||
///
|
||||
RxString get videoType => _videoType;
|
||||
bool get isLive => _isLive;
|
||||
|
||||
/// 弹幕开关
|
||||
RxBool enableShowDanmaku = Pref.enableShowDanmaku.obs;
|
||||
@@ -467,7 +467,8 @@ class PlPlayerController {
|
||||
Box video = GStorage.video;
|
||||
|
||||
// 添加一个私有构造函数
|
||||
PlPlayerController._() {
|
||||
PlPlayerController._({bool isLive = false}) {
|
||||
_isLive = isLive;
|
||||
if (!Accounts.get(AccountType.heartbeat).isLogin || Pref.historyPause) {
|
||||
enableHeart = false;
|
||||
}
|
||||
@@ -492,13 +493,10 @@ class PlPlayerController {
|
||||
}
|
||||
|
||||
// 获取实例 传参
|
||||
static PlPlayerController getInstance({
|
||||
String videoType = 'archive',
|
||||
}) {
|
||||
static PlPlayerController getInstance({bool isLive = false}) {
|
||||
// 如果实例尚未创建,则创建一个新实例
|
||||
_instance ??= PlPlayerController._();
|
||||
_instance ??= PlPlayerController._(isLive: isLive);
|
||||
_instance!._playerCount.value += 1;
|
||||
_videoType.value = videoType;
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@@ -520,7 +518,7 @@ class PlPlayerController {
|
||||
int? height,
|
||||
Duration? duration,
|
||||
// 方向
|
||||
String? direction,
|
||||
bool? isVertical,
|
||||
// 记录历史记录
|
||||
String bvid = '',
|
||||
int cid = 0,
|
||||
@@ -544,7 +542,7 @@ class PlPlayerController {
|
||||
// 初始化数据加载状态
|
||||
dataStatus.status.value = DataStatus.loading;
|
||||
// 初始化全屏方向
|
||||
_direction.value = direction ?? 'horizontal';
|
||||
_isVertical = isVertical ?? false;
|
||||
_bvid = bvid;
|
||||
_cid = cid;
|
||||
_epid = epid;
|
||||
@@ -697,12 +695,8 @@ class PlPlayerController {
|
||||
configuration: PlayerConfiguration(
|
||||
// 默认缓冲 4M 大小
|
||||
bufferSize: Pref.expandBuffer
|
||||
? (videoType.value == 'live'
|
||||
? 64 * 1024 * 1024
|
||||
: 32 * 1024 * 1024)
|
||||
: (videoType.value == 'live'
|
||||
? 16 * 1024 * 1024
|
||||
: 4 * 1024 * 1024),
|
||||
? (isLive ? 64 * 1024 * 1024 : 32 * 1024 * 1024)
|
||||
: (isLive ? 16 * 1024 * 1024 : 4 * 1024 * 1024),
|
||||
),
|
||||
);
|
||||
var pp = player.platform as NativePlayer;
|
||||
@@ -833,7 +827,7 @@ class PlPlayerController {
|
||||
Future<void> _initializePlayer() async {
|
||||
if (_instance == null) return;
|
||||
// 设置倍速
|
||||
if (videoType.value == 'live') {
|
||||
if (isLive) {
|
||||
await setPlaybackSpeed(1.0);
|
||||
} else {
|
||||
if (_videoPlayerController?.state.rate != _playbackSpeed.value) {
|
||||
@@ -891,7 +885,7 @@ class PlPlayerController {
|
||||
videoPlayerServiceHandler.onStatusChange(
|
||||
playerStatus.status.value,
|
||||
isBuffering.value,
|
||||
videoType.value == 'live',
|
||||
isLive,
|
||||
);
|
||||
|
||||
/// 触发回调事件
|
||||
@@ -941,12 +935,12 @@ class PlPlayerController {
|
||||
videoPlayerServiceHandler.onStatusChange(
|
||||
playerStatus.status.value,
|
||||
event,
|
||||
videoType.value == 'live',
|
||||
isLive,
|
||||
);
|
||||
}),
|
||||
videoPlayerController!.stream.error.listen((String event) {
|
||||
// 直播的错误提示没有参考价值,均不予显示
|
||||
if (videoType.value == 'live') return;
|
||||
if (isLive) return;
|
||||
if (event.startsWith("Failed to open https://") ||
|
||||
event.startsWith("Can not open external file https://") ||
|
||||
//tcp: ffurl_read returned 0xdfb9b0bb
|
||||
@@ -957,11 +951,12 @@ class PlPlayerController {
|
||||
const Duration(milliseconds: 10000),
|
||||
() {
|
||||
Future.delayed(const Duration(milliseconds: 3000), () async {
|
||||
if (kDebugMode) {
|
||||
debugPrint("isBuffering.value: ${isBuffering.value}");
|
||||
}
|
||||
if (kDebugMode)
|
||||
debugPrint("_buffered.value: ${_buffered.value}");
|
||||
// if (kDebugMode) {
|
||||
// debugPrint("isBuffering.value: ${isBuffering.value}");
|
||||
// }
|
||||
// if (kDebugMode) {
|
||||
// debugPrint("_buffered.value: ${_buffered.value}");
|
||||
// }
|
||||
if (isBuffering.value && _buffered.value == Duration.zero) {
|
||||
SmartDialog.showToast(
|
||||
'视频链接打开失败,重试中',
|
||||
@@ -998,7 +993,7 @@ class PlPlayerController {
|
||||
videoPlayerServiceHandler.onStatusChange(
|
||||
event,
|
||||
isBuffering.value,
|
||||
videoType.value == 'live',
|
||||
isLive,
|
||||
);
|
||||
}),
|
||||
onPositionChanged.listen((Duration event) {
|
||||
@@ -1286,7 +1281,7 @@ class PlPlayerController {
|
||||
});
|
||||
}
|
||||
// fill不应该在竖屏视频生效
|
||||
} else if (attr == BoxFit.fill && direction.value == 'vertical') {
|
||||
} else if (attr == BoxFit.fill && isVertical) {
|
||||
attr = BoxFit.contain;
|
||||
}
|
||||
_videoFit.value = attr;
|
||||
@@ -1312,7 +1307,7 @@ class PlPlayerController {
|
||||
|
||||
/// 设置长按倍速状态 live模式下禁用
|
||||
Future<void> setLongPressStatus(bool val) async {
|
||||
if (videoType.value == 'live') {
|
||||
if (isLive) {
|
||||
return;
|
||||
}
|
||||
if (controlsLock.value) {
|
||||
@@ -1376,10 +1371,9 @@ class PlPlayerController {
|
||||
return;
|
||||
}
|
||||
if (mode == FullScreenMode.vertical ||
|
||||
(mode == FullScreenMode.auto && direction.value == 'vertical') ||
|
||||
(mode == FullScreenMode.auto && isVertical) ||
|
||||
(mode == FullScreenMode.ratio &&
|
||||
(Get.height / Get.width < 1.25 ||
|
||||
direction.value == 'vertical'))) {
|
||||
(Get.height / Get.width < 1.25 || isVertical))) {
|
||||
await verticalScreenForTwoSeconds();
|
||||
} else {
|
||||
await landScape();
|
||||
@@ -1445,7 +1439,7 @@ class PlPlayerController {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (videoType.value == 'live') {
|
||||
if (isLive) {
|
||||
return;
|
||||
}
|
||||
bool isComplete =
|
||||
@@ -1512,9 +1506,9 @@ class PlPlayerController {
|
||||
..put(SettingBoxKey.subtitleFontWeight, subtitleFontWeight);
|
||||
}
|
||||
|
||||
Future<void> dispose({String type = 'single'}) async {
|
||||
Future<void> dispose() async {
|
||||
// 每次减1,最后销毁
|
||||
if (type == 'single' && playerCount.value > 1) {
|
||||
if (playerCount.value > 1) {
|
||||
_playerCount.value -= 1;
|
||||
_heartDuration = 0;
|
||||
if (!Get.previousRoute.startsWith('/video')) {
|
||||
|
||||
1
lib/plugin/pl_player/models/double_tap_type.dart
Normal file
1
lib/plugin/pl_player/models/double_tap_type.dart
Normal file
@@ -0,0 +1 @@
|
||||
enum DoubleTapType { left, center, right }
|
||||
10
lib/plugin/pl_player/models/gesture_type.dart
Normal file
10
lib/plugin/pl_player/models/gesture_type.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
// ignore_for_file: constant_identifier_names
|
||||
|
||||
enum GestureType {
|
||||
left,
|
||||
center,
|
||||
right,
|
||||
horizontal,
|
||||
center_up,
|
||||
center_down,
|
||||
}
|
||||
@@ -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/models/bottom_control_type.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/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/widgets/app_bar_ani.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;
|
||||
|
||||
Offset _initialFocalPoint = Offset.zero;
|
||||
String? _gestureType;
|
||||
GestureType? _gestureType;
|
||||
//播放器放缩
|
||||
bool interacting = false;
|
||||
|
||||
@@ -138,20 +140,20 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
}
|
||||
|
||||
void doubleTapFuc(String type) {
|
||||
void doubleTapFuc(DoubleTapType type) {
|
||||
if (!plPlayerController.enableQuickDouble) {
|
||||
onDoubleTapCenter();
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case 'left':
|
||||
case DoubleTapType.left:
|
||||
// 双击左边区域 👈
|
||||
onDoubleTapSeekBackward();
|
||||
break;
|
||||
case 'center':
|
||||
case DoubleTapType.center:
|
||||
onDoubleTapCenter();
|
||||
break;
|
||||
case 'right':
|
||||
case DoubleTapType.right:
|
||||
// 双击右边区域 👈
|
||||
onDoubleTapSeekForward();
|
||||
break;
|
||||
@@ -770,7 +772,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
if (cumulativeDelta.distance < 1) return;
|
||||
if (cumulativeDelta.dx.abs() >
|
||||
3 * cumulativeDelta.dy.abs()) {
|
||||
_gestureType = 'horizontal';
|
||||
_gestureType = GestureType.horizontal;
|
||||
} else if (cumulativeDelta.dy.abs() >
|
||||
3 * cumulativeDelta.dx.abs()) {
|
||||
if (!plPlayerController.enableSlideVolumeBrightness &&
|
||||
@@ -787,19 +789,19 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
return;
|
||||
}
|
||||
// 左边区域
|
||||
_gestureType = 'left';
|
||||
_gestureType = GestureType.left;
|
||||
} else if (tapPosition < sectionWidth * 2) {
|
||||
if (!plPlayerController.enableSlideFS) {
|
||||
return;
|
||||
}
|
||||
// 全屏
|
||||
_gestureType = 'center';
|
||||
_gestureType = GestureType.center;
|
||||
} else {
|
||||
if (!plPlayerController.enableSlideVolumeBrightness) {
|
||||
return;
|
||||
}
|
||||
// 右边区域
|
||||
_gestureType = 'right';
|
||||
_gestureType = GestureType.right;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
@@ -808,9 +810,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
|
||||
Offset delta = details.focalPointDelta;
|
||||
|
||||
if (_gestureType == 'horizontal') {
|
||||
if (_gestureType == GestureType.horizontal) {
|
||||
// live模式下禁用
|
||||
if (plPlayerController.videoType.value == 'live') return;
|
||||
if (plPlayerController.isLive) return;
|
||||
|
||||
final int curSliderPosition =
|
||||
plPlayerController.sliderPosition.value.inMilliseconds;
|
||||
@@ -884,14 +886,14 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
} else if (_gestureType == 'left') {
|
||||
} else if (_gestureType == GestureType.left) {
|
||||
// 左边区域 👈
|
||||
final double level = maxHeight * 3;
|
||||
final double brightness =
|
||||
_brightnessValue.value - delta.dy / level;
|
||||
final double result = brightness.clamp(0.0, 1.0);
|
||||
setBrightness(result);
|
||||
} else if (_gestureType == 'center') {
|
||||
} else if (_gestureType == GestureType.center) {
|
||||
// 全屏
|
||||
const double threshold = 2.5; // 滑动阈值
|
||||
double cumulativeDy =
|
||||
@@ -902,7 +904,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
|
||||
if (cumulativeDy > threshold) {
|
||||
_gestureType = 'center_down';
|
||||
_gestureType = GestureType.center_down;
|
||||
if (isFullScreen ^
|
||||
plPlayerController.fullScreenGestureReverse) {
|
||||
fullScreenTrigger(
|
||||
@@ -911,7 +913,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
// if (kDebugMode) debugPrint('center_down:$cumulativeDy');
|
||||
} else if (cumulativeDy < -threshold) {
|
||||
_gestureType = 'center_up';
|
||||
_gestureType = GestureType.center_up;
|
||||
if (!isFullScreen ^
|
||||
plPlayerController.fullScreenGestureReverse) {
|
||||
fullScreenTrigger(
|
||||
@@ -920,7 +922,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
// if (kDebugMode) debugPrint('center_up:$cumulativeDy');
|
||||
}
|
||||
} else if (_gestureType == 'right') {
|
||||
} else if (_gestureType == GestureType.right) {
|
||||
// 右边区域
|
||||
final double level = maxHeight * 0.5;
|
||||
EasyThrottle.throttle(
|
||||
@@ -975,25 +977,25 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
final double tapPosition = details.localPosition.dx;
|
||||
final double sectionWidth = maxWidth / 3;
|
||||
late String gestureType;
|
||||
late GestureType gestureType;
|
||||
if (tapPosition < sectionWidth) {
|
||||
if (!plPlayerController.enableSlideVolumeBrightness) {
|
||||
return;
|
||||
}
|
||||
// 左边区域
|
||||
gestureType = 'left';
|
||||
gestureType = GestureType.left;
|
||||
} else if (tapPosition < sectionWidth * 2) {
|
||||
if (!plPlayerController.enableSlideFS) {
|
||||
return;
|
||||
}
|
||||
// 全屏
|
||||
gestureType = 'center';
|
||||
gestureType = GestureType.center;
|
||||
} else {
|
||||
if (!plPlayerController.enableSlideVolumeBrightness) {
|
||||
return;
|
||||
}
|
||||
// 右边区域
|
||||
gestureType = 'right';
|
||||
gestureType = GestureType.right;
|
||||
}
|
||||
|
||||
if (_gestureType != null && _gestureType != gestureType) {
|
||||
@@ -1001,14 +1003,14 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
_gestureType = gestureType;
|
||||
|
||||
if (_gestureType == 'left') {
|
||||
if (_gestureType == GestureType.left) {
|
||||
// 左边区域 👈
|
||||
final double level = maxHeight * 3;
|
||||
final double brightness =
|
||||
_brightnessValue.value - details.delta.dy / level;
|
||||
final double result = brightness.clamp(0.0, 1.0);
|
||||
setBrightness(result);
|
||||
} else if (_gestureType == 'center') {
|
||||
} else if (_gestureType == GestureType.center) {
|
||||
// 全屏
|
||||
const double threshold = 2.5; // 滑动阈值
|
||||
double cumulativeDy =
|
||||
@@ -1019,7 +1021,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
|
||||
if (cumulativeDy > threshold) {
|
||||
_gestureType = 'center_down';
|
||||
_gestureType = GestureType.center_down;
|
||||
if (isFullScreen ^
|
||||
plPlayerController.fullScreenGestureReverse) {
|
||||
fullScreenTrigger(
|
||||
@@ -1028,7 +1030,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
// if (kDebugMode) debugPrint('center_down:$cumulativeDy');
|
||||
} else if (cumulativeDy < -threshold) {
|
||||
_gestureType = 'center_up';
|
||||
_gestureType = GestureType.center_up;
|
||||
if (!isFullScreen ^
|
||||
plPlayerController.fullScreenGestureReverse) {
|
||||
fullScreenTrigger(
|
||||
@@ -1037,7 +1039,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
// if (kDebugMode) debugPrint('center_up:$cumulativeDy');
|
||||
}
|
||||
} else if (_gestureType == 'right') {
|
||||
} else if (_gestureType == GestureType.right) {
|
||||
// 右边区域
|
||||
final double level = maxHeight * 0.5;
|
||||
EasyThrottle.throttle(
|
||||
@@ -1065,19 +1067,19 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
if (plPlayerController.controlsLock.value) {
|
||||
return;
|
||||
}
|
||||
if (plPlayerController.videoType.value == 'live') {
|
||||
doubleTapFuc('center');
|
||||
if (plPlayerController.isLive) {
|
||||
doubleTapFuc(DoubleTapType.center);
|
||||
return;
|
||||
}
|
||||
final double tapPosition = details.localPosition.dx;
|
||||
final double sectionWidth = maxWidth / 4;
|
||||
String type = 'left';
|
||||
DoubleTapType type;
|
||||
if (tapPosition < sectionWidth) {
|
||||
type = 'left';
|
||||
type = DoubleTapType.left;
|
||||
} else if (tapPosition < sectionWidth * 3) {
|
||||
type = 'center';
|
||||
type = DoubleTapType.center;
|
||||
} else {
|
||||
type = 'right';
|
||||
type = DoubleTapType.right;
|
||||
}
|
||||
doubleTapFuc(type);
|
||||
},
|
||||
@@ -1426,7 +1428,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
}
|
||||
|
||||
if (plPlayerController.videoType.value == 'live') {
|
||||
if (plPlayerController.isLive) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
@@ -1551,9 +1553,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
SafeArea(
|
||||
child: Obx(
|
||||
() => Visibility(
|
||||
visible:
|
||||
plPlayerController.videoType.value != 'live' &&
|
||||
isFullScreen,
|
||||
visible: !plPlayerController.isLive && isFullScreen,
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FractionalTranslation(
|
||||
@@ -1895,7 +1895,7 @@ Widget buildSeekPreviewWidget(PlPlayerController plPlayerController) {
|
||||
try {
|
||||
double scale =
|
||||
plPlayerController.isFullScreen.value &&
|
||||
plPlayerController.direction.value == 'horizontal'
|
||||
!plPlayerController.isVertical
|
||||
? 4
|
||||
: 2.5;
|
||||
// offset
|
||||
|
||||
@@ -134,7 +134,7 @@ class SettingBoxKey {
|
||||
directExitOnBack = 'directExitOnBack',
|
||||
quickFavId = 'quickFavId';
|
||||
|
||||
static const String subtitlePreference = 'subtitlePreference',
|
||||
static const String subtitlePreferenceV2 = 'subtitlePreferenceV2',
|
||||
enableDragSubtitle = 'enableDragSubtitle',
|
||||
subtitlePaddingH = 'subtitlePaddingH',
|
||||
subtitlePaddingB = 'subtitlePaddingB',
|
||||
|
||||
@@ -186,9 +186,9 @@ class Pref {
|
||||
defaultValue: BtmProgressBehavior.alwaysShow.index,
|
||||
);
|
||||
|
||||
static String get subtitlePreference => _setting.get(
|
||||
SettingBoxKey.subtitlePreference,
|
||||
defaultValue: SubtitlePrefType.off.code,
|
||||
static int get subtitlePreferenceV2 => _setting.get(
|
||||
SettingBoxKey.subtitlePreferenceV2,
|
||||
defaultValue: SubtitlePrefType.off.index,
|
||||
);
|
||||
|
||||
static bool get useRelativeSlide =>
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:io' show Platform;
|
||||
import 'package:PiliPlus/build_config.dart';
|
||||
import 'package:PiliPlus/http/api.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/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
@@ -22,7 +23,7 @@ class Update {
|
||||
final res = await Request().get(
|
||||
Api.latestApp,
|
||||
options: Options(
|
||||
headers: {'user-agent': Request.headerUa()},
|
||||
headers: {'user-agent': UaType.mob.ua},
|
||||
extra: {'account': NoAccount()},
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user