fix: video play

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-02-27 19:05:57 +08:00
parent 69667c135d
commit bceabae06f
2 changed files with 158 additions and 155 deletions

View File

@@ -862,7 +862,9 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
} }
videoDetailController.scrollRatio.value = videoDetailController.scrollRatio.value =
0; 0;
if (plPlayerController == null) { if (plPlayerController == null ||
videoDetailController.playedTime ==
null) {
handlePlay(); handlePlay();
} else { } else {
if (plPlayerController! if (plPlayerController!
@@ -1641,161 +1643,162 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
); );
} }
Widget videoPlayer(double videoWidth, double videoHeight) => Stack( Widget videoPlayer(double videoWidth, double videoHeight) {
children: [ return Stack(
if (isShowing) plPlayer, children: [
if (isShowing) plPlayer,
/// 关闭自动播放时 手动播放 if (!videoDetailController.autoPlay.value) ...[
if (!videoDetailController.autoPlay.value) ...[ Obx(
Obx( () => videoDetailController.isShowCover.value
() => Visibility( ? Positioned(
visible: videoDetailController.isShowCover.value, top: 0,
child: Positioned( left: 0,
top: 0, right: 0,
left: 0, child: GestureDetector(
right: 0, onTap: handlePlay,
child: GestureDetector( child: Obx(
onTap: handlePlay, () => CachedNetworkImage(
child: Obx( imageUrl:
() => CachedNetworkImage( videoDetailController.videoItem['pic'] != null
imageUrl: videoDetailController.videoItem['pic'] != null ? (videoDetailController.videoItem['pic']
? (videoDetailController.videoItem['pic'] as String) as String)
.http2https .http2https
: '', : '',
width: videoWidth, width: videoWidth,
height: videoHeight, height: videoHeight,
fit: BoxFit.cover, fit: BoxFit.cover,
fadeOutDuration: const Duration(milliseconds: 120), fadeOutDuration: const Duration(milliseconds: 120),
fadeInDuration: const Duration(milliseconds: 120), fadeInDuration: const Duration(milliseconds: 120),
memCacheWidth: videoWidth.cacheSize(context), memCacheWidth: videoWidth.cacheSize(context),
placeholder: (context, url) => Center( placeholder: (context, url) => Center(
child: Image.asset('assets/images/loading.png'), child: Image.asset('assets/images/loading.png'),
),
), ),
), ),
), ),
), )
), : const SizedBox.shrink(),
),
),
manualPlayerWidget,
],
if (videoDetailController.enableSponsorBlock ||
videoDetailController.continuePlayingPart)
Positioned(
left: 16,
bottom: isFullScreen ? max(75, Get.height * 0.25) : 75,
child: SizedBox(
width: MediaQuery.textScalerOf(context).scale(120),
child: AnimatedList(
padding: EdgeInsets.zero,
key: videoDetailController.listKey,
reverse: true,
shrinkWrap: true,
initialItemCount: videoDetailController.listData.length,
itemBuilder: (context, index, animation) {
return videoDetailController.buildItem(
videoDetailController.listData[index],
animation,
);
},
),
),
),
// for debug
// Positioned(
// right: 16,
// bottom: 75,
// child: FilledButton.tonal(
// onPressed: () {
// videoDetailController.onAddItem(
// SegmentModel(
// UUID: '',
// segmentType: SegmentType.sponsor,
// segment: Pair(first: 0, second: 0),
// skipType: SkipType.alwaysSkip,
// ),
// );
// },
// child: Text('skip'),
// ),
// ),
// Positioned(
// right: 16,
// bottom: 120,
// child: FilledButton.tonal(
// onPressed: () {
// videoDetailController.onAddItem(2);
// },
// child: Text('index'),
// ),
// ),
Obx(
() {
if (videoDetailController.showSteinEdgeInfo.value) {
try {
return Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 16,
vertical: plPlayerController?.showControls.value == true
? 75
: 16,
),
child: Wrap(
spacing: 25,
runSpacing: 10,
children: (videoDetailController.steinEdgeInfo!['edges']
['questions'][0]['choices'] as List)
.map((item) {
return FilledButton.tonal(
style: FilledButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
backgroundColor: Theme.of(context)
.colorScheme
.secondaryContainer
.withOpacity(0.8),
padding: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
visualDensity:
VisualDensity(horizontal: -2, vertical: -2),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: () {
videoIntroController.changeSeasonOrbangu(
null,
videoDetailController.bvid,
item['cid'],
IdUtils.bv2av(videoDetailController.bvid),
null,
true,
);
videoDetailController
.getSteinEdgeInfo(item['id']);
},
child: Text(item['option']),
);
}).toList(),
),
),
);
} catch (e) {
debugPrint('build stein edges: $e');
return const SizedBox.shrink();
}
}
return const SizedBox.shrink();
},
), ),
manualPlayerWidget,
], ],
);
if (videoDetailController.enableSponsorBlock ||
videoDetailController.continuePlayingPart)
Positioned(
left: 16,
bottom: isFullScreen ? max(75, Get.height * 0.25) : 75,
child: SizedBox(
width: MediaQuery.textScalerOf(context).scale(120),
child: AnimatedList(
padding: EdgeInsets.zero,
key: videoDetailController.listKey,
reverse: true,
shrinkWrap: true,
initialItemCount: videoDetailController.listData.length,
itemBuilder: (context, index, animation) {
return videoDetailController.buildItem(
videoDetailController.listData[index],
animation,
);
},
),
),
),
// for debug
// Positioned(
// right: 16,
// bottom: 75,
// child: FilledButton.tonal(
// onPressed: () {
// videoDetailController.onAddItem(
// SegmentModel(
// UUID: '',
// segmentType: SegmentType.sponsor,
// segment: Pair(first: 0, second: 0),
// skipType: SkipType.alwaysSkip,
// ),
// );
// },
// child: Text('skip'),
// ),
// ),
// Positioned(
// right: 16,
// bottom: 120,
// child: FilledButton.tonal(
// onPressed: () {
// videoDetailController.onAddItem(2);
// },
// child: Text('index'),
// ),
// ),
Obx(
() {
if (videoDetailController.showSteinEdgeInfo.value) {
try {
return Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 16,
vertical: plPlayerController?.showControls.value == true
? 75
: 16,
),
child: Wrap(
spacing: 25,
runSpacing: 10,
children: (videoDetailController.steinEdgeInfo!['edges']
['questions'][0]['choices'] as List)
.map((item) {
return FilledButton.tonal(
style: FilledButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
backgroundColor: Theme.of(context)
.colorScheme
.secondaryContainer
.withOpacity(0.8),
padding: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
visualDensity:
VisualDensity(horizontal: -2, vertical: -2),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: () {
videoIntroController.changeSeasonOrbangu(
null,
videoDetailController.bvid,
item['cid'],
IdUtils.bv2av(videoDetailController.bvid),
null,
true,
);
videoDetailController.getSteinEdgeInfo(item['id']);
},
child: Text(item['option']),
);
}).toList(),
),
),
);
} catch (e) {
debugPrint('build stein edges: $e');
return const SizedBox.shrink();
}
}
return const SizedBox.shrink();
},
),
],
);
}
Widget videoIntro([bool needRelated = true, bool needCtr = true]) { Widget videoIntro([bool needRelated = true, bool needCtr = true]) {
Widget introPanel() => Scaffold( Widget introPanel() => Scaffold(

View File

@@ -856,13 +856,13 @@ class PlPlayerController {
} }
} }
List<StreamSubscription> subscriptions = []; Set<StreamSubscription> subscriptions = {};
final List<Function(Duration position)> _positionListeners = []; final Set<Function(Duration position)> _positionListeners = {};
final List<Function(PlayerStatus status)> _statusListeners = []; final Set<Function(PlayerStatus status)> _statusListeners = {};
/// 播放事件监听 /// 播放事件监听
void startListeners() { void startListeners() {
subscriptions = [ subscriptions = {
videoPlayerController!.stream.playing.listen((event) { videoPlayerController!.stream.playing.listen((event) {
if (event) { if (event) {
playerStatus.status.value = PlayerStatus.playing; playerStatus.status.value = PlayerStatus.playing;
@@ -973,7 +973,7 @@ class PlPlayerController {
const Duration(seconds: 1), const Duration(seconds: 1),
() => videoPlayerServiceHandler.onPositionChange(event)); () => videoPlayerServiceHandler.onPositionChange(event));
}), }),
]; };
} }
/// 移除事件监听 /// 移除事件监听