mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-20 17:16:29 +08:00
@@ -430,10 +430,9 @@ class VideoDetailController extends GetxController
|
||||
bool get showVideoSheet => !horizontalScreen && !isPortrait;
|
||||
|
||||
int? _lastPos;
|
||||
List<PostSegmentModel> postList = [];
|
||||
RxList<SegmentModel> segmentList = <SegmentModel>[].obs;
|
||||
List<Segment> viewPointList = <Segment>[];
|
||||
List<Segment>? segmentProgressList;
|
||||
late final List<PostSegmentModel> postList = [];
|
||||
late final List<SegmentModel> segmentList = <SegmentModel>[];
|
||||
late final RxList<Segment> segmentProgressList = <Segment>[].obs;
|
||||
|
||||
Color _getColor(SegmentType segment) =>
|
||||
plPlayerController.blockColor[segment.index];
|
||||
@@ -678,7 +677,7 @@ class VideoDetailController extends GetxController
|
||||
positionSubscription?.cancel();
|
||||
videoLabel.value = '';
|
||||
segmentList.clear();
|
||||
segmentProgressList = null;
|
||||
segmentProgressList.clear();
|
||||
final result = await Request().get(
|
||||
'$blockServer/api/skipSegments',
|
||||
queryParameters: {
|
||||
@@ -774,7 +773,7 @@ class VideoDetailController extends GetxController
|
||||
);
|
||||
|
||||
// _segmentProgressList
|
||||
(segmentProgressList ??= <Segment>[]).addAll(
|
||||
segmentProgressList.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);
|
||||
@@ -785,7 +784,6 @@ class VideoDetailController extends GetxController
|
||||
if (positionSubscription == null &&
|
||||
(autoPlay.value || plPlayerController.preInitPlayer)) {
|
||||
initSkip();
|
||||
plPlayerController.segmentList.value = segmentProgressList!;
|
||||
}
|
||||
} catch (e) {
|
||||
if (kDebugMode) debugPrint('failed to parse sponsorblock: $e');
|
||||
@@ -1072,10 +1070,6 @@ class VideoDetailController extends GetxController
|
||||
'referer': HttpString.baseUrl,
|
||||
},
|
||||
),
|
||||
segmentList: segmentProgressList,
|
||||
viewPointList: viewPointList,
|
||||
showVP: showVP,
|
||||
dmTrend: dmTrend,
|
||||
seekTo: seekToTime ?? defaultST ?? playedTime,
|
||||
duration:
|
||||
duration ??
|
||||
@@ -1101,13 +1095,15 @@ class VideoDetailController extends GetxController
|
||||
height: firstVideo.height,
|
||||
);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -1365,13 +1361,8 @@ class VideoDetailController extends GetxController
|
||||
RxList<Subtitle> subtitles = RxList<Subtitle>();
|
||||
late final Map<int, String> _vttSubtitles = {};
|
||||
late final RxInt vttSubtitlesIndex = (-1).obs;
|
||||
late bool showVP = true;
|
||||
|
||||
void _getSubtitle() {
|
||||
_vttSubtitles.clear();
|
||||
viewPointList.clear();
|
||||
_queryPlayInfo();
|
||||
}
|
||||
late final RxBool showVP = true.obs;
|
||||
late final RxList<Segment> viewPointList = <Segment>[].obs;
|
||||
|
||||
// 设定字幕轨道
|
||||
Future<void> setSubtitle(int index) async {
|
||||
@@ -1439,6 +1430,10 @@ class VideoDetailController extends GetxController
|
||||
late bool continuePlayingPart = Pref.continuePlayingPart;
|
||||
|
||||
Future<void> _queryPlayInfo() async {
|
||||
_vttSubtitles.clear();
|
||||
if (plPlayerController.showViewPoints) {
|
||||
viewPointList.clear();
|
||||
}
|
||||
var res = await VideoHttp.playInfo(bvid: bvid, cid: cid.value);
|
||||
if (res['status']) {
|
||||
PlayInfoData playInfo = res['data'];
|
||||
@@ -1475,9 +1470,10 @@ class VideoDetailController extends GetxController
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
if (playInfo.viewPoints?.isNotEmpty == true && Pref.showViewPoints) {
|
||||
if (plPlayerController.showViewPoints &&
|
||||
playInfo.viewPoints?.isNotEmpty == true) {
|
||||
try {
|
||||
viewPointList = playInfo.viewPoints!.map((item) {
|
||||
viewPointList.value = playInfo.viewPoints!.map((item) {
|
||||
double start = (item.to! / (data.timeLength! / 1000)).clamp(
|
||||
0.0,
|
||||
1.0,
|
||||
@@ -1492,10 +1488,6 @@ class VideoDetailController extends GetxController
|
||||
item.to,
|
||||
);
|
||||
}).toList();
|
||||
if (plPlayerController.viewPointList.isEmpty) {
|
||||
plPlayerController.viewPointList.value = viewPointList;
|
||||
plPlayerController.showVP.value = showVP = true;
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
@@ -1576,8 +1568,12 @@ class VideoDetailController extends GetxController
|
||||
scrollRatio.refresh();
|
||||
}
|
||||
|
||||
// dm trend
|
||||
if (plPlayerController.showDmChart) {
|
||||
dmTrend.value = null;
|
||||
}
|
||||
|
||||
// danmaku
|
||||
dmTrend = null;
|
||||
savedDanmaku = null;
|
||||
|
||||
// subtitle
|
||||
@@ -1586,7 +1582,9 @@ class VideoDetailController extends GetxController
|
||||
_vttSubtitles.clear();
|
||||
|
||||
// view point
|
||||
if (plPlayerController.showViewPoints) {
|
||||
viewPointList.clear();
|
||||
}
|
||||
|
||||
// sponsor block
|
||||
if (plPlayerController.enableSponsorBlock) {
|
||||
@@ -1594,7 +1592,7 @@ class VideoDetailController extends GetxController
|
||||
positionSubscription = null;
|
||||
videoLabel.value = '';
|
||||
segmentList.clear();
|
||||
segmentProgressList = null;
|
||||
segmentProgressList.clear();
|
||||
}
|
||||
|
||||
// interactive video
|
||||
@@ -1605,10 +1603,12 @@ class VideoDetailController extends GetxController
|
||||
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 {
|
||||
dmTrend = null;
|
||||
dmTrend.value = LoadingState<List<double>>.loading();
|
||||
try {
|
||||
var res = await Request().get(
|
||||
'https://bvc.bilivideo.com/pbp/data',
|
||||
@@ -1617,16 +1617,15 @@ class VideoDetailController extends GetxController
|
||||
'cid': cid.value,
|
||||
},
|
||||
);
|
||||
|
||||
PbpData data = PbpData.fromJson(res.data);
|
||||
int stepSec = data.stepSec ?? 0;
|
||||
if (stepSec != 0 && data.events?.eDefault?.isNotEmpty == true) {
|
||||
dmTrend = data.events?.eDefault;
|
||||
if (plPlayerController.dmTrend.isEmpty) {
|
||||
plPlayerController.dmTrend.value = dmTrend!;
|
||||
}
|
||||
dmTrend.value = Success(data.events!.eDefault!);
|
||||
return;
|
||||
}
|
||||
dmTrend.value = const Error(null);
|
||||
} catch (e) {
|
||||
dmTrend.value = const Error(null);
|
||||
if (kDebugMode) debugPrint('_getDmTrend: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:PiliPlus/common/constants.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/pair.dart';
|
||||
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/models/common/sponsor_block/action_type.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(),
|
||||
);
|
||||
}
|
||||
plPlayerController.segmentList.value =
|
||||
videoDetailController.segmentProgressList ?? <Segment>[];
|
||||
if (videoDetailController.positionSubscription == null) {
|
||||
videoDetailController.initSkip();
|
||||
}
|
||||
|
||||
@@ -396,9 +396,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
..playerStatus = plPlayerController?.playerStatus.status.value
|
||||
..brightness = plPlayerController?.brightness.value;
|
||||
if (plPlayerController != null) {
|
||||
videoDetailController
|
||||
..makeHeartBeat()
|
||||
..showVP = plPlayerController!.showVP.value;
|
||||
videoDetailController.makeHeartBeat();
|
||||
plPlayerController!
|
||||
..removeStatusLister(playerListener)
|
||||
..removePositionListener(positionListener)
|
||||
|
||||
@@ -59,10 +59,9 @@ class _ViewPointsPageState extends State<ViewPointsPage>
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
value: videoDetailController.plPlayerController.showVP.value,
|
||||
onChanged: (value) {
|
||||
videoDetailController.plPlayerController.showVP.value = value;
|
||||
},
|
||||
value: videoDetailController.showVP.value,
|
||||
onChanged: (value) =>
|
||||
videoDetailController.showVP.value = value,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2054,7 +2054,7 @@ class HeaderControlState extends TripleState<HeaderControl> {
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => videoDetailCtr.segmentList.isNotEmpty
|
||||
() => videoDetailCtr.segmentProgressList.isNotEmpty
|
||||
? SizedBox(
|
||||
width: 42,
|
||||
height: 34,
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'dart:math' show max;
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
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/loading_state.dart';
|
||||
import 'package:PiliPlus/http/ua_type.dart';
|
||||
@@ -144,10 +143,6 @@ class PlPlayerController {
|
||||
Timer? _timerForSeek;
|
||||
Timer? _timerForShowingVolume;
|
||||
|
||||
final RxList<Segment> viewPointList = <Segment>[].obs;
|
||||
final RxBool showVP = true.obs;
|
||||
final RxList<Segment> segmentList = <Segment>[].obs;
|
||||
|
||||
Box setting = GStorage.setting;
|
||||
|
||||
// final Durations durations;
|
||||
@@ -333,6 +328,7 @@ class PlPlayerController {
|
||||
late final reverseFromFirst = Pref.reverseFromFirst;
|
||||
late final horizontalPreview = Pref.horizontalPreview;
|
||||
late final showDmChart = Pref.showDmChart;
|
||||
late final showViewPoints = Pref.showViewPoints;
|
||||
late final showFsScreenshotBtn = Pref.showFsScreenshotBtn;
|
||||
late final showFsLockBtn = Pref.showFsLockBtn;
|
||||
late final keyboardControl = Pref.keyboardControl;
|
||||
@@ -531,10 +527,6 @@ class PlPlayerController {
|
||||
Future<void> setDataSource(
|
||||
DataSource dataSource, {
|
||||
bool isLive = false,
|
||||
List<Segment>? segmentList,
|
||||
List<Segment>? viewPointList,
|
||||
bool? showVP,
|
||||
List<double>? dmTrend,
|
||||
bool autoplay = true,
|
||||
// 默认不循环
|
||||
PlaylistMode looping = PlaylistMode.none,
|
||||
@@ -563,10 +555,6 @@ class PlPlayerController {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
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;
|
||||
_looping = looping;
|
||||
// 初始化视频倍速
|
||||
@@ -1720,7 +1708,4 @@ class PlPlayerController {
|
||||
if (kDebugMode) debugPrint('getVideoShot: $e');
|
||||
}
|
||||
}
|
||||
|
||||
late final RxList<double> dmTrend = <double>[].obs;
|
||||
late final RxBool showDmTreandChart = true.obs;
|
||||
}
|
||||
|
||||
@@ -107,6 +107,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
late AnimationController animationController;
|
||||
late VideoController videoController;
|
||||
late final CommonIntroController introController = widget.introController!;
|
||||
late final VideoDetailController videoDetailController =
|
||||
widget.videoDetailController!;
|
||||
|
||||
final GlobalKey _playerKey = GlobalKey();
|
||||
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 isSeason = videoDetail.ugcSeason != null;
|
||||
final isPart = videoDetail.pages != null && videoDetail.pages!.length > 1;
|
||||
final isPgc = !widget.videoDetailController!.isUgc;
|
||||
final isPlayAll = widget.videoDetailController?.isPlayAll == true;
|
||||
final isPgc = !videoDetailController.isUgc;
|
||||
final isPlayAll = videoDetailController.isPlayAll;
|
||||
final anySeason = isSeason || isPart || isPgc || isPlayAll;
|
||||
final isFullScreen = this.isFullScreen;
|
||||
final double widgetWidth = isLandscape && isFullScreen ? 42 : 35;
|
||||
@@ -318,12 +323,13 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
|
||||
/// 高能进度条
|
||||
BottomControlType.dmChart => Obx(
|
||||
() => plPlayerController.dmTrend.isEmpty
|
||||
? const SizedBox.shrink()
|
||||
: ComBtn(
|
||||
() {
|
||||
final list = videoDetailController.dmTrend.value?.dataOrNull;
|
||||
if (list != null && list.isNotEmpty) {
|
||||
return ComBtn(
|
||||
width: widgetWidth,
|
||||
height: 30,
|
||||
icon: plPlayerController.showDmTreandChart.value
|
||||
icon: videoDetailController.showDmTreandChart.value
|
||||
? const Icon(
|
||||
Icons.show_chart,
|
||||
size: 22,
|
||||
@@ -345,9 +351,12 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
),
|
||||
],
|
||||
),
|
||||
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(
|
||||
() => plPlayerController.viewPointList.isEmpty
|
||||
() => videoDetailController.viewPointList.isEmpty
|
||||
? const SizedBox.shrink()
|
||||
: ComBtn(
|
||||
width: widgetWidth,
|
||||
@@ -402,8 +411,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
onTap: widget.showViewPoints,
|
||||
onLongPress: () {
|
||||
Feedback.forLongPress(context);
|
||||
plPlayerController.showVP.value =
|
||||
!plPlayerController.showVP.value;
|
||||
videoDetailController.showVP.value =
|
||||
!videoDetailController.showVP.value;
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -453,7 +462,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
bvid,
|
||||
IdUtils.bv2av(bvid),
|
||||
isSeason && isPart
|
||||
? widget.videoDetailController?.seasonCid ?? currentCid
|
||||
? videoDetailController.seasonCid ?? currentCid
|
||||
: currentCid,
|
||||
);
|
||||
},
|
||||
@@ -494,32 +503,32 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
|
||||
/// 字幕
|
||||
BottomControlType.subtitle => Obx(
|
||||
() => widget.videoDetailController?.subtitles.isEmpty == true
|
||||
() => videoDetailController.subtitles.isEmpty == true
|
||||
? const SizedBox.shrink()
|
||||
: PopupMenuButton<int>(
|
||||
tooltip: '选择字幕',
|
||||
requestFocus: false,
|
||||
initialValue: widget
|
||||
.videoDetailController!
|
||||
.vttSubtitlesIndex
|
||||
.value
|
||||
.clamp(0, widget.videoDetailController!.subtitles.length),
|
||||
initialValue: videoDetailController.vttSubtitlesIndex.value
|
||||
.clamp(
|
||||
0,
|
||||
videoDetailController.subtitles.length,
|
||||
),
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
PopupMenuItem<int>(
|
||||
value: 0,
|
||||
onTap: () => widget.videoDetailController!.setSubtitle(0),
|
||||
onTap: () => videoDetailController.setSubtitle(0),
|
||||
child: const Text(
|
||||
"关闭字幕",
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
...widget.videoDetailController!.subtitles.indexed.map((e) {
|
||||
...videoDetailController.subtitles.indexed.map((e) {
|
||||
return PopupMenuItem<int>(
|
||||
value: e.$1 + 1,
|
||||
onTap: () =>
|
||||
widget.videoDetailController!.setSubtitle(e.$1 + 1),
|
||||
videoDetailController.setSubtitle(e.$1 + 1),
|
||||
child: Text(
|
||||
"${e.$2.lanDoc}",
|
||||
style: const TextStyle(color: Colors.white),
|
||||
@@ -531,8 +540,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
child: SizedBox(
|
||||
width: widgetWidth,
|
||||
height: 30,
|
||||
child:
|
||||
widget.videoDetailController!.vttSubtitlesIndex.value == 0
|
||||
child: videoDetailController.vttSubtitlesIndex.value == 0
|
||||
? const Icon(
|
||||
Icons.closed_caption_off_outlined,
|
||||
size: 22,
|
||||
@@ -584,10 +592,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
|
||||
BottomControlType.qa => Obx(
|
||||
() {
|
||||
final videoDetailCtr = widget.videoDetailController!;
|
||||
final VideoQuality currentVideoQa =
|
||||
videoDetailCtr.currentVideoQa.value;
|
||||
final PlayUrlModel videoInfo = videoDetailCtr.data;
|
||||
videoDetailController.currentVideoQa.value;
|
||||
final PlayUrlModel videoInfo = videoDetailController.data;
|
||||
if (videoInfo.dash == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
@@ -625,7 +632,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
final int quality = item.quality!;
|
||||
final newQa = VideoQuality.fromCode(quality);
|
||||
videoDetailCtr
|
||||
videoDetailController
|
||||
..currentVideoQa.value = newQa
|
||||
..updatePlayer();
|
||||
|
||||
@@ -697,9 +704,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
];
|
||||
|
||||
List<BottomControlType> userSpecifyItemRight = [
|
||||
BottomControlType.dmChart,
|
||||
if (plPlayerController.showDmChart) BottomControlType.dmChart,
|
||||
if (plPlayerController.isAnim) BottomControlType.superResolution,
|
||||
BottomControlType.viewPoints,
|
||||
if (plPlayerController.showViewPoints) BottomControlType.viewPoints,
|
||||
if (anySeason) BottomControlType.episode,
|
||||
if (isFullScreen) BottomControlType.fit,
|
||||
BottomControlType.subtitle,
|
||||
@@ -1264,8 +1271,11 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
maxWidth: maxWidth,
|
||||
isFullScreen: isFullScreen,
|
||||
controller: plPlayerController,
|
||||
buildBottomControl: () =>
|
||||
buildBottomControl(maxWidth > maxHeight),
|
||||
videoDetailController: videoDetailController,
|
||||
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(
|
||||
left: 0,
|
||||
right: 0,
|
||||
@@ -1405,14 +1416,16 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
key: const Key('segmentList'),
|
||||
size: const Size(double.infinity, 3.5),
|
||||
painter: SegmentProgressBar(
|
||||
segmentColors: plPlayerController.segmentList,
|
||||
segmentColors:
|
||||
videoDetailController.segmentProgressList,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (plPlayerController.viewPointList.isNotEmpty &&
|
||||
plPlayerController.showVP.value) ...[
|
||||
if (plPlayerController.showViewPoints &&
|
||||
videoDetailController.viewPointList.isNotEmpty &&
|
||||
videoDetailController.showVP.value) ...[
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
@@ -1423,7 +1436,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
key: const Key('viewPointList'),
|
||||
size: const Size(double.infinity, 3.5),
|
||||
painter: SegmentProgressBar(
|
||||
segmentColors: plPlayerController.viewPointList,
|
||||
segmentColors:
|
||||
videoDetailController.viewPointList,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1431,14 +1445,17 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
),
|
||||
if (isMobile)
|
||||
buildViewPointWidget(
|
||||
videoDetailController,
|
||||
plPlayerController,
|
||||
4.25,
|
||||
maxWidth,
|
||||
),
|
||||
],
|
||||
if (plPlayerController.dmTrend.isNotEmpty &&
|
||||
plPlayerController.showDmTreandChart.value)
|
||||
buildDmChart(theme, plPlayerController),
|
||||
if (plPlayerController.showDmChart &&
|
||||
videoDetailController.showDmTreandChart.value)
|
||||
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 {
|
||||
final videoCtr = widget.videoDetailController!;
|
||||
final videoInfo = videoCtr.data;
|
||||
final videoInfo = videoDetailController.data;
|
||||
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;
|
||||
String? url = video.baseUrl;
|
||||
@@ -1760,7 +1778,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
title: '选择画质',
|
||||
initialValue: qa.code,
|
||||
onSelected: (value) {
|
||||
final video = videoCtr.findVideoByQa(value);
|
||||
final video = videoDetailController.findVideoByQa(value);
|
||||
url = video.baseUrl;
|
||||
qa = video.quality;
|
||||
return false;
|
||||
@@ -1859,7 +1877,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
|
||||
Widget buildDmChart(
|
||||
ThemeData theme,
|
||||
PlPlayerController plPlayerController, [
|
||||
List<double> dmTrend,
|
||||
VideoDetailController videoDetailController, [
|
||||
double offset = 0,
|
||||
]) {
|
||||
final color = theme.colorScheme.primary;
|
||||
@@ -1868,8 +1887,8 @@ Widget buildDmChart(
|
||||
height: 12,
|
||||
margin: EdgeInsets.only(
|
||||
bottom:
|
||||
plPlayerController.viewPointList.isNotEmpty &&
|
||||
plPlayerController.showVP.value
|
||||
videoDetailController.viewPointList.isNotEmpty &&
|
||||
videoDetailController.showVP.value
|
||||
? 20.25 + offset
|
||||
: 4.25 + offset,
|
||||
),
|
||||
@@ -1880,18 +1899,16 @@ Widget buildDmChart(
|
||||
gridData: const FlGridData(show: false),
|
||||
borderData: FlBorderData(show: false),
|
||||
minX: 0,
|
||||
maxX: (plPlayerController.dmTrend.length - 1).toDouble(),
|
||||
maxX: (dmTrend.length - 1).toDouble(),
|
||||
minY: 0,
|
||||
maxY: plPlayerController.dmTrend
|
||||
.reduce((a, b) => a > b ? a : b)
|
||||
.toDouble(),
|
||||
maxY: dmTrend.reduce((a, b) => a > b ? a : b).toDouble(),
|
||||
lineBarsData: [
|
||||
LineChartBarData(
|
||||
spots: List.generate(
|
||||
plPlayerController.dmTrend.length,
|
||||
dmTrend.length,
|
||||
(index) => FlSpot(
|
||||
index.toDouble(),
|
||||
plPlayerController.dmTrend[index],
|
||||
dmTrend[index],
|
||||
),
|
||||
),
|
||||
isCurved: true,
|
||||
@@ -2172,6 +2189,7 @@ class _CroppedImagePainter extends CustomPainter {
|
||||
}
|
||||
|
||||
Widget buildViewPointWidget(
|
||||
VideoDetailController videoDetailController,
|
||||
PlPlayerController plPlayerController,
|
||||
double offset,
|
||||
double maxWidth,
|
||||
@@ -2184,7 +2202,7 @@ Widget buildViewPointWidget(
|
||||
onPointerDown: (event) {
|
||||
try {
|
||||
double seg = event.localPosition.dx / maxWidth;
|
||||
Segment item = plPlayerController.viewPointList
|
||||
Segment item = videoDetailController.viewPointList
|
||||
.where((item) => item.start >= seg)
|
||||
.reduce((a, b) => a.start < b.start ? a : b);
|
||||
if (item.from != null) {
|
||||
|
||||
@@ -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/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/view.dart';
|
||||
import 'package:PiliPlus/utils/feed_back.dart';
|
||||
@@ -17,12 +18,14 @@ class BottomControl extends StatelessWidget {
|
||||
required this.isFullScreen,
|
||||
required this.controller,
|
||||
required this.buildBottomControl,
|
||||
required this.videoDetailController,
|
||||
});
|
||||
|
||||
final double maxWidth;
|
||||
final bool isFullScreen;
|
||||
final PlPlayerController controller;
|
||||
final Widget Function() buildBottomControl;
|
||||
final VideoDetailController videoDetailController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -107,7 +110,8 @@ class BottomControl extends StatelessWidget {
|
||||
},
|
||||
);
|
||||
}),
|
||||
if (controller.segmentList.isNotEmpty)
|
||||
if (controller.enableSponsorBlock &&
|
||||
videoDetailController.segmentProgressList.isNotEmpty)
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
@@ -118,14 +122,16 @@ class BottomControl extends StatelessWidget {
|
||||
key: const Key('segmentList'),
|
||||
size: const Size(double.infinity, 3.5),
|
||||
painter: SegmentProgressBar(
|
||||
segmentColors: controller.segmentList,
|
||||
segmentColors:
|
||||
videoDetailController.segmentProgressList,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (controller.viewPointList.isNotEmpty &&
|
||||
controller.showVP.value) ...[
|
||||
if (controller.showViewPoints &&
|
||||
videoDetailController.viewPointList.isNotEmpty &&
|
||||
videoDetailController.showVP.value) ...[
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
@@ -136,18 +142,26 @@ class BottomControl extends StatelessWidget {
|
||||
key: const Key('viewPointList'),
|
||||
size: const Size(double.infinity, 3.5),
|
||||
painter: SegmentProgressBar(
|
||||
segmentColors: controller.viewPointList,
|
||||
segmentColors:
|
||||
videoDetailController.viewPointList,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!Utils.isMobile)
|
||||
buildViewPointWidget(controller, 8.75, maxWidth - 40),
|
||||
buildViewPointWidget(
|
||||
videoDetailController,
|
||||
controller,
|
||||
8.75,
|
||||
maxWidth - 40,
|
||||
),
|
||||
],
|
||||
if (controller.dmTrend.isNotEmpty &&
|
||||
controller.showDmTreandChart.value)
|
||||
buildDmChart(theme, controller, 4.5),
|
||||
if (controller.showDmChart &&
|
||||
videoDetailController.showDmTreandChart.value)
|
||||
if (videoDetailController.dmTrend.value?.dataOrNull
|
||||
case final list?)
|
||||
buildDmChart(theme, list, videoDetailController, 4.5),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user