Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-07-23 16:47:11 +08:00
parent 148e0872b4
commit 418a1e8d39
821 changed files with 29467 additions and 25520 deletions

View File

@@ -151,8 +151,8 @@ class VideoDetailController extends GetxController
void setVideoHeight() {
String direction = firstVideo.width != null && firstVideo.height != null
? firstVideo.width! > firstVideo.height!
? 'horizontal'
: 'vertical'
? 'horizontal'
: 'vertical'
: 'horizontal';
if (!scrollCtr.hasClients) {
videoHeight = direction == 'vertical' ? maxVideoHeight : minVideoHeight;
@@ -161,19 +161,22 @@ class VideoDetailController extends GetxController
}
if (this.direction.value != direction) {
this.direction.value = direction;
double videoHeight =
direction == 'vertical' ? maxVideoHeight : minVideoHeight;
double videoHeight = direction == 'vertical'
? maxVideoHeight
: minVideoHeight;
if (this.videoHeight != videoHeight) {
if (videoHeight > this.videoHeight) {
// current minVideoHeight
isExpanding = true;
animationController.forward(
from: (minVideoHeight - scrollCtr.offset) / maxVideoHeight);
from: (minVideoHeight - scrollCtr.offset) / maxVideoHeight,
);
this.videoHeight = maxVideoHeight;
} else {
// current maxVideoHeight
final currentHeight =
(maxVideoHeight - scrollCtr.offset).toPrecision(2);
final currentHeight = (maxVideoHeight - scrollCtr.offset).toPrecision(
2,
);
double minVideoHeightPrecise = minVideoHeight.toPrecision(2);
if (currentHeight == minVideoHeightPrecise) {
isExpanding = true;
@@ -188,7 +191,8 @@ class VideoDetailController extends GetxController
// collapse
isCollapsing = true;
animationController.forward(
from: scrollCtr.offset / (maxVideoHeight - minVideoHeight));
from: scrollCtr.offset / (maxVideoHeight - minVideoHeight),
);
this.videoHeight = minVideoHeight;
}
}
@@ -231,7 +235,7 @@ class VideoDetailController extends GetxController
imageStatus = false;
}
// 页面来源 稍后再看 收藏夹
// 页面来源 稍后再看 收藏夹
String sourceType = 'normal';
late bool _mediaDesc = false;
late final RxList<MediaListItemModel> mediaList = <MediaListItemModel>[].obs;
@@ -239,11 +243,11 @@ class VideoDetailController extends GetxController
bool get isPlayAll =>
const ['watchLater', 'fav', 'archive', 'playlist'].contains(sourceType);
int get _mediaType => switch (sourceType) {
'archive' => 1,
'watchLater' => 2,
'fav' || 'playlist' => 3,
_ => -1,
};
'archive' => 1,
'watchLater' => 2,
'fav' || 'playlist' => 3,
_ => -1,
};
late dynamic epId = Get.parameters['epId'];
late dynamic seasonId = Get.parameters['seasonId'];
@@ -282,7 +286,10 @@ class VideoDetailController extends GetxController
bool defaultShowComment = Pref.defaultShowComment;
tabCtr = TabController(
length: 2, vsync: this, initialIndex: defaultShowComment ? 1 : 0);
length: 2,
vsync: this,
initialIndex: defaultShowComment ? 1 : 0,
);
autoPlay.value = Pref.autoPlayEnable;
if (autoPlay.value) isShowCover.value = false;
danmakuCid.value = cid.value;
@@ -310,25 +317,25 @@ class VideoDetailController extends GetxController
oid: isReverse
? null
: mediaList.isEmpty
? Get.arguments['isContinuePlaying'] == true
? Get.arguments['oid']
: null
: isLoadPrevious
? mediaList.first.aid
: mediaList.last.aid,
? Get.arguments['isContinuePlaying'] == true
? Get.arguments['oid']
: null
: isLoadPrevious
? mediaList.first.aid
: mediaList.last.aid,
otype: isReverse
? null
: mediaList.isEmpty
? null
: isLoadPrevious
? mediaList.first.type
: mediaList.last.type,
? null
: isLoadPrevious
? mediaList.first.type
: mediaList.last.type,
desc: _mediaDesc,
sortField: Get.arguments['sortField'] ?? 1,
withCurrent:
mediaList.isEmpty && Get.arguments['isContinuePlaying'] == true
? true
: false,
? true
: false,
);
if (res['status']) {
MediaListData data = res['data'];
@@ -338,8 +345,9 @@ class VideoDetailController extends GetxController
try {
for (var item in mediaList) {
if (item.cid != null) {
Get.find<VideoIntroController>(tag: heroTag)
.changeSeasonOrbangu(
Get.find<VideoIntroController>(
tag: heroTag,
).changeSeasonOrbangu(
null,
item.bvid,
item.cid,
@@ -365,51 +373,53 @@ class VideoDetailController extends GetxController
void showMediaListPanel(BuildContext context) {
if (mediaList.isNotEmpty) {
Widget panel() => MediaListPanel(
mediaList: mediaList,
changeMediaList: (bvid, cid, aid, cover) {
try {
Get.find<VideoIntroController>(tag: heroTag)
.changeSeasonOrbangu(null, bvid, cid, aid, cover);
} catch (_) {}
},
panelTitle: watchLaterTitle,
getBvId: () => bvid,
count: Get.arguments['count'],
loadMoreMedia: getMediaList,
desc: _mediaDesc,
onReverse: () {
_mediaDesc = !_mediaDesc;
getMediaList(isReverse: true);
},
loadPrevious: Get.arguments['isContinuePlaying'] == true
? () => getMediaList(isLoadPrevious: true)
: null,
onDelete: sourceType == 'watchLater' ||
(sourceType == 'fav' && Get.arguments?['isOwner'] == true)
? (item, index) async {
if (sourceType == 'watchLater') {
var res = await UserHttp.toViewDel(
aids: [item.aid],
);
if (res['status']) {
mediaList.removeAt(index);
}
SmartDialog.showToast(res['msg']);
} else {
var res = await FavHttp.delFav(
ids: ['${item.aid}:${item.type}'],
delIds: '${Get.arguments?['mediaId']}',
);
if (res['status']) {
mediaList.removeAt(index);
SmartDialog.showToast('取消收藏');
} else {
SmartDialog.showToast(res['msg']);
}
}
mediaList: mediaList,
changeMediaList: (bvid, cid, aid, cover) {
try {
Get.find<VideoIntroController>(
tag: heroTag,
).changeSeasonOrbangu(null, bvid, cid, aid, cover);
} catch (_) {}
},
panelTitle: watchLaterTitle,
getBvId: () => bvid,
count: Get.arguments['count'],
loadMoreMedia: getMediaList,
desc: _mediaDesc,
onReverse: () {
_mediaDesc = !_mediaDesc;
getMediaList(isReverse: true);
},
loadPrevious: Get.arguments['isContinuePlaying'] == true
? () => getMediaList(isLoadPrevious: true)
: null,
onDelete:
sourceType == 'watchLater' ||
(sourceType == 'fav' && Get.arguments?['isOwner'] == true)
? (item, index) async {
if (sourceType == 'watchLater') {
var res = await UserHttp.toViewDel(
aids: [item.aid],
);
if (res['status']) {
mediaList.removeAt(index);
}
: null,
);
SmartDialog.showToast(res['msg']);
} else {
var res = await FavHttp.delFav(
ids: ['${item.aid}:${item.type}'],
delIds: '${Get.arguments?['mediaId']}',
);
if (res['status']) {
mediaList.removeAt(index);
SmartDialog.showToast('取消收藏');
} else {
SmartDialog.showToast(res['msg']);
}
}
}
: null,
);
if (plPlayerController.isFullScreen.value || showVideoSheet) {
PageUtils.showVideoBottomSheet(
context,
@@ -451,16 +461,18 @@ class VideoDetailController extends GetxController
late final List listData = [];
void _vote(String uuid, int type) {
Request().post(
'$blockServer/api/voteOnSponsorTime',
queryParameters: {
'UUID': uuid,
'userID': Pref.blockUserID,
'type': type,
},
).then((res) {
SmartDialog.showToast(res.statusCode == 200 ? '投票成功' : '投票失败');
});
Request()
.post(
'$blockServer/api/voteOnSponsorTime',
queryParameters: {
'UUID': uuid,
'userID': Pref.blockUserID,
'type': type,
},
)
.then((res) {
SmartDialog.showToast(res.statusCode == 200 ? '投票成功' : '投票失败');
});
}
void _showCategoryDialog(BuildContext context, SegmentModel segment) {
@@ -473,45 +485,50 @@ class VideoDetailController extends GetxController
child: Column(
mainAxisSize: MainAxisSize.min,
children: SegmentType.values
.map((item) => ListTile(
dense: true,
onTap: () {
Get.back();
Request().post(
'$blockServer/api/voteOnSponsorTime',
queryParameters: {
'UUID': segment.UUID,
'userID': Pref.blockUserID,
'category': item.name,
},
).then((res) {
SmartDialog.showToast(
'类别更改${res.statusCode == 200 ? '成功' : '失败'}');
});
},
title: Text.rich(
TextSpan(
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Container(
height: 10,
width: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _getColor(item),
),
.map(
(item) => ListTile(
dense: true,
onTap: () {
Get.back();
Request()
.post(
'$blockServer/api/voteOnSponsorTime',
queryParameters: {
'UUID': segment.UUID,
'userID': Pref.blockUserID,
'category': item.name,
},
)
.then((res) {
SmartDialog.showToast(
'类别更改${res.statusCode == 200 ? '成功' : '失败'}',
);
});
},
title: Text.rich(
TextSpan(
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Container(
height: 10,
width: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _getColor(item),
),
style: const TextStyle(fontSize: 14, height: 1),
),
TextSpan(
text: ' ${item.title}',
style: const TextStyle(fontSize: 14, height: 1),
),
],
),
style: const TextStyle(fontSize: 14, height: 1),
),
TextSpan(
text: ' ${item.title}',
style: const TextStyle(fontSize: 14, height: 1),
),
],
),
))
),
),
)
.toList(),
),
),
@@ -644,10 +661,9 @@ class VideoDetailController extends GetxController
? Icons.my_location
: MdiIcons.debugStepOver,
size: 18,
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.7),
color: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.7),
),
),
)
@@ -697,71 +713,89 @@ class VideoDetailController extends GetxController
try {
final duration = list.first.videoDuration ?? data.timeLength!;
// segmentList
segmentList.addAll(list
.where((item) =>
plPlayerController.enableList.contains(item.category) &&
item.segment[1] >= item.segment[0])
.map(
(item) {
final segmentType = SegmentType.values.byName(item.category);
if (item.segment[0] == 0 && item.segment[1] == 0) {
videoLabel.value +=
'${videoLabel.value.isNotEmpty ? '/' : ''}${segmentType.title}';
}
var skipType =
plPlayerController.blockSettings[segmentType.index].second;
if (skipType != SkipType.showOnly) {
if (item.segment[1] == item.segment[0] ||
item.segment[1] - item.segment[0] <
plPlayerController.blockLimit) {
skipType = SkipType.showOnly;
}
}
segmentList.addAll(
list
.where(
(item) =>
plPlayerController.enableList.contains(item.category) &&
item.segment[1] >= item.segment[0],
)
.map(
(item) {
final segmentType = SegmentType.values.byName(item.category);
if (item.segment[0] == 0 && item.segment[1] == 0) {
videoLabel.value +=
'${videoLabel.value.isNotEmpty ? '/' : ''}${segmentType.title}';
}
var skipType = plPlayerController
.blockSettings[segmentType.index]
.second;
if (skipType != SkipType.showOnly) {
if (item.segment[1] == item.segment[0] ||
item.segment[1] - item.segment[0] <
plPlayerController.blockLimit) {
skipType = SkipType.showOnly;
}
}
final segmentModel = SegmentModel(
UUID: item.uuid,
segmentType: segmentType,
segment: Pair(
first: item.segment[0],
second: item.segment[1],
),
skipType: skipType,
);
final segmentModel = SegmentModel(
UUID: item.uuid,
segmentType: segmentType,
segment: Pair(
first: item.segment[0],
second: item.segment[1],
),
skipType: skipType,
);
if (positionSubscription == null &&
!isShowCover.value &&
plPlayerController.videoPlayerController != null) {
final currPost = plPlayerController.position.value.inMilliseconds;
if (currPost >= segmentModel.segment.first &&
currPost < segmentModel.segment.second) {
_lastPos = currPost;
if (segmentModel.skipType == SkipType.alwaysSkip) {
plPlayerController.videoPlayerController!.stream.buffer.first
.whenComplete(() {
onSkip(segmentModel);
});
} else if (segmentModel.skipType == SkipType.skipOnce) {
segmentModel.hasSkipped = true;
plPlayerController.videoPlayerController!.stream.buffer.first
.whenComplete(() {
onSkip(segmentModel);
});
} else if (segmentModel.skipType == SkipType.skipManually) {
onAddItem(segmentModel);
}
}
}
if (positionSubscription == null &&
!isShowCover.value &&
plPlayerController.videoPlayerController != null) {
final currPost =
plPlayerController.position.value.inMilliseconds;
if (currPost >= segmentModel.segment.first &&
currPost < segmentModel.segment.second) {
_lastPos = currPost;
if (segmentModel.skipType == SkipType.alwaysSkip) {
plPlayerController
.videoPlayerController!
.stream
.buffer
.first
.whenComplete(() {
onSkip(segmentModel);
});
} else if (segmentModel.skipType == SkipType.skipOnce) {
segmentModel.hasSkipped = true;
plPlayerController
.videoPlayerController!
.stream
.buffer
.first
.whenComplete(() {
onSkip(segmentModel);
});
} else if (segmentModel.skipType ==
SkipType.skipManually) {
onAddItem(segmentModel);
}
}
}
return segmentModel;
},
).toList());
return segmentModel;
},
)
.toList(),
);
// _segmentProgressList
(segmentProgressList ??= <Segment>[]).addAll(segmentList.map((e) {
double start = (e.segment.first / duration).clamp(0.0, 1.0);
double end = (e.segment.second / duration).clamp(0.0, 1.0);
return Segment(start, end, _getColor(e.segmentType));
}).toList());
(segmentProgressList ??= <Segment>[]).addAll(
segmentList.map((e) {
double start = (e.segment.first / duration).clamp(0.0, 1.0);
double end = (e.segment.second / duration).clamp(0.0, 1.0);
return Segment(start, end, _getColor(e.segmentType));
}).toList(),
);
if (positionSubscription == null &&
(!isShowCover.value || plPlayerController.preInitPlayer)) {
@@ -778,36 +812,38 @@ class VideoDetailController extends GetxController
if (segmentList.isNotEmpty) {
positionSubscription?.cancel();
positionSubscription = plPlayerController
.videoPlayerController?.stream.position
.videoPlayerController
?.stream
.position
.listen((position) {
if (isShowCover.value) {
return;
}
int currentPos = position.inSeconds;
if (currentPos != _lastPos) {
_lastPos = currentPos;
final msPos = currentPos * 1000;
for (SegmentModel item in segmentList) {
// if (kDebugMode) {
// debugPrint(
// '${position.inSeconds},,${item.segment.first},,${item.segment.second},,${item.skipType.name},,${item.hasSkipped}');
// }
if (msPos <= item.segment.first &&
item.segment.first <= msPos + 1000) {
if (item.skipType == SkipType.alwaysSkip) {
onSkip(item);
} else if (item.skipType == SkipType.skipOnce &&
!item.hasSkipped) {
item.hasSkipped = true;
onSkip(item);
} else if (item.skipType == SkipType.skipManually) {
onAddItem(item);
}
break;
if (isShowCover.value) {
return;
}
}
}
});
int currentPos = position.inSeconds;
if (currentPos != _lastPos) {
_lastPos = currentPos;
final msPos = currentPos * 1000;
for (SegmentModel item in segmentList) {
// if (kDebugMode) {
// debugPrint(
// '${position.inSeconds},,${item.segment.first},,${item.segment.second},,${item.skipType.name},,${item.hasSkipped}');
// }
if (msPos <= item.segment.first &&
item.segment.first <= msPos + 1000) {
if (item.skipType == SkipType.alwaysSkip) {
onSkip(item);
} else if (item.skipType == SkipType.skipOnce &&
!item.hasSkipped) {
item.hasSkipped = true;
onSkip(item);
} else if (item.skipType == SkipType.skipManually) {
onAddItem(item);
}
break;
}
}
}
});
}
}
@@ -823,20 +859,23 @@ class VideoDetailController extends GetxController
}
void onRemoveItem(int index, item) {
EasyThrottle.throttle('onRemoveItem', const Duration(milliseconds: 500),
() {
try {
listData.removeAt(index);
if (listData.isEmpty) {
skipTimer?.cancel();
skipTimer = null;
}
listKey.currentState?.removeItem(
index,
(context, animation) => buildItem(item, animation),
);
} catch (_) {}
});
EasyThrottle.throttle(
'onRemoveItem',
const Duration(milliseconds: 500),
() {
try {
listData.removeAt(index);
if (listData.isEmpty) {
skipTimer?.cancel();
skipTimer = null;
}
listKey.currentState?.removeItem(
index,
(context, animation) => buildItem(item, animation),
);
} catch (_) {}
},
);
}
Widget buildItem(dynamic item, Animation<double> animation) {
@@ -857,8 +896,9 @@ class VideoDetailController extends GetxController
}
},
child: SearchText(
bgColor:
theme.colorScheme.secondaryContainer.withValues(alpha: 0.8),
bgColor: theme.colorScheme.secondaryContainer.withValues(
alpha: 0.8,
),
textColor: theme.colorScheme.onSecondaryContainer,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
fontSize: 14,
@@ -900,8 +940,9 @@ class VideoDetailController extends GetxController
Future<void> onSkip(SegmentModel item, [bool isSkip = true]) async {
try {
plPlayerController.danmakuController?.clear();
await plPlayerController.videoPlayerController
?.seek(Duration(milliseconds: item.segment.second));
await plPlayerController.videoPlayerController?.seek(
Duration(milliseconds: item.segment.second),
);
if (isSkip) {
if (Pref.blockToast) {
_showBlockToast('已跳过${item.segmentType.shortTitle}片段');
@@ -963,8 +1004,10 @@ class VideoDetailController extends GetxController
const end = Offset.zero;
const curve = Curves.linear;
var tween =
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
var tween = Tween(
begin: begin,
end: end,
).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
@@ -987,8 +1030,9 @@ class VideoDetailController extends GetxController
plPlayerController.buffered.value = Duration.zero;
/// 根据currentVideoQa和currentDecodeFormats 重新设置videoUrl
List<VideoItem> videoList =
data.dash!.video!.where((i) => i.id == currentVideoQa.code).toList();
List<VideoItem> videoList = data.dash!.video!
.where((i) => i.id == currentVideoQa.code)
.toList();
final List supportDecodeFormats = videoList.map((e) => e.codecs!).toList();
VideoDecodeFormatType defaultDecodeFormats =
@@ -1013,12 +1057,14 @@ class VideoDetailController extends GetxController
if (flag == 1) {
//currentDecodeFormats
firstVideo = videoList.firstWhere(
(i) => i.codecs!.startsWith(currentDecodeFormats.code),
orElse: () => videoList.first);
(i) => i.codecs!.startsWith(currentDecodeFormats.code),
orElse: () => videoList.first,
);
} else {
if (currentVideoQa == VideoQuality.dolbyVision) {
currentDecodeFormats =
VideoDecodeFormatTypeExt.fromString(videoList.first.codecs!)!;
currentDecodeFormats = VideoDecodeFormatTypeExt.fromString(
videoList.first.codecs!,
)!;
firstVideo = videoList.first;
} else if (flag == 2) {
//defaultDecodeFormats
@@ -1035,8 +1081,9 @@ class VideoDetailController extends GetxController
orElse: () => videoList.first,
);
} else if (flag == 0) {
currentDecodeFormats =
VideoDecodeFormatTypeExt.fromString(supportDecodeFormats.first)!;
currentDecodeFormats = VideoDecodeFormatTypeExt.fromString(
supportDecodeFormats.first,
)!;
firstVideo = videoList.first;
}
}
@@ -1070,13 +1117,14 @@ class VideoDetailController extends GetxController
videoSource: plPlayerController.onlyPlayAudio.value
? audio ?? audioUrl
: video ?? videoUrl,
audioSource:
plPlayerController.onlyPlayAudio.value ? '' : audio ?? audioUrl,
audioSource: plPlayerController.onlyPlayAudio.value
? ''
: audio ?? audioUrl,
type: DataSourceType.network,
httpHeaders: {
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
'referer': HttpString.baseUrl
'referer': HttpString.baseUrl,
},
),
segmentList: segmentProgressList,
@@ -1084,7 +1132,8 @@ class VideoDetailController extends GetxController
showVP: showVP,
dmTrend: dmTrend,
seekTo: seekToTime ?? defaultST ?? playedTime,
duration: duration ??
duration:
duration ??
(data.timeLength == null
? null
: Duration(milliseconds: data.timeLength!)),
@@ -1168,10 +1217,11 @@ class VideoDetailController extends GetxController
}
// 实际为FLV/MP4格式但已被淘汰这里仅做兜底处理
firstVideo = VideoItem(
id: data.quality!,
baseUrl: videoUrl,
codecs: 'avc1',
quality: VideoQuality.fromCode(data.quality!));
id: data.quality!,
baseUrl: videoUrl,
codecs: 'avc1',
quality: VideoQuality.fromCode(data.quality!),
);
setVideoHeight();
currentDecodeFormats = VideoDecodeFormatTypeExt.fromString('avc1')!;
currentVideoQa = VideoQuality.fromCode(data.quality!);
@@ -1203,23 +1253,29 @@ class VideoDetailController extends GetxController
int resVideoQa = currentHighVideoQa;
if (plPlayerController.cacheVideoQa! <= currentHighVideoQa) {
// 如果预设的画质低于当前最高
final List<int> numbers =
data.acceptQuality!.where((e) => e <= currentHighVideoQa).toList();
resVideoQa =
Utils.findClosestNumber(plPlayerController.cacheVideoQa!, numbers);
final List<int> numbers = data.acceptQuality!
.where((e) => e <= currentHighVideoQa)
.toList();
resVideoQa = Utils.findClosestNumber(
plPlayerController.cacheVideoQa!,
numbers,
);
}
currentVideoQa = VideoQuality.fromCode(resVideoQa);
/// 取出符合当前画质的videoList
final List<VideoItem> videosList =
allVideosList.where((e) => e.quality.code == resVideoQa).toList();
final List<VideoItem> videosList = allVideosList
.where((e) => e.quality.code == resVideoQa)
.toList();
/// 优先顺序 设置中指定解码格式 -> 当前可选的首个解码格式
final List<FormatItem> supportFormats = data.supportFormats!;
// 根据画质选编码格式
final List supportDecodeFormats = supportFormats
.firstWhere((e) => e.quality == resVideoQa,
orElse: () => supportFormats.first)
.firstWhere(
(e) => e.quality == resVideoQa,
orElse: () => supportFormats.first,
)
.codecs!;
// 默认从设置中取AV1
currentDecodeFormats = VideoDecodeFormatTypeExt.fromString(cacheDecode)!;
@@ -1238,14 +1294,16 @@ class VideoDetailController extends GetxController
if (flag == 2) {
currentDecodeFormats = secondDecodeFormats;
} else if (flag == 0) {
currentDecodeFormats =
VideoDecodeFormatTypeExt.fromString(supportDecodeFormats.first)!;
currentDecodeFormats = VideoDecodeFormatTypeExt.fromString(
supportDecodeFormats.first,
)!;
}
/// 取出符合当前解码格式的videoItem
firstVideo = videosList.firstWhere(
(e) => e.codecs!.startsWith(currentDecodeFormats.code),
orElse: () => videosList.first);
(e) => e.codecs!.startsWith(currentDecodeFormats.code),
orElse: () => videosList.first,
);
setVideoHeight();
videoUrl = VideoUtils.getCdnUrl(firstVideo);
@@ -1266,14 +1324,18 @@ class VideoDetailController extends GetxController
if (audiosList.isNotEmpty) {
final List<int> numbers = audiosList.map((map) => map.id!).toList();
int closestNumber =
Utils.findClosestNumber(plPlayerController.cacheAudioQa, numbers);
int closestNumber = Utils.findClosestNumber(
plPlayerController.cacheAudioQa,
numbers,
);
if (!numbers.contains(plPlayerController.cacheAudioQa) &&
numbers.any((e) => e > plPlayerController.cacheAudioQa)) {
closestNumber = 30280;
}
firstAudio = audiosList.firstWhere((e) => e.id == closestNumber,
orElse: () => audiosList.first);
firstAudio = audiosList.firstWhere(
(e) => e.id == closestNumber,
orElse: () => audiosList.first,
);
audioUrl = VideoUtils.getCdnUrl(firstAudio);
if (firstAudio.id != null) {
currentAudioQa = AudioQuality.fromCode(firstAudio.id!);
@@ -1373,8 +1435,9 @@ class VideoDetailController extends GetxController
// 设定字幕轨道
Future<void> setSubtitle(int index) async {
if (index <= 0) {
plPlayerController.videoPlayerController
?.setSubtitleTrack(SubtitleTrack.no());
plPlayerController.videoPlayerController?.setSubtitleTrack(
SubtitleTrack.no(),
);
vttSubtitlesIndex.value = index;
return;
}
@@ -1394,8 +1457,9 @@ class VideoDetailController extends GetxController
if (subtitle != null) {
setSub(subtitle);
} else {
var result =
await VideoHttp.vttSubtitles(subtitles[index - 1].subtitleUrl!);
var result = await VideoHttp.vttSubtitles(
subtitles[index - 1].subtitleUrl!,
);
if (result != null) {
_vttSubtitles[index - 1] = result;
setSub(result);
@@ -1471,8 +1535,10 @@ class VideoDetailController extends GetxController
if (playInfo.viewPoints?.isNotEmpty == true && Pref.showViewPoints) {
try {
viewPointList = playInfo.viewPoints!.map((item) {
double start =
(item.to! / (data.timeLength! / 1000)).clamp(0.0, 1.0);
double start = (item.to! / (data.timeLength! / 1000)).clamp(
0.0,
1.0,
);
return Segment(
start,
start,
@@ -1529,8 +1595,8 @@ class VideoDetailController extends GetxController
plPlayerController.makeHeartBeat(
data.timeLength != null
? (data.timeLength! - playedTime!.inMilliseconds).abs() <= 1000
? -1
: playedTime!.inSeconds
? -1
: playedTime!.inSeconds
: playedTime!.inSeconds,
type: 'status',
isManual: true,
@@ -1621,8 +1687,9 @@ class VideoDetailController extends GetxController
void showNoteList(BuildContext context) {
String? title;
try {
title =
Get.find<VideoIntroController>(tag: heroTag).videoDetail.value.title;
title = Get.find<VideoIntroController>(
tag: heroTag,
).videoDetail.value.title;
} catch (_) {}
if (plPlayerController.isFullScreen.value || showVideoSheet) {
PageUtils.showVideoBottomSheet(