opt player

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-08-10 13:03:49 +08:00
parent b788794f4b
commit dbde90459b
4 changed files with 1263 additions and 1230 deletions

View File

@@ -14,7 +14,6 @@ import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart'; import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
import 'package:PiliPlus/plugin/pl_player/view.dart'; import 'package:PiliPlus/plugin/pl_player/view.dart';
import 'package:PiliPlus/services/service_locator.dart'; import 'package:PiliPlus/services/service_locator.dart';
import 'package:PiliPlus/utils/context_ext.dart';
import 'package:PiliPlus/utils/duration_util.dart'; import 'package:PiliPlus/utils/duration_util.dart';
import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart';
@@ -113,20 +112,39 @@ class _LiveRoomPageState extends State<LiveRoomPage>
} }
} }
late double maxWidth;
late double maxHeight;
late EdgeInsets padding;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isPortrait = context.isPortrait; padding = MediaQuery.paddingOf(context);
if (Platform.isAndroid) { return LayoutBuilder(
return Floating().isPipMode builder: (context, constraints) {
? videoPlayerPanel(isFullScreen, isPipMode: true) maxWidth = constraints.maxWidth;
: childWhenDisabled(isPortrait); maxHeight = constraints.maxHeight;
} else { final isPortrait = maxHeight >= maxWidth;
return childWhenDisabled(isPortrait);
} if (Platform.isAndroid) {
return Floating().isPipMode
? videoPlayerPanel(
isFullScreen,
width: maxWidth,
height: maxHeight,
isPipMode: true,
)
: childWhenDisabled(isPortrait);
} else {
return childWhenDisabled(isPortrait);
}
},
);
} }
Widget videoPlayerPanel( Widget videoPlayerPanel(
bool isFullScreen, { bool isFullScreen, {
required double width,
required double height,
bool isPipMode = false, bool isPipMode = false,
Color? fill, Color? fill,
Alignment? alignment, Alignment? alignment,
@@ -144,6 +162,8 @@ class _LiveRoomPageState extends State<LiveRoomPage>
final roomInfoH5 = _liveRoomController.roomInfoH5.value; final roomInfoH5 = _liveRoomController.roomInfoH5.value;
return PLVideoPlayer( return PLVideoPlayer(
key: playerKey, key: playerKey,
maxWidth: width,
maxHeight: height,
fill: fill, fill: fill,
alignment: alignment, alignment: alignment,
plPlayerController: plPlayerController, plPlayerController: plPlayerController,
@@ -212,11 +232,10 @@ class _LiveRoomPageState extends State<LiveRoomPage>
?.appBackground; ?.appBackground;
Widget child; Widget child;
if (appBackground?.isNotEmpty == true) { if (appBackground?.isNotEmpty == true) {
final size = Get.size;
child = CachedNetworkImage( child = CachedNetworkImage(
fit: BoxFit.cover, fit: BoxFit.cover,
width: size.width, width: maxWidth,
height: size.height, height: maxHeight,
imageUrl: appBackground!.http2https, imageUrl: appBackground!.http2https,
); );
} else { } else {
@@ -254,14 +273,18 @@ class _LiveRoomPageState extends State<LiveRoomPage>
Widget get _buildPH { Widget get _buildPH {
final isFullScreen = this.isFullScreen; final isFullScreen = this.isFullScreen;
final size = Get.size; final height = isFullScreen ? maxHeight : maxWidth * 9 / 16;
return Column( return Column(
children: [ children: [
if (!isFullScreen) _buildAppBar, if (!isFullScreen) _buildAppBar,
SizedBox( SizedBox(
width: size.width, width: maxWidth,
height: isFullScreen ? size.height : size.width * 9 / 16, height: height,
child: videoPlayerPanel(isFullScreen), child: videoPlayerPanel(
isFullScreen,
width: maxWidth,
height: height,
),
), ),
..._buildBottomWidget, ..._buildBottomWidget,
], ],
@@ -270,11 +293,17 @@ class _LiveRoomPageState extends State<LiveRoomPage>
Widget get _buildPP { Widget get _buildPP {
final isFullScreen = this.isFullScreen; final isFullScreen = this.isFullScreen;
final bottomHeight = 85.0 + padding.bottom;
final height = isFullScreen
? maxHeight
: maxHeight - padding.top - kToolbarHeight - bottomHeight;
Widget child = Stack( Widget child = Stack(
clipBehavior: Clip.none, clipBehavior: Clip.none,
children: [ children: [
Positioned.fill( Positioned.fill(
child: videoPlayerPanel( child: videoPlayerPanel(
width: maxWidth,
height: height,
isFullScreen, isFullScreen,
alignment: isFullScreen ? null : Alignment.topCenter, alignment: isFullScreen ? null : Alignment.topCenter,
needDm: isFullScreen, needDm: isFullScreen,
@@ -288,7 +317,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
maintainState: true, maintainState: true,
visible: !isFullScreen, visible: !isFullScreen,
child: SizedBox( child: SizedBox(
height: Get.height * 0.32, height: maxHeight * 0.32,
child: _buildChatWidget(true), child: _buildChatWidget(true),
), ),
), ),
@@ -302,7 +331,10 @@ class _LiveRoomPageState extends State<LiveRoomPage>
children: [ children: [
_buildAppBar, _buildAppBar,
Expanded(child: child), Expanded(child: child),
_buildInputWidget, SizedBox(
height: bottomHeight,
child: _buildInputWidget,
),
], ],
); );
} }
@@ -471,23 +503,23 @@ class _LiveRoomPageState extends State<LiveRoomPage>
Widget get _buildBodyH { Widget get _buildBodyH {
double videoWidth = double videoWidth =
clampDouble(context.height / context.width * 1.08, 0.58, 0.75) * clampDouble(maxHeight / maxWidth * 1.08, 0.58, 0.75) * maxWidth;
context.width;
return Obx( return Obx(
() { () {
final isFullScreen = this.isFullScreen; final isFullScreen = this.isFullScreen;
final size = Get.size; final width = isFullScreen ? maxWidth : videoWidth;
final height = isFullScreen ? maxHeight : maxWidth * 9 / 16;
Widget child = Row( Widget child = Row(
children: [ children: [
Container( Container(
margin: EdgeInsets.only( margin: EdgeInsets.only(bottom: padding.bottom),
bottom: MediaQuery.paddingOf(context).bottom, width: width,
), height: height,
width: isFullScreen ? size.width : videoWidth,
height: isFullScreen ? size.height : size.width * 9 / 16,
child: videoPlayerPanel( child: videoPlayerPanel(
isFullScreen, isFullScreen,
fill: Colors.transparent, fill: Colors.transparent,
width: width,
height: height,
), ),
), ),
Expanded( Expanded(
@@ -531,7 +563,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
top: 5, top: 5,
left: 10, left: 10,
right: 10, right: 10,
bottom: 15 + MediaQuery.paddingOf(context).bottom, bottom: 15 + padding.bottom,
), ),
decoration: const BoxDecoration( decoration: const BoxDecoration(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(

View File

@@ -665,25 +665,21 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
showStatusBar(); showStatusBar();
} }
} }
final height = !isPortrait || isFullScreen
? maxHeight -
(!isPortrait || removeSafeArea
? 0
: padding.top)
: videoDetailController.isExpanding ||
videoDetailController.isCollapsing
? animHeight
: videoDetailController.videoHeight;
return SizedBox( return SizedBox(
height: !isPortrait || isFullScreen
? maxHeight -
(!isPortrait || removeSafeArea
? 0
: padding.top)
: videoDetailController.isExpanding ||
videoDetailController.isCollapsing
? animHeight
: videoDetailController.videoHeight,
width: maxWidth, width: maxWidth,
height: height,
child: videoPlayer( child: videoPlayer(
maxWidth, width: maxWidth,
!isPortrait || isFullScreen height: height,
? maxHeight
: videoDetailController.isExpanding ||
videoDetailController.isCollapsing
? animHeight
: videoDetailController.videoHeight,
), ),
); );
}, },
@@ -964,14 +960,18 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
if (videoDetailController.isVertical.value && enableVerticalExpand) { if (videoDetailController.isVertical.value && enableVerticalExpand) {
final double videoHeight = final double videoHeight =
maxHeight - (removeSafeArea ? 0 : padding.vertical); maxHeight - (removeSafeArea ? 0 : padding.vertical);
final double videoWidth = videoHeight * 9 / 16; final double width = videoHeight * 9 / 16;
final videoWidth = isFullScreen ? maxWidth : width;
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SizedBox( SizedBox(
width: videoWidth,
height: videoHeight, height: videoHeight,
width: isFullScreen ? maxWidth : videoWidth, child: videoPlayer(
child: videoPlayer(videoWidth, videoHeight), width: videoWidth,
height: videoHeight,
),
), ),
Expanded( Expanded(
child: Scaffold( child: Scaffold(
@@ -986,7 +986,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
controller: videoDetailController.tabCtr, controller: videoDetailController.tabCtr,
children: [ children: [
videoIntro( videoIntro(
width: maxWidth - videoWidth, width: maxWidth - width,
height: maxHeight, height: maxHeight,
), ),
if (videoDetailController.showReply) if (videoDetailController.showReply)
@@ -1002,16 +1002,20 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
], ],
); );
} }
final double videoHeight = maxHeight / 2.5;
final shouldShowSeasonPanel = _shouldShowSeasonPanel; final shouldShowSeasonPanel = _shouldShowSeasonPanel;
final double height = maxHeight / 2.5;
final videoHeight = isFullScreen
? maxHeight - (removeSafeArea ? 0 : padding.vertical)
: height;
return Column( return Column(
children: [ children: [
SizedBox( SizedBox(
width: maxWidth, width: maxWidth,
height: isFullScreen height: videoHeight,
? maxHeight - (removeSafeArea ? 0 : padding.vertical) child: videoPlayer(
: videoHeight, width: maxWidth,
child: videoPlayer(maxWidth, videoHeight), height: videoHeight,
),
), ),
Expanded( Expanded(
child: Scaffold( child: Scaffold(
@@ -1032,7 +1036,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
if (shouldShowSeasonPanel) flex++; if (shouldShowSeasonPanel) flex++;
return maxWidth / flex; return maxWidth / flex;
}(), }(),
height: maxHeight - videoHeight, height: maxHeight - height,
), ),
), ),
if (videoDetailController.showReply) if (videoDetailController.showReply)
@@ -1056,20 +1060,24 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
if (videoDetailController.isVertical.value && enableVerticalExpand) { if (videoDetailController.isVertical.value && enableVerticalExpand) {
final double videoHeight = final double videoHeight =
maxHeight - (removeSafeArea ? 0 : padding.top); maxHeight - (removeSafeArea ? 0 : padding.top);
final double videoWidth = videoHeight * 9 / 16; final double width = videoHeight * 9 / 16;
final videoWidth = isFullScreen ? maxWidth : width;
return Row( return Row(
children: [ children: [
if (!isFullScreen) if (!isFullScreen)
Expanded( Expanded(
child: videoIntro( child: videoIntro(
width: (maxWidth - videoWidth) / 2, width: (maxWidth - width) / 2,
height: maxHeight, height: maxHeight,
), ),
), ),
SizedBox( SizedBox(
width: videoWidth,
height: videoHeight, height: videoHeight,
width: isFullScreen ? maxWidth : videoWidth, child: videoPlayer(
child: videoPlayer(videoWidth, videoHeight), width: videoWidth,
height: videoHeight,
),
), ),
Expanded( Expanded(
child: Scaffold( child: Scaffold(
@@ -1096,12 +1104,13 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
], ],
); );
} }
double videoWidth = double width =
clampDouble(maxHeight / maxWidth * 1.08, 0.5, 0.7) * maxWidth; clampDouble(maxHeight / maxWidth * 1.08, 0.5, 0.7) * maxWidth;
if (maxWidth >= 560) { if (maxWidth >= 560) {
videoWidth = min(videoWidth, maxWidth - 280); width = min(width, maxWidth - 280);
} }
final double videoHeight = videoWidth * 9 / 16; final videoWidth = isFullScreen ? maxWidth : width;
final double videoHeight = isFullScreen ? maxHeight : width * 9 / 16;
final introHeight = final introHeight =
maxHeight - videoHeight - (removeSafeArea ? 0 : padding.top); maxHeight - videoHeight - (removeSafeArea ? 0 : padding.top);
return Row( return Row(
@@ -1109,17 +1118,20 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
Column( Column(
children: [ children: [
SizedBox( SizedBox(
width: isFullScreen ? maxWidth : videoWidth, width: videoWidth,
height: isFullScreen ? maxHeight : videoHeight, height: videoHeight,
child: videoPlayer(videoWidth, videoHeight), child: videoPlayer(
width: videoWidth,
height: videoHeight,
),
), ),
Offstage( Offstage(
offstage: isFullScreen, offstage: isFullScreen,
child: SizedBox( child: SizedBox(
width: videoWidth, width: width,
height: introHeight, height: introHeight,
child: videoIntro( child: videoIntro(
width: videoWidth, width: width,
height: introHeight, height: introHeight,
needRelated: false, needRelated: false,
needCtr: false, needCtr: false,
@@ -1132,9 +1144,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
offstage: isFullScreen, offstage: isFullScreen,
child: SizedBox( child: SizedBox(
width: width:
maxWidth - maxWidth - width - (removeSafeArea ? 0 : padding.horizontal),
videoWidth -
(removeSafeArea ? 0 : padding.horizontal),
height: maxHeight - (removeSafeArea ? 0 : padding.top), height: maxHeight - (removeSafeArea ? 0 : padding.top),
child: Scaffold( child: Scaffold(
key: videoDetailController.childKey, key: videoDetailController.childKey,
@@ -1372,7 +1382,11 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
return const SizedBox.shrink(); return const SizedBox.shrink();
}); });
Widget plPlayer([bool isPipMode = false]) => Obx( Widget plPlayer({
required double width,
required double height,
bool isPipMode = false,
}) => Obx(
key: videoPlayerKey, key: videoPlayerKey,
() => () =>
videoDetailController.videoState.value is! Success || videoDetailController.videoState.value is! Success ||
@@ -1381,6 +1395,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
? const SizedBox.shrink() ? const SizedBox.shrink()
: PLVideoPlayer( : PLVideoPlayer(
key: playerKey, key: playerKey,
maxWidth: width,
maxHeight: height,
plPlayerController: plPlayerController!, plPlayerController: plPlayerController!,
videoDetailController: videoDetailController, videoDetailController: videoDetailController,
introController: videoDetailController.isUgc introController: videoDetailController.isUgc
@@ -1410,7 +1426,9 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
Widget autoChoose(Widget childWhenDisabled) { Widget autoChoose(Widget childWhenDisabled) {
if (Platform.isAndroid) { if (Platform.isAndroid) {
return Floating().isPipMode ? plPlayer(true) : childWhenDisabled; return Floating().isPipMode
? plPlayer(width: maxWidth, height: maxHeight, isPipMode: true)
: childWhenDisabled;
} }
return childWhenDisabled; return childWhenDisabled;
} }
@@ -1428,7 +1446,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
builder: (context, constraints) { builder: (context, constraints) {
maxWidth = constraints.maxWidth; maxWidth = constraints.maxWidth;
maxHeight = constraints.maxHeight; maxHeight = constraints.maxHeight;
isPortrait = maxHeight > maxWidth; isPortrait = maxHeight >= maxWidth;
if (!videoDetailController.horizontalScreen) { if (!videoDetailController.horizontalScreen) {
return autoChoose(childWhenDisabled); return autoChoose(childWhenDisabled);
@@ -1599,7 +1617,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
); );
} }
Widget videoPlayer(double videoWidth, double videoHeight) { Widget videoPlayer({required double width, required double height}) {
final isFullScreen = this.isFullScreen; final isFullScreen = this.isFullScreen;
return PopScope( return PopScope(
canPop: canPop:
@@ -1611,7 +1629,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
children: [ children: [
const Positioned.fill(child: ColoredBox(color: Colors.black)), const Positioned.fill(child: ColoredBox(color: Colors.black)),
if (isShowing) plPlayer(), if (isShowing) plPlayer(width: width, height: height),
Obx(() { Obx(() {
if (!videoDetailController.autoPlay.value) { if (!videoDetailController.autoPlay.value) {
@@ -1621,12 +1639,12 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
child: Obx( child: Obx(
() => CachedNetworkImage( () => CachedNetworkImage(
imageUrl: videoDetailController.cover.value.http2https, imageUrl: videoDetailController.cover.value.http2https,
width: videoWidth, width: width,
height: videoHeight, height: height,
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: width.cacheSize(context),
placeholder: (context, url) => Center( placeholder: (context, url) => Center(
child: Image.asset('assets/images/loading.png'), child: Image.asset('assets/images/loading.png'),
), ),

File diff suppressed because it is too large Load Diff

View File

@@ -10,14 +10,17 @@ import 'package:flutter/rendering.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class BottomControl extends StatelessWidget { class BottomControl extends StatelessWidget {
final PlPlayerController controller;
final Function buildBottomControl;
const BottomControl({ const BottomControl({
required this.controller, required this.controller,
required this.buildBottomControl, required this.buildBottomControl,
required this.maxWidth,
super.key, super.key,
}); });
final PlPlayerController controller;
final Widget Function(double maxWidth) buildBottomControl;
final double maxWidth;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
@@ -51,7 +54,7 @@ class BottomControl extends StatelessWidget {
buildDmChart(theme, controller, 4.5), buildDmChart(theme, controller, 4.5),
if (controller.viewPointList.isNotEmpty && if (controller.viewPointList.isNotEmpty &&
controller.showVP.value) controller.showVP.value)
buildViewPointWidget(controller, 8.75), buildViewPointWidget(controller, 8.75, maxWidth),
ProgressBar( ProgressBar(
progress: Duration(seconds: value), progress: Duration(seconds: value),
buffered: Duration(seconds: buffer), buffered: Duration(seconds: buffer),
@@ -146,7 +149,7 @@ class BottomControl extends StatelessWidget {
left: 0, left: 0,
right: 0, right: 0,
bottom: 18, bottom: 18,
child: buildSeekPreviewWidget(controller), child: buildSeekPreviewWidget(controller, maxWidth),
), ),
], ],
), ),
@@ -154,7 +157,7 @@ class BottomControl extends StatelessWidget {
); );
}, },
), ),
buildBottomControl(), buildBottomControl(maxWidth),
const SizedBox(height: 12), const SizedBox(height: 12),
], ],
), ),