mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-19 10:00:13 +08:00
committed by
GitHub
parent
0460030a2b
commit
ed2bd069ee
@@ -1,19 +1,54 @@
|
|||||||
// ignore_for_file: non_constant_identifier_names
|
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/pair.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_new/sponsor_block/segment_item.dart';
|
||||||
|
import 'package:PiliPlus/pages/sponsor_block/block_mixin.dart';
|
||||||
|
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||||
|
|
||||||
class SegmentModel {
|
class SegmentModel implements Comparable<SegmentModel> {
|
||||||
SegmentModel({
|
SegmentModel({
|
||||||
required this.UUID,
|
required this.uuid,
|
||||||
required this.segmentType,
|
required this.segmentType,
|
||||||
required this.segment,
|
required this.segment,
|
||||||
required this.skipType,
|
required this.skipType,
|
||||||
});
|
});
|
||||||
String UUID;
|
final String uuid;
|
||||||
SegmentType segmentType;
|
final SegmentType segmentType;
|
||||||
Pair<int, int> segment;
|
final (int, int) segment;
|
||||||
SkipType skipType;
|
final SkipType skipType;
|
||||||
late bool hasSkipped = false;
|
bool hasSkipped = false;
|
||||||
|
|
||||||
|
factory SegmentModel.fromItemModel(
|
||||||
|
SegmentItemModel model,
|
||||||
|
BlockConfigMixin? config,
|
||||||
|
) {
|
||||||
|
final segmentType = SegmentType.values.byName(model.category);
|
||||||
|
final segment = (model.segment[0], model.segment[1]);
|
||||||
|
SkipType skipType;
|
||||||
|
if (config != null) {
|
||||||
|
skipType = config.blockSettings[segmentType.index].second;
|
||||||
|
if (skipType != SkipType.showOnly) {
|
||||||
|
if (segment.isEq || segment.length < config.blockLimit) {
|
||||||
|
skipType = SkipType.showOnly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
skipType = Pref.pgcSkipType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SegmentModel(
|
||||||
|
uuid: model.uuid,
|
||||||
|
segmentType: segmentType,
|
||||||
|
segment: segment,
|
||||||
|
skipType: skipType,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int compareTo(SegmentModel other) => segment.$1.compareTo(other.segment.$1);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension IntRecordExt on (int, int) {
|
||||||
|
bool get isEq => $1 == $2;
|
||||||
|
int get length => $2 - $1;
|
||||||
|
bool contains(num other) => $1 <= other && other < $2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'dart:async' show StreamSubscription, Timer;
|
import 'dart:async' show StreamSubscription, Timer;
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/pair.dart';
|
|
||||||
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
|
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/http/sponsor_block.dart';
|
import 'package:PiliPlus/http/sponsor_block.dart';
|
||||||
@@ -21,15 +21,17 @@ import 'package:media_kit/media_kit.dart';
|
|||||||
mixin BlockConfigMixin {
|
mixin BlockConfigMixin {
|
||||||
late final pgcSkipType = Pref.pgcSkipType;
|
late final pgcSkipType = Pref.pgcSkipType;
|
||||||
late final enablePgcSkip = pgcSkipType != SkipType.disable;
|
late final enablePgcSkip = pgcSkipType != SkipType.disable;
|
||||||
late final bool enableSponsorBlock = Pref.enableSponsorBlock;
|
late final enableSponsorBlock = Pref.enableSponsorBlock;
|
||||||
late final bool enableBlock = enableSponsorBlock || enablePgcSkip;
|
late final enableBlock = enableSponsorBlock || enablePgcSkip;
|
||||||
late final double blockLimit = Pref.blockLimit;
|
late final blockColor = Pref.blockColor;
|
||||||
|
late final blockLimit = Pref.blockLimit;
|
||||||
late final blockSettings = Pref.blockSettings;
|
late final blockSettings = Pref.blockSettings;
|
||||||
late final List<Color> blockColor = Pref.blockColor;
|
late final enableList = blockSettings
|
||||||
late final Set<String> enableList = blockSettings
|
|
||||||
.where((item) => item.second != SkipType.disable)
|
.where((item) => item.second != SkipType.disable)
|
||||||
.map((item) => item.first.name)
|
.map((item) => item.first.name)
|
||||||
.toSet();
|
.toSet();
|
||||||
|
|
||||||
|
Color _getColor(SegmentType segment) => blockColor[segment.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin BlockMixin on GetxController {
|
mixin BlockMixin on GetxController {
|
||||||
@@ -37,14 +39,12 @@ mixin BlockMixin on GetxController {
|
|||||||
BlockConfigMixin get blockConfig;
|
BlockConfigMixin get blockConfig;
|
||||||
StreamSubscription<Duration>? _blockListener;
|
StreamSubscription<Duration>? _blockListener;
|
||||||
StreamSubscription<Duration>? get blockListener => _blockListener;
|
StreamSubscription<Duration>? get blockListener => _blockListener;
|
||||||
Color _getBlockColor(SegmentType segment) =>
|
|
||||||
blockConfig.blockColor[segment.index];
|
|
||||||
late final List<SegmentModel> _segmentList = <SegmentModel>[];
|
late final List<SegmentModel> _segmentList = <SegmentModel>[];
|
||||||
late final RxList<Segment> segmentProgressList = <Segment>[].obs;
|
late final RxList<Segment> segmentProgressList = <Segment>[].obs;
|
||||||
|
|
||||||
Timer? _skipTimer;
|
Timer? _skipTimer;
|
||||||
late final listKey = GlobalKey<AnimatedListState>();
|
late final listKey = GlobalKey<AnimatedListState>();
|
||||||
late final List listData = [];
|
late final List<Object> listData = [];
|
||||||
|
|
||||||
RxString? get videoLabel => null;
|
RxString? get videoLabel => null;
|
||||||
Player? get player;
|
Player? get player;
|
||||||
@@ -89,8 +89,7 @@ mixin BlockMixin on GetxController {
|
|||||||
// debugPrint(
|
// debugPrint(
|
||||||
// '${position.inSeconds},,${item.segment.first},,${item.segment.second},,${item.skipType.name},,${item.hasSkipped}');
|
// '${position.inSeconds},,${item.segment.first},,${item.segment.second},,${item.skipType.name},,${item.hasSkipped}');
|
||||||
// }
|
// }
|
||||||
if (msPos <= item.segment.first &&
|
if (msPos <= item.segment.$1 && item.segment.$1 <= msPos + 1000) {
|
||||||
item.segment.first <= msPos + 1000) {
|
|
||||||
switch (item.skipType) {
|
switch (item.skipType) {
|
||||||
case SkipType.alwaysSkip:
|
case SkipType.alwaysSkip:
|
||||||
onSkip(item, isSeek: false);
|
onSkip(item, isSeek: false);
|
||||||
@@ -118,7 +117,7 @@ mixin BlockMixin on GetxController {
|
|||||||
Future<void> handleSBData(List<SegmentItemModel> list) async {
|
Future<void> handleSBData(List<SegmentItemModel> list) async {
|
||||||
if (list.isNotEmpty) {
|
if (list.isNotEmpty) {
|
||||||
try {
|
try {
|
||||||
Future? future;
|
Future<void>? future;
|
||||||
final duration = list.first.videoDuration ?? timeLength!;
|
final duration = list.first.videoDuration ?? timeLength!;
|
||||||
// segmentList
|
// segmentList
|
||||||
_segmentList.addAll(
|
_segmentList.addAll(
|
||||||
@@ -130,41 +129,19 @@ mixin BlockMixin on GetxController {
|
|||||||
)
|
)
|
||||||
.map(
|
.map(
|
||||||
(item) {
|
(item) {
|
||||||
final segmentType = SegmentType.values.byName(item.category);
|
final segmentModel = SegmentModel.fromItemModel(
|
||||||
if (item.segment[0] == 0 && item.segment[1] == 0) {
|
item,
|
||||||
videoLabel?.value +=
|
isBlock ? blockConfig : null,
|
||||||
'${videoLabel!.value.isNotEmpty ? '/' : ''}${segmentType.title}';
|
|
||||||
}
|
|
||||||
SkipType skipType;
|
|
||||||
if (isBlock) {
|
|
||||||
skipType =
|
|
||||||
blockConfig.blockSettings[segmentType.index].second;
|
|
||||||
if (skipType != SkipType.showOnly) {
|
|
||||||
if (item.segment[1] == item.segment[0] ||
|
|
||||||
item.segment[1] - item.segment[0] <
|
|
||||||
blockConfig.blockLimit) {
|
|
||||||
skipType = SkipType.showOnly;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
skipType = blockConfig.pgcSkipType;
|
|
||||||
}
|
|
||||||
|
|
||||||
final segmentModel = SegmentModel(
|
|
||||||
UUID: item.uuid,
|
|
||||||
segmentType: segmentType,
|
|
||||||
segment: Pair(
|
|
||||||
first: item.segment[0],
|
|
||||||
second: item.segment[1],
|
|
||||||
),
|
|
||||||
skipType: skipType,
|
|
||||||
);
|
);
|
||||||
|
if (segmentModel.segment == const (0, 0)) {
|
||||||
|
videoLabel?.value +=
|
||||||
|
'${videoLabel!.value.isNotEmpty ? '/' : ''}${segmentModel.segmentType.title}';
|
||||||
|
}
|
||||||
|
|
||||||
if (_blockListener == null && autoPlay && player != null) {
|
if (_blockListener == null && autoPlay && player != null) {
|
||||||
final currPos = currPosInMilliseconds;
|
final currPos = currPosInMilliseconds;
|
||||||
|
|
||||||
if (currPos >= segmentModel.segment.first &&
|
if (segmentModel.segment.contains(currPos)) {
|
||||||
currPos < segmentModel.segment.second) {
|
|
||||||
_lastBlockPos = currPos;
|
_lastBlockPos = currPos;
|
||||||
|
|
||||||
switch (segmentModel.skipType) {
|
switch (segmentModel.skipType) {
|
||||||
@@ -182,7 +159,7 @@ mixin BlockMixin on GetxController {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
}, orElse: () => false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SkipType.skipManually:
|
case SkipType.skipManually:
|
||||||
@@ -202,12 +179,12 @@ mixin BlockMixin on GetxController {
|
|||||||
// _segmentProgressList
|
// _segmentProgressList
|
||||||
segmentProgressList.addAll(
|
segmentProgressList.addAll(
|
||||||
_segmentList.map((e) {
|
_segmentList.map((e) {
|
||||||
double start = (e.segment.first / duration).clamp(0.0, 1.0);
|
double start = (e.segment.$1 / duration).clamp(0.0, 1.0);
|
||||||
double end = (e.segment.second / duration).clamp(0.0, 1.0);
|
double end = (e.segment.$2 / duration).clamp(0.0, 1.0);
|
||||||
return Segment(
|
return Segment(
|
||||||
start: start,
|
start: start,
|
||||||
end: end,
|
end: end,
|
||||||
color: _getBlockColor(e.segmentType),
|
color: blockConfig._getColor(e.segmentType),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -222,7 +199,7 @@ mixin BlockMixin on GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onAddItem(dynamic item) {
|
void onAddItem(Object item) {
|
||||||
if (listData.contains(item)) return;
|
if (listData.contains(item)) return;
|
||||||
listData.insert(0, item);
|
listData.insert(0, item);
|
||||||
listKey.currentState?.insertItem(0);
|
listKey.currentState?.insertItem(0);
|
||||||
@@ -233,7 +210,7 @@ mixin BlockMixin on GetxController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void onRemoveItem(int index, item) {
|
void onRemoveItem(int index, Object item) {
|
||||||
EasyThrottle.throttle(
|
EasyThrottle.throttle(
|
||||||
'onRemoveItem',
|
'onRemoveItem',
|
||||||
const Duration(milliseconds: 500),
|
const Duration(milliseconds: 500),
|
||||||
@@ -252,7 +229,7 @@ mixin BlockMixin on GetxController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildItem(dynamic item, Animation<double> animation) =>
|
Widget buildItem(Object item, Animation<double> animation) =>
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
|
|
||||||
void _stopSkipTimer() {
|
void _stopSkipTimer() {
|
||||||
@@ -264,6 +241,15 @@ mixin BlockMixin on GetxController {
|
|||||||
|
|
||||||
Future<void>? seekTo(Duration duration, {required bool isSeek});
|
Future<void>? seekTo(Duration duration, {required bool isSeek});
|
||||||
|
|
||||||
|
void _skipToast(SegmentModel item) {
|
||||||
|
if (autoPlay && Pref.blockToast) {
|
||||||
|
_showBlockToast('已跳过${item.segmentType.shortTitle}片段');
|
||||||
|
}
|
||||||
|
if (isBlock && Pref.blockTrack) {
|
||||||
|
SponsorBlock.viewedVideoSponsorTime(item.uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> onSkip(
|
Future<void> onSkip(
|
||||||
SegmentModel item, {
|
SegmentModel item, {
|
||||||
bool isSkip = true,
|
bool isSkip = true,
|
||||||
@@ -271,16 +257,11 @@ mixin BlockMixin on GetxController {
|
|||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
await seekTo(
|
await seekTo(
|
||||||
Duration(milliseconds: item.segment.second),
|
Duration(milliseconds: item.segment.$2),
|
||||||
isSeek: isSeek,
|
isSeek: isSeek,
|
||||||
);
|
);
|
||||||
if (isSkip) {
|
if (isSkip) {
|
||||||
if (autoPlay && Pref.blockToast) {
|
_skipToast(item);
|
||||||
_showBlockToast('已跳过${item.segmentType.shortTitle}片段');
|
|
||||||
}
|
|
||||||
if (isBlock && Pref.blockTrack) {
|
|
||||||
SponsorBlock.viewedVideoSponsorTime(item.UUID);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
_showBlockToast('已跳至${item.segmentType.shortTitle}');
|
_showBlockToast('已跳至${item.segmentType.shortTitle}');
|
||||||
}
|
}
|
||||||
@@ -316,7 +297,7 @@ mixin BlockMixin on GetxController {
|
|||||||
title: const Text('赞成票', style: TextStyle(fontSize: 14)),
|
title: const Text('赞成票', style: TextStyle(fontSize: 14)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
_doVote(segment.UUID, 1);
|
_doVote(segment.uuid, 1);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@@ -324,7 +305,7 @@ mixin BlockMixin on GetxController {
|
|||||||
title: const Text('反对票', style: TextStyle(fontSize: 14)),
|
title: const Text('反对票', style: TextStyle(fontSize: 14)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
_doVote(segment.UUID, 0);
|
_doVote(segment.uuid, 0);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@@ -363,7 +344,7 @@ mixin BlockMixin on GetxController {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
SponsorBlock.voteOnSponsorTime(
|
SponsorBlock.voteOnSponsorTime(
|
||||||
uuid: segment.UUID,
|
uuid: segment.uuid,
|
||||||
category: item,
|
category: item,
|
||||||
).then((i) {
|
).then((i) {
|
||||||
SmartDialog.showToast(
|
SmartDialog.showToast(
|
||||||
@@ -381,7 +362,7 @@ mixin BlockMixin on GetxController {
|
|||||||
width: 10,
|
width: 10,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: _getBlockColor(item),
|
color: blockConfig._getColor(item),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: const TextStyle(fontSize: 14, height: 1),
|
style: const TextStyle(fontSize: 14, height: 1),
|
||||||
@@ -431,7 +412,7 @@ mixin BlockMixin on GetxController {
|
|||||||
width: 10,
|
width: 10,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: _getBlockColor(item.segmentType),
|
color: blockConfig._getColor(item.segmentType),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: const TextStyle(fontSize: 14, height: 1),
|
style: const TextStyle(fontSize: 14, height: 1),
|
||||||
@@ -445,7 +426,7 @@ mixin BlockMixin on GetxController {
|
|||||||
),
|
),
|
||||||
contentPadding: const EdgeInsets.only(left: 16, right: 8),
|
contentPadding: const EdgeInsets.only(left: 16, right: 8),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'${DurationUtils.formatDuration(item.segment.first / 1000)} 至 ${DurationUtils.formatDuration(item.segment.second / 1000)}',
|
'${DurationUtils.formatDuration(item.segment.$1 / 1000)} 至 ${DurationUtils.formatDuration(item.segment.$2 / 1000)}',
|
||||||
style: const TextStyle(fontSize: 13),
|
style: const TextStyle(fontSize: 13),
|
||||||
),
|
),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
@@ -455,7 +436,7 @@ mixin BlockMixin on GetxController {
|
|||||||
item.skipType.label,
|
item.skipType.label,
|
||||||
style: const TextStyle(fontSize: 13),
|
style: const TextStyle(fontSize: 13),
|
||||||
),
|
),
|
||||||
if (item.segment.second != 0)
|
if (item.segment.$2 != 0)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 36,
|
width: 36,
|
||||||
height: 36,
|
height: 36,
|
||||||
@@ -514,6 +495,30 @@ mixin BlockMixin on GetxController {
|
|||||||
segmentProgressList.clear();
|
segmentProgressList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Duration? getFirstSegment([int pos = 0]) {
|
||||||
|
for (var i in _segmentList..sort()) {
|
||||||
|
final (start, end) = i.segment;
|
||||||
|
if (start == end) {
|
||||||
|
continue;
|
||||||
|
} else if (start - pos < 100) {
|
||||||
|
if (switch (i.skipType) {
|
||||||
|
.alwaysSkip => true,
|
||||||
|
.skipOnce => !i.hasSkipped,
|
||||||
|
_ => false,
|
||||||
|
}) {
|
||||||
|
_skipToast(i);
|
||||||
|
pos = math.max(pos, i.segment.$2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pos != 0) {
|
||||||
|
return Duration(milliseconds: pos);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
_stopSkipTimer();
|
_stopSkipTimer();
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
|
|||||||
final _url = 'https://github.com/hanydd/BilibiliSponsorBlock';
|
final _url = 'https://github.com/hanydd/BilibiliSponsorBlock';
|
||||||
final _textController = TextEditingController();
|
final _textController = TextEditingController();
|
||||||
double _blockLimit = Pref.blockLimit;
|
double _blockLimit = Pref.blockLimit;
|
||||||
final List<Pair<SegmentType, SkipType>> _blockSettings = Pref.blockSettings;
|
final _blockSettings = Pref.blockSettings;
|
||||||
final List<Color> _blockColor = Pref.blockColor;
|
final List<Color> _blockColor = Pref.blockColor;
|
||||||
String _userId = Pref.blockUserID;
|
String _userId = Pref.blockUserID;
|
||||||
bool _blockToast = Pref.blockToast;
|
bool _blockToast = Pref.blockToast;
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ class VideoDetailController extends GetxController
|
|||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildItem(dynamic item, Animation<double> animation) {
|
Widget buildItem(Object item, Animation<double> animation) {
|
||||||
final theme = Get.theme;
|
final theme = Get.theme;
|
||||||
return Align(
|
return Align(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
@@ -536,7 +536,7 @@ class VideoDetailController extends GetxController
|
|||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
text: item is SegmentModel
|
text: item is SegmentModel
|
||||||
? '跳过: ${item.segmentType.shortTitle}'
|
? '跳过: ${item.segmentType.shortTitle}'
|
||||||
: '上次看到第${item + 1}P,点击跳转',
|
: '上次看到第${(item as int) + 1}P,点击跳转',
|
||||||
onTap: (_) {
|
onTap: (_) {
|
||||||
if (item is int) {
|
if (item is int) {
|
||||||
try {
|
try {
|
||||||
@@ -679,6 +679,10 @@ class VideoDetailController extends GetxController
|
|||||||
Volume? volume,
|
Volume? volume,
|
||||||
}) async {
|
}) async {
|
||||||
final onlyPlayAudio = plPlayerController.onlyPlayAudio.value;
|
final onlyPlayAudio = plPlayerController.onlyPlayAudio.value;
|
||||||
|
Duration? seek = seekToTime ?? defaultST ?? playedTime;
|
||||||
|
if (seek == null || seek == Duration.zero) {
|
||||||
|
seek = getFirstSegment();
|
||||||
|
}
|
||||||
await plPlayerController.setDataSource(
|
await plPlayerController.setDataSource(
|
||||||
DataSource(
|
DataSource(
|
||||||
videoSource: isFileSource
|
videoSource: isFileSource
|
||||||
@@ -695,7 +699,7 @@ class VideoDetailController extends GetxController
|
|||||||
'referer': HttpString.baseUrl,
|
'referer': HttpString.baseUrl,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
seekTo: seekToTime ?? defaultST ?? playedTime,
|
seekTo: seek,
|
||||||
duration:
|
duration:
|
||||||
duration ??
|
duration ??
|
||||||
(data.timeLength == null
|
(data.timeLength == null
|
||||||
@@ -803,16 +807,11 @@ class VideoDetailController extends GetxController
|
|||||||
|
|
||||||
volume = data.volume;
|
volume = data.volume;
|
||||||
|
|
||||||
final progress = args['progress'];
|
final progress = args.remove('progress');
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
this.defaultST = Duration(milliseconds: progress);
|
this.defaultST = Duration(milliseconds: progress);
|
||||||
args['progress'] = null;
|
} else if (defaultST == null && data.lastPlayTime != null) {
|
||||||
} else {
|
this.defaultST = Duration(milliseconds: data.lastPlayTime!);
|
||||||
this.defaultST =
|
|
||||||
defaultST ??
|
|
||||||
(data.lastPlayTime == null
|
|
||||||
? Duration.zero
|
|
||||||
: Duration(milliseconds: data.lastPlayTime!));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isUgc && !fromReset && plPlayerController.enablePgcSkip) {
|
if (!isUgc && !fromReset && plPlayerController.enablePgcSkip) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||||
@@ -473,14 +474,14 @@ class _PostPanelState extends State<PostPanel>
|
|||||||
await videoCtr.play();
|
await videoCtr.play();
|
||||||
}
|
}
|
||||||
final delay = start - seek;
|
final delay = start - seek;
|
||||||
if (delay > 0) {
|
Future<void> seekTo() => videoCtr.seek(
|
||||||
await Future.delayed(Duration(milliseconds: delay));
|
Duration(milliseconds: (item.segment.second * 1000).round()),
|
||||||
}
|
|
||||||
videoCtr.seek(
|
|
||||||
Duration(
|
|
||||||
milliseconds: (item.segment.second * 1000).round(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
if (delay > 0) {
|
||||||
|
Timer(Duration(milliseconds: delay), seekTo);
|
||||||
|
} else {
|
||||||
|
seekTo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import 'package:PiliPlus/utils/storage_key.dart';
|
|||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:crypto/crypto.dart';
|
import 'package:crypto/crypto.dart';
|
||||||
import 'package:flex_seed_scheme/flex_seed_scheme.dart' show FlexSchemeVariant;
|
import 'package:flex_seed_scheme/flex_seed_scheme.dart' show FlexSchemeVariant;
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
@@ -324,7 +325,7 @@ abstract final class Pref {
|
|||||||
);
|
);
|
||||||
|
|
||||||
static bool get blockTrack =>
|
static bool get blockTrack =>
|
||||||
_setting.get(SettingBoxKey.blockTrack, defaultValue: true);
|
_setting.get(SettingBoxKey.blockTrack, defaultValue: !kDebugMode);
|
||||||
|
|
||||||
static bool get checkDynamic =>
|
static bool get checkDynamic =>
|
||||||
_setting.get(SettingBoxKey.checkDynamic, defaultValue: true);
|
_setting.get(SettingBoxKey.checkDynamic, defaultValue: true);
|
||||||
|
|||||||
Reference in New Issue
Block a user