opt player

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-09-20 11:45:56 +08:00
parent d62d0eddc2
commit 9b171e04be
8 changed files with 163 additions and 153 deletions

View File

@@ -430,10 +430,9 @@ class VideoDetailController extends GetxController
bool get showVideoSheet => !horizontalScreen && !isPortrait; bool get showVideoSheet => !horizontalScreen && !isPortrait;
int? _lastPos; int? _lastPos;
List<PostSegmentModel> postList = []; late final List<PostSegmentModel> postList = [];
RxList<SegmentModel> segmentList = <SegmentModel>[].obs; late final List<SegmentModel> segmentList = <SegmentModel>[];
List<Segment> viewPointList = <Segment>[]; late final RxList<Segment> segmentProgressList = <Segment>[].obs;
List<Segment>? segmentProgressList;
Color _getColor(SegmentType segment) => Color _getColor(SegmentType segment) =>
plPlayerController.blockColor[segment.index]; plPlayerController.blockColor[segment.index];
@@ -678,7 +677,7 @@ class VideoDetailController extends GetxController
positionSubscription?.cancel(); positionSubscription?.cancel();
videoLabel.value = ''; videoLabel.value = '';
segmentList.clear(); segmentList.clear();
segmentProgressList = null; segmentProgressList.clear();
final result = await Request().get( final result = await Request().get(
'$blockServer/api/skipSegments', '$blockServer/api/skipSegments',
queryParameters: { queryParameters: {
@@ -774,7 +773,7 @@ class VideoDetailController extends GetxController
); );
// _segmentProgressList // _segmentProgressList
(segmentProgressList ??= <Segment>[]).addAll( segmentProgressList.addAll(
segmentList.map((e) { segmentList.map((e) {
double start = (e.segment.first / duration).clamp(0.0, 1.0); double start = (e.segment.first / duration).clamp(0.0, 1.0);
double end = (e.segment.second / duration).clamp(0.0, 1.0); double end = (e.segment.second / duration).clamp(0.0, 1.0);
@@ -785,7 +784,6 @@ class VideoDetailController extends GetxController
if (positionSubscription == null && if (positionSubscription == null &&
(autoPlay.value || plPlayerController.preInitPlayer)) { (autoPlay.value || plPlayerController.preInitPlayer)) {
initSkip(); initSkip();
plPlayerController.segmentList.value = segmentProgressList!;
} }
} catch (e) { } catch (e) {
if (kDebugMode) debugPrint('failed to parse sponsorblock: $e'); if (kDebugMode) debugPrint('failed to parse sponsorblock: $e');
@@ -1072,10 +1070,6 @@ class VideoDetailController extends GetxController
'referer': HttpString.baseUrl, 'referer': HttpString.baseUrl,
}, },
), ),
segmentList: segmentProgressList,
viewPointList: viewPointList,
showVP: showVP,
dmTrend: dmTrend,
seekTo: seekToTime ?? defaultST ?? playedTime, seekTo: seekToTime ?? defaultST ?? playedTime,
duration: duration:
duration ?? duration ??
@@ -1101,13 +1095,15 @@ class VideoDetailController extends GetxController
height: firstVideo.height, height: firstVideo.height,
); );
initSkip(); if (plPlayerController.enableSponsorBlock) {
initSkip();
if (vttSubtitlesIndex.value == -1) {
_getSubtitle();
} }
if (plPlayerController.showDmChart && dmTrend == null) { if (vttSubtitlesIndex.value == -1) {
_queryPlayInfo();
}
if (plPlayerController.showDmChart && dmTrend.value == null) {
_getDmTrend(); _getDmTrend();
} }
@@ -1365,13 +1361,8 @@ class VideoDetailController extends GetxController
RxList<Subtitle> subtitles = RxList<Subtitle>(); RxList<Subtitle> subtitles = RxList<Subtitle>();
late final Map<int, String> _vttSubtitles = {}; late final Map<int, String> _vttSubtitles = {};
late final RxInt vttSubtitlesIndex = (-1).obs; late final RxInt vttSubtitlesIndex = (-1).obs;
late bool showVP = true; late final RxBool showVP = true.obs;
late final RxList<Segment> viewPointList = <Segment>[].obs;
void _getSubtitle() {
_vttSubtitles.clear();
viewPointList.clear();
_queryPlayInfo();
}
// 设定字幕轨道 // 设定字幕轨道
Future<void> setSubtitle(int index) async { Future<void> setSubtitle(int index) async {
@@ -1439,6 +1430,10 @@ class VideoDetailController extends GetxController
late bool continuePlayingPart = Pref.continuePlayingPart; late bool continuePlayingPart = Pref.continuePlayingPart;
Future<void> _queryPlayInfo() async { Future<void> _queryPlayInfo() async {
_vttSubtitles.clear();
if (plPlayerController.showViewPoints) {
viewPointList.clear();
}
var res = await VideoHttp.playInfo(bvid: bvid, cid: cid.value); var res = await VideoHttp.playInfo(bvid: bvid, cid: cid.value);
if (res['status']) { if (res['status']) {
PlayInfoData playInfo = res['data']; PlayInfoData playInfo = res['data'];
@@ -1475,9 +1470,10 @@ class VideoDetailController extends GetxController
} catch (_) {} } catch (_) {}
} }
if (playInfo.viewPoints?.isNotEmpty == true && Pref.showViewPoints) { if (plPlayerController.showViewPoints &&
playInfo.viewPoints?.isNotEmpty == true) {
try { try {
viewPointList = playInfo.viewPoints!.map((item) { viewPointList.value = playInfo.viewPoints!.map((item) {
double start = (item.to! / (data.timeLength! / 1000)).clamp( double start = (item.to! / (data.timeLength! / 1000)).clamp(
0.0, 0.0,
1.0, 1.0,
@@ -1492,10 +1488,6 @@ class VideoDetailController extends GetxController
item.to, item.to,
); );
}).toList(); }).toList();
if (plPlayerController.viewPointList.isEmpty) {
plPlayerController.viewPointList.value = viewPointList;
plPlayerController.showVP.value = showVP = true;
}
} catch (_) {} } catch (_) {}
} }
@@ -1576,8 +1568,12 @@ class VideoDetailController extends GetxController
scrollRatio.refresh(); scrollRatio.refresh();
} }
// dm trend
if (plPlayerController.showDmChart) {
dmTrend.value = null;
}
// danmaku // danmaku
dmTrend = null;
savedDanmaku = null; savedDanmaku = null;
// subtitle // subtitle
@@ -1586,7 +1582,9 @@ class VideoDetailController extends GetxController
_vttSubtitles.clear(); _vttSubtitles.clear();
// view point // view point
viewPointList.clear(); if (plPlayerController.showViewPoints) {
viewPointList.clear();
}
// sponsor block // sponsor block
if (plPlayerController.enableSponsorBlock) { if (plPlayerController.enableSponsorBlock) {
@@ -1594,7 +1592,7 @@ class VideoDetailController extends GetxController
positionSubscription = null; positionSubscription = null;
videoLabel.value = ''; videoLabel.value = '';
segmentList.clear(); segmentList.clear();
segmentProgressList = null; segmentProgressList.clear();
} }
// interactive video // interactive video
@@ -1605,10 +1603,12 @@ class VideoDetailController extends GetxController
showSteinEdgeInfo.value = false; showSteinEdgeInfo.value = false;
} }
List<double>? dmTrend; late final Rx<LoadingState<List<double>>?> dmTrend =
Rx<LoadingState<List<double>>?>(null);
late final RxBool showDmTreandChart = true.obs;
Future<void> _getDmTrend() async { Future<void> _getDmTrend() async {
dmTrend = null; dmTrend.value = LoadingState<List<double>>.loading();
try { try {
var res = await Request().get( var res = await Request().get(
'https://bvc.bilivideo.com/pbp/data', 'https://bvc.bilivideo.com/pbp/data',
@@ -1617,16 +1617,15 @@ class VideoDetailController extends GetxController
'cid': cid.value, 'cid': cid.value,
}, },
); );
PbpData data = PbpData.fromJson(res.data); PbpData data = PbpData.fromJson(res.data);
int stepSec = data.stepSec ?? 0; int stepSec = data.stepSec ?? 0;
if (stepSec != 0 && data.events?.eDefault?.isNotEmpty == true) { if (stepSec != 0 && data.events?.eDefault?.isNotEmpty == true) {
dmTrend = data.events?.eDefault; dmTrend.value = Success(data.events!.eDefault!);
if (plPlayerController.dmTrend.isEmpty) { return;
plPlayerController.dmTrend.value = dmTrend!;
}
} }
dmTrend.value = const Error(null);
} catch (e) { } catch (e) {
dmTrend.value = const Error(null);
if (kDebugMode) debugPrint('_getDmTrend: $e'); if (kDebugMode) debugPrint('_getDmTrend: $e');
} }
} }

View File

@@ -4,7 +4,6 @@ import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/button/icon_button.dart'; import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart'; import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
import 'package:PiliPlus/common/widgets/pair.dart'; import 'package:PiliPlus/common/widgets/pair.dart';
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/models/common/sponsor_block/action_type.dart'; import 'package:PiliPlus/models/common/sponsor_block/action_type.dart';
import 'package:PiliPlus/models/common/sponsor_block/post_segment_model.dart'; import 'package:PiliPlus/models/common/sponsor_block/post_segment_model.dart';
@@ -338,8 +337,6 @@ class _PostPanelState extends State<PostPanel>
list.map((e) => SegmentItemModel.fromJson(e)).toList(), list.map((e) => SegmentItemModel.fromJson(e)).toList(),
); );
} }
plPlayerController.segmentList.value =
videoDetailController.segmentProgressList ?? <Segment>[];
if (videoDetailController.positionSubscription == null) { if (videoDetailController.positionSubscription == null) {
videoDetailController.initSkip(); videoDetailController.initSkip();
} }

View File

@@ -396,9 +396,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
..playerStatus = plPlayerController?.playerStatus.status.value ..playerStatus = plPlayerController?.playerStatus.status.value
..brightness = plPlayerController?.brightness.value; ..brightness = plPlayerController?.brightness.value;
if (plPlayerController != null) { if (plPlayerController != null) {
videoDetailController videoDetailController.makeHeartBeat();
..makeHeartBeat()
..showVP = plPlayerController!.showVP.value;
plPlayerController! plPlayerController!
..removeStatusLister(playerListener) ..removeStatusLister(playerListener)
..removePositionListener(positionListener) ..removePositionListener(positionListener)

View File

@@ -59,10 +59,9 @@ class _ViewPointsPageState extends State<ViewPointsPage>
} }
return null; return null;
}), }),
value: videoDetailController.plPlayerController.showVP.value, value: videoDetailController.showVP.value,
onChanged: (value) { onChanged: (value) =>
videoDetailController.plPlayerController.showVP.value = value; videoDetailController.showVP.value = value,
},
), ),
), ),
), ),

View File

@@ -2054,7 +2054,7 @@ class HeaderControlState extends TripleState<HeaderControl> {
), ),
), ),
Obx( Obx(
() => videoDetailCtr.segmentList.isNotEmpty () => videoDetailCtr.segmentProgressList.isNotEmpty
? SizedBox( ? SizedBox(
width: 42, width: 42,
height: 34, height: 34,

View File

@@ -5,7 +5,6 @@ import 'dart:math' show max;
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.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/http/ua_type.dart';
@@ -144,10 +143,6 @@ class PlPlayerController {
Timer? _timerForSeek; Timer? _timerForSeek;
Timer? _timerForShowingVolume; Timer? _timerForShowingVolume;
final RxList<Segment> viewPointList = <Segment>[].obs;
final RxBool showVP = true.obs;
final RxList<Segment> segmentList = <Segment>[].obs;
Box setting = GStorage.setting; Box setting = GStorage.setting;
// final Durations durations; // final Durations durations;
@@ -333,6 +328,7 @@ class PlPlayerController {
late final reverseFromFirst = Pref.reverseFromFirst; late final reverseFromFirst = Pref.reverseFromFirst;
late final horizontalPreview = Pref.horizontalPreview; late final horizontalPreview = Pref.horizontalPreview;
late final showDmChart = Pref.showDmChart; late final showDmChart = Pref.showDmChart;
late final showViewPoints = Pref.showViewPoints;
late final showFsScreenshotBtn = Pref.showFsScreenshotBtn; late final showFsScreenshotBtn = Pref.showFsScreenshotBtn;
late final showFsLockBtn = Pref.showFsLockBtn; late final showFsLockBtn = Pref.showFsLockBtn;
late final keyboardControl = Pref.keyboardControl; late final keyboardControl = Pref.keyboardControl;
@@ -531,10 +527,6 @@ class PlPlayerController {
Future<void> setDataSource( Future<void> setDataSource(
DataSource dataSource, { DataSource dataSource, {
bool isLive = false, bool isLive = false,
List<Segment>? segmentList,
List<Segment>? viewPointList,
bool? showVP,
List<double>? dmTrend,
bool autoplay = true, bool autoplay = true,
// 默认不循环 // 默认不循环
PlaylistMode looping = PlaylistMode.none, PlaylistMode looping = PlaylistMode.none,
@@ -563,10 +555,6 @@ class PlPlayerController {
this.width = width; this.width = width;
this.height = height; this.height = height;
this.dataSource = dataSource; this.dataSource = dataSource;
this.segmentList.value = segmentList ?? <Segment>[];
this.viewPointList.value = viewPointList ?? <Segment>[];
this.showVP.value = showVP ?? true;
this.dmTrend.value = dmTrend ?? <double>[];
_autoPlay = autoplay; _autoPlay = autoplay;
_looping = looping; _looping = looping;
// 初始化视频倍速 // 初始化视频倍速
@@ -1720,7 +1708,4 @@ class PlPlayerController {
if (kDebugMode) debugPrint('getVideoShot: $e'); if (kDebugMode) debugPrint('getVideoShot: $e');
} }
} }
late final RxList<double> dmTrend = <double>[].obs;
late final RxBool showDmTreandChart = true.obs;
} }

View File

@@ -107,6 +107,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
late AnimationController animationController; late AnimationController animationController;
late VideoController videoController; late VideoController videoController;
late final CommonIntroController introController = widget.introController!; late final CommonIntroController introController = widget.introController!;
late final VideoDetailController videoDetailController =
widget.videoDetailController!;
final GlobalKey _playerKey = GlobalKey(); final GlobalKey _playerKey = GlobalKey();
final GlobalKey<VideoState> key = GlobalKey<VideoState>(); final GlobalKey<VideoState> key = GlobalKey<VideoState>();
@@ -229,12 +231,15 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
// 动态构建底部控制条 // 动态构建底部控制条
Widget buildBottomControl(bool isLandscape) { Widget buildBottomControl(
VideoDetailController videoDetailController,
bool isLandscape,
) {
final videoDetail = introController.videoDetail.value; final videoDetail = introController.videoDetail.value;
final isSeason = videoDetail.ugcSeason != null; final isSeason = videoDetail.ugcSeason != null;
final isPart = videoDetail.pages != null && videoDetail.pages!.length > 1; final isPart = videoDetail.pages != null && videoDetail.pages!.length > 1;
final isPgc = !widget.videoDetailController!.isUgc; final isPgc = !videoDetailController.isUgc;
final isPlayAll = widget.videoDetailController?.isPlayAll == true; final isPlayAll = videoDetailController.isPlayAll;
final anySeason = isSeason || isPart || isPgc || isPlayAll; final anySeason = isSeason || isPart || isPgc || isPlayAll;
final isFullScreen = this.isFullScreen; final isFullScreen = this.isFullScreen;
final double widgetWidth = isLandscape && isFullScreen ? 42 : 35; final double widgetWidth = isLandscape && isFullScreen ? 42 : 35;
@@ -318,36 +323,40 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
/// 高能进度条 /// 高能进度条
BottomControlType.dmChart => Obx( BottomControlType.dmChart => Obx(
() => plPlayerController.dmTrend.isEmpty () {
? const SizedBox.shrink() final list = videoDetailController.dmTrend.value?.dataOrNull;
: ComBtn( if (list != null && list.isNotEmpty) {
width: widgetWidth, return ComBtn(
height: 30, width: widgetWidth,
icon: plPlayerController.showDmTreandChart.value height: 30,
? const Icon( icon: videoDetailController.showDmTreandChart.value
Icons.show_chart, ? const Icon(
size: 22, Icons.show_chart,
color: Colors.white, size: 22,
) color: Colors.white,
: const Stack( )
clipBehavior: Clip.none, : const Stack(
alignment: Alignment.center, clipBehavior: Clip.none,
children: [ alignment: Alignment.center,
Icon( children: [
Icons.show_chart, Icon(
size: 22, Icons.show_chart,
color: Colors.white, size: 22,
), color: Colors.white,
Icon( ),
Icons.hide_source, Icon(
size: 22, Icons.hide_source,
color: Colors.white, size: 22,
), color: Colors.white,
], ),
), ],
onTap: () => plPlayerController.showDmTreandChart.value = ),
!plPlayerController.showDmTreandChart.value, onTap: () => videoDetailController.showDmTreandChart.value =
), !videoDetailController.showDmTreandChart.value,
);
}
return const SizedBox.shrink();
},
), ),
/// 超分辨率 /// 超分辨率
@@ -385,7 +394,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
/// 分段信息 /// 分段信息
BottomControlType.viewPoints => Obx( BottomControlType.viewPoints => Obx(
() => plPlayerController.viewPointList.isEmpty () => videoDetailController.viewPointList.isEmpty
? const SizedBox.shrink() ? const SizedBox.shrink()
: ComBtn( : ComBtn(
width: widgetWidth, width: widgetWidth,
@@ -402,8 +411,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
onTap: widget.showViewPoints, onTap: widget.showViewPoints,
onLongPress: () { onLongPress: () {
Feedback.forLongPress(context); Feedback.forLongPress(context);
plPlayerController.showVP.value = videoDetailController.showVP.value =
!plPlayerController.showVP.value; !videoDetailController.showVP.value;
}, },
), ),
), ),
@@ -453,7 +462,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
bvid, bvid,
IdUtils.bv2av(bvid), IdUtils.bv2av(bvid),
isSeason && isPart isSeason && isPart
? widget.videoDetailController?.seasonCid ?? currentCid ? videoDetailController.seasonCid ?? currentCid
: currentCid, : currentCid,
); );
}, },
@@ -494,32 +503,32 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
/// 字幕 /// 字幕
BottomControlType.subtitle => Obx( BottomControlType.subtitle => Obx(
() => widget.videoDetailController?.subtitles.isEmpty == true () => videoDetailController.subtitles.isEmpty == true
? const SizedBox.shrink() ? const SizedBox.shrink()
: PopupMenuButton<int>( : PopupMenuButton<int>(
tooltip: '选择字幕', tooltip: '选择字幕',
requestFocus: false, requestFocus: false,
initialValue: widget initialValue: videoDetailController.vttSubtitlesIndex.value
.videoDetailController! .clamp(
.vttSubtitlesIndex 0,
.value videoDetailController.subtitles.length,
.clamp(0, widget.videoDetailController!.subtitles.length), ),
color: Colors.black.withValues(alpha: 0.8), color: Colors.black.withValues(alpha: 0.8),
itemBuilder: (context) { itemBuilder: (context) {
return [ return [
PopupMenuItem<int>( PopupMenuItem<int>(
value: 0, value: 0,
onTap: () => widget.videoDetailController!.setSubtitle(0), onTap: () => videoDetailController.setSubtitle(0),
child: const Text( child: const Text(
"关闭字幕", "关闭字幕",
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
), ),
), ),
...widget.videoDetailController!.subtitles.indexed.map((e) { ...videoDetailController.subtitles.indexed.map((e) {
return PopupMenuItem<int>( return PopupMenuItem<int>(
value: e.$1 + 1, value: e.$1 + 1,
onTap: () => onTap: () =>
widget.videoDetailController!.setSubtitle(e.$1 + 1), videoDetailController.setSubtitle(e.$1 + 1),
child: Text( child: Text(
"${e.$2.lanDoc}", "${e.$2.lanDoc}",
style: const TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
@@ -531,8 +540,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
child: SizedBox( child: SizedBox(
width: widgetWidth, width: widgetWidth,
height: 30, height: 30,
child: child: videoDetailController.vttSubtitlesIndex.value == 0
widget.videoDetailController!.vttSubtitlesIndex.value == 0
? const Icon( ? const Icon(
Icons.closed_caption_off_outlined, Icons.closed_caption_off_outlined,
size: 22, size: 22,
@@ -584,10 +592,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
BottomControlType.qa => Obx( BottomControlType.qa => Obx(
() { () {
final videoDetailCtr = widget.videoDetailController!;
final VideoQuality currentVideoQa = final VideoQuality currentVideoQa =
videoDetailCtr.currentVideoQa.value; videoDetailController.currentVideoQa.value;
final PlayUrlModel videoInfo = videoDetailCtr.data; final PlayUrlModel videoInfo = videoDetailController.data;
if (videoInfo.dash == null) { if (videoInfo.dash == null) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
@@ -625,7 +632,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
} }
final int quality = item.quality!; final int quality = item.quality!;
final newQa = VideoQuality.fromCode(quality); final newQa = VideoQuality.fromCode(quality);
videoDetailCtr videoDetailController
..currentVideoQa.value = newQa ..currentVideoQa.value = newQa
..updatePlayer(); ..updatePlayer();
@@ -697,9 +704,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
]; ];
List<BottomControlType> userSpecifyItemRight = [ List<BottomControlType> userSpecifyItemRight = [
BottomControlType.dmChart, if (plPlayerController.showDmChart) BottomControlType.dmChart,
if (plPlayerController.isAnim) BottomControlType.superResolution, if (plPlayerController.isAnim) BottomControlType.superResolution,
BottomControlType.viewPoints, if (plPlayerController.showViewPoints) BottomControlType.viewPoints,
if (anySeason) BottomControlType.episode, if (anySeason) BottomControlType.episode,
if (isFullScreen) BottomControlType.fit, if (isFullScreen) BottomControlType.fit,
BottomControlType.subtitle, BottomControlType.subtitle,
@@ -1264,8 +1271,11 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
maxWidth: maxWidth, maxWidth: maxWidth,
isFullScreen: isFullScreen, isFullScreen: isFullScreen,
controller: plPlayerController, controller: plPlayerController,
buildBottomControl: () => videoDetailController: videoDetailController,
buildBottomControl(maxWidth > maxHeight), buildBottomControl: () => buildBottomControl(
videoDetailController,
maxWidth > maxHeight,
),
), ),
), ),
], ],
@@ -1394,7 +1404,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
); );
}), }),
), ),
if (plPlayerController.segmentList.isNotEmpty) if (plPlayerController.enableSponsorBlock &&
videoDetailController.segmentProgressList.isNotEmpty)
Positioned( Positioned(
left: 0, left: 0,
right: 0, right: 0,
@@ -1405,14 +1416,16 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
key: const Key('segmentList'), key: const Key('segmentList'),
size: const Size(double.infinity, 3.5), size: const Size(double.infinity, 3.5),
painter: SegmentProgressBar( painter: SegmentProgressBar(
segmentColors: plPlayerController.segmentList, segmentColors:
videoDetailController.segmentProgressList,
), ),
), ),
), ),
), ),
), ),
if (plPlayerController.viewPointList.isNotEmpty && if (plPlayerController.showViewPoints &&
plPlayerController.showVP.value) ...[ videoDetailController.viewPointList.isNotEmpty &&
videoDetailController.showVP.value) ...[
Positioned( Positioned(
left: 0, left: 0,
right: 0, right: 0,
@@ -1423,7 +1436,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
key: const Key('viewPointList'), key: const Key('viewPointList'),
size: const Size(double.infinity, 3.5), size: const Size(double.infinity, 3.5),
painter: SegmentProgressBar( painter: SegmentProgressBar(
segmentColors: plPlayerController.viewPointList, segmentColors:
videoDetailController.viewPointList,
), ),
), ),
), ),
@@ -1431,14 +1445,17 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
), ),
if (isMobile) if (isMobile)
buildViewPointWidget( buildViewPointWidget(
videoDetailController,
plPlayerController, plPlayerController,
4.25, 4.25,
maxWidth, maxWidth,
), ),
], ],
if (plPlayerController.dmTrend.isNotEmpty && if (plPlayerController.showDmChart &&
plPlayerController.showDmTreandChart.value) videoDetailController.showDmTreandChart.value)
buildDmChart(theme, plPlayerController), if (videoDetailController.dmTrend.value?.dataOrNull
case final list?)
buildDmChart(theme, list, videoDetailController),
], ],
); );
}, },
@@ -1719,10 +1736,11 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
); );
Future<void> screenshotWebp() async { Future<void> screenshotWebp() async {
final videoCtr = widget.videoDetailController!; final videoInfo = videoDetailController.data;
final videoInfo = videoCtr.data;
final ids = videoInfo.dash!.video!.map((i) => i.id!).toSet(); final ids = videoInfo.dash!.video!.map((i) => i.id!).toSet();
final video = videoCtr.findVideoByQa(ids.reduce((p, n) => p < n ? p : n)); final video = videoDetailController.findVideoByQa(
ids.reduce((p, n) => p < n ? p : n),
);
VideoQuality qa = video.quality; VideoQuality qa = video.quality;
String? url = video.baseUrl; String? url = video.baseUrl;
@@ -1760,7 +1778,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
title: '选择画质', title: '选择画质',
initialValue: qa.code, initialValue: qa.code,
onSelected: (value) { onSelected: (value) {
final video = videoCtr.findVideoByQa(value); final video = videoDetailController.findVideoByQa(value);
url = video.baseUrl; url = video.baseUrl;
qa = video.quality; qa = video.quality;
return false; return false;
@@ -1859,7 +1877,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Widget buildDmChart( Widget buildDmChart(
ThemeData theme, ThemeData theme,
PlPlayerController plPlayerController, [ List<double> dmTrend,
VideoDetailController videoDetailController, [
double offset = 0, double offset = 0,
]) { ]) {
final color = theme.colorScheme.primary; final color = theme.colorScheme.primary;
@@ -1868,8 +1887,8 @@ Widget buildDmChart(
height: 12, height: 12,
margin: EdgeInsets.only( margin: EdgeInsets.only(
bottom: bottom:
plPlayerController.viewPointList.isNotEmpty && videoDetailController.viewPointList.isNotEmpty &&
plPlayerController.showVP.value videoDetailController.showVP.value
? 20.25 + offset ? 20.25 + offset
: 4.25 + offset, : 4.25 + offset,
), ),
@@ -1880,18 +1899,16 @@ Widget buildDmChart(
gridData: const FlGridData(show: false), gridData: const FlGridData(show: false),
borderData: FlBorderData(show: false), borderData: FlBorderData(show: false),
minX: 0, minX: 0,
maxX: (plPlayerController.dmTrend.length - 1).toDouble(), maxX: (dmTrend.length - 1).toDouble(),
minY: 0, minY: 0,
maxY: plPlayerController.dmTrend maxY: dmTrend.reduce((a, b) => a > b ? a : b).toDouble(),
.reduce((a, b) => a > b ? a : b)
.toDouble(),
lineBarsData: [ lineBarsData: [
LineChartBarData( LineChartBarData(
spots: List.generate( spots: List.generate(
plPlayerController.dmTrend.length, dmTrend.length,
(index) => FlSpot( (index) => FlSpot(
index.toDouble(), index.toDouble(),
plPlayerController.dmTrend[index], dmTrend[index],
), ),
), ),
isCurved: true, isCurved: true,
@@ -2172,6 +2189,7 @@ class _CroppedImagePainter extends CustomPainter {
} }
Widget buildViewPointWidget( Widget buildViewPointWidget(
VideoDetailController videoDetailController,
PlPlayerController plPlayerController, PlPlayerController plPlayerController,
double offset, double offset,
double maxWidth, double maxWidth,
@@ -2184,7 +2202,7 @@ Widget buildViewPointWidget(
onPointerDown: (event) { onPointerDown: (event) {
try { try {
double seg = event.localPosition.dx / maxWidth; double seg = event.localPosition.dx / maxWidth;
Segment item = plPlayerController.viewPointList Segment item = videoDetailController.viewPointList
.where((item) => item.start >= seg) .where((item) => item.start >= seg)
.reduce((a, b) => a.start < b.start ? a : b); .reduce((a, b) => a.start < b.start ? a : b);
if (item.from != null) { if (item.from != null) {

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.dart'; import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.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/pages/video/controller.dart';
import 'package:PiliPlus/plugin/pl_player/controller.dart'; import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/plugin/pl_player/view.dart'; import 'package:PiliPlus/plugin/pl_player/view.dart';
import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/feed_back.dart';
@@ -17,12 +18,14 @@ class BottomControl extends StatelessWidget {
required this.isFullScreen, required this.isFullScreen,
required this.controller, required this.controller,
required this.buildBottomControl, required this.buildBottomControl,
required this.videoDetailController,
}); });
final double maxWidth; final double maxWidth;
final bool isFullScreen; final bool isFullScreen;
final PlPlayerController controller; final PlPlayerController controller;
final Widget Function() buildBottomControl; final Widget Function() buildBottomControl;
final VideoDetailController videoDetailController;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -107,7 +110,8 @@ class BottomControl extends StatelessWidget {
}, },
); );
}), }),
if (controller.segmentList.isNotEmpty) if (controller.enableSponsorBlock &&
videoDetailController.segmentProgressList.isNotEmpty)
Positioned( Positioned(
left: 0, left: 0,
right: 0, right: 0,
@@ -118,14 +122,16 @@ class BottomControl extends StatelessWidget {
key: const Key('segmentList'), key: const Key('segmentList'),
size: const Size(double.infinity, 3.5), size: const Size(double.infinity, 3.5),
painter: SegmentProgressBar( painter: SegmentProgressBar(
segmentColors: controller.segmentList, segmentColors:
videoDetailController.segmentProgressList,
), ),
), ),
), ),
), ),
), ),
if (controller.viewPointList.isNotEmpty && if (controller.showViewPoints &&
controller.showVP.value) ...[ videoDetailController.viewPointList.isNotEmpty &&
videoDetailController.showVP.value) ...[
Positioned( Positioned(
left: 0, left: 0,
right: 0, right: 0,
@@ -136,18 +142,26 @@ class BottomControl extends StatelessWidget {
key: const Key('viewPointList'), key: const Key('viewPointList'),
size: const Size(double.infinity, 3.5), size: const Size(double.infinity, 3.5),
painter: SegmentProgressBar( painter: SegmentProgressBar(
segmentColors: controller.viewPointList, segmentColors:
videoDetailController.viewPointList,
), ),
), ),
), ),
), ),
), ),
if (!Utils.isMobile) if (!Utils.isMobile)
buildViewPointWidget(controller, 8.75, maxWidth - 40), buildViewPointWidget(
videoDetailController,
controller,
8.75,
maxWidth - 40,
),
], ],
if (controller.dmTrend.isNotEmpty && if (controller.showDmChart &&
controller.showDmTreandChart.value) videoDetailController.showDmTreandChart.value)
buildDmChart(theme, controller, 4.5), if (videoDetailController.dmTrend.value?.dataOrNull
case final list?)
buildDmChart(theme, list, videoDetailController, 4.5),
], ],
), ),
), ),