mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-16 23:26:14 +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");
|
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,
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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
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/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,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
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 {
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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']) {
|
||||||
|
|||||||
@@ -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: '收藏',
|
||||||
|
|||||||
@@ -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']) {
|
||||||
|
|||||||
@@ -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: '收藏',
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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')) {
|
||||||
|
|||||||
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/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
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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 =>
|
||||||
|
|||||||
@@ -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()},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user