From 1bebb32a0d4f6b53f23d09904c9d5b244c12399b Mon Sep 17 00:00:00 2001 From: guozhigq Date: Mon, 4 Sep 2023 15:01:02 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E7=9B=B4=E6=92=AD=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/liveRoom/view.dart | 121 +++++------------- .../liveRoom/widgets/bottom_control.dart | 118 +++++++++++++++++ lib/plugin/pl_player/controller.dart | 5 + lib/plugin/pl_player/view.dart | 48 ++++--- 4 files changed, 182 insertions(+), 110 deletions(-) create mode 100644 lib/pages/liveRoom/widgets/bottom_control.dart diff --git a/lib/pages/liveRoom/view.dart b/lib/pages/liveRoom/view.dart index fa881cb8..01718bd2 100644 --- a/lib/pages/liveRoom/view.dart +++ b/lib/pages/liveRoom/view.dart @@ -4,6 +4,7 @@ import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/plugin/pl_player/index.dart'; import 'controller.dart'; +import 'widgets/bottom_control.dart'; class LiveRoomPage extends StatefulWidget { const LiveRoomPage({super.key}); @@ -87,96 +88,38 @@ class _LiveRoomPageState extends State { ), body: Column( children: [ - Hero( - tag: _liveRoomController.heroTag, - child: Stack( - children: [ - AspectRatio( - aspectRatio: 16 / 9, - child: plPlayerController!.videoPlayerController != null - ? PLVideoPlayer(controller: plPlayerController!) - : const SizedBox(), - ), - // if (_liveRoomController.liveItem != null && - // _liveRoomController.liveItem.cover != null) - // Visibility( - // visible: isShowCover, - // child: Positioned( - // top: 0, - // left: 0, - // right: 0, - // child: NetworkImgLayer( - // type: 'emote', - // src: _liveRoomController.liveItem.cover, - // width: Get.size.width, - // height: videoHeight, - // ), - // ), - // ), - ], - ), + Stack( + children: [ + AspectRatio( + aspectRatio: 16 / 9, + child: plPlayerController!.videoPlayerController != null + ? PLVideoPlayer( + controller: plPlayerController!, + bottomControl: BottomControl( + controller: plPlayerController, + liveRoomCtr: _liveRoomController, + ), + ) + : const SizedBox(), + ), + // if (_liveRoomController.liveItem != null && + // _liveRoomController.liveItem.cover != null) + // Visibility( + // visible: isShowCover, + // child: Positioned( + // top: 0, + // left: 0, + // right: 0, + // child: NetworkImgLayer( + // type: 'emote', + // src: _liveRoomController.liveItem.cover, + // width: Get.size.width, + // height: videoHeight, + // ), + // ), + // ), + ], ), - // Container( - // height: 45, - // padding: const EdgeInsets.only(left: 12, right: 12), - // decoration: BoxDecoration( - // color: Theme.of(context).colorScheme.background, - // border: Border( - // bottom: BorderSide( - // color: Theme.of(context).dividerColor.withOpacity(0.1)), - // ), - // ), - // child: Row(children: [ - // SizedBox( - // width: 38, - // height: 38, - // child: IconButton( - // onPressed: () {}, - // icon: const Icon( - // Icons.subtitles_outlined, - // size: 21, - // ), - // ), - // ), - // const Spacer(), - // SizedBox( - // width: 38, - // height: 38, - // child: IconButton( - // onPressed: () {}, - // icon: const Icon( - // Icons.hd_outlined, - // size: 20, - // ), - // ), - // ), - // SizedBox( - // width: 38, - // height: 38, - // child: IconButton( - // onPressed: () => _liveRoomController - // .setVolumn(plPlayerController!.volume.value), - // icon: Obx(() => Icon( - // _liveRoomController.volumeOff.value - // ? Icons.volume_off_outlined - // : Icons.volume_up_outlined, - // size: 21, - // )), - // ), - // ), - // SizedBox( - // width: 38, - // height: 38, - // child: IconButton( - // onPressed: () => {}, - // // plPlayerController!.goToFullscreen(context), - // icon: const Icon( - // Icons.fullscreen, - // ), - // ), - // ), - // ]), - // ), ], ), ); diff --git a/lib/pages/liveRoom/widgets/bottom_control.dart b/lib/pages/liveRoom/widgets/bottom_control.dart new file mode 100644 index 00000000..f538acad --- /dev/null +++ b/lib/pages/liveRoom/widgets/bottom_control.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:hive/hive.dart'; +import 'package:pilipala/models/video/play/url.dart'; +import 'package:pilipala/pages/liveRoom/index.dart'; +import 'package:pilipala/plugin/pl_player/index.dart'; +import 'package:pilipala/utils/storage.dart'; + +class BottomControl extends StatefulWidget implements PreferredSizeWidget { + final PlPlayerController? controller; + final LiveRoomController? liveRoomCtr; + const BottomControl({ + this.controller, + this.liveRoomCtr, + Key? key, + }) : super(key: key); + + @override + State createState() => _BottomControlState(); + + @override + Size get preferredSize => throw UnimplementedError(); +} + +class _BottomControlState extends State { + late PlayUrlModel videoInfo; + List playSpeed = PlaySpeed.values; + TextStyle subTitleStyle = const TextStyle(fontSize: 12); + TextStyle titleStyle = const TextStyle(fontSize: 14); + Size get preferredSize => const Size(double.infinity, kToolbarHeight); + Box localCache = GStrorage.localCache; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + const textStyle = TextStyle( + color: Colors.white, + fontSize: 12, + ); + return AppBar( + backgroundColor: Colors.transparent, + foregroundColor: Colors.white, + elevation: 0, + scrolledUnderElevation: 0, + primary: false, + centerTitle: false, + automaticallyImplyLeading: false, + titleSpacing: 14, + title: Row( + children: [ + ComBtn( + icon: const Icon( + Icons.subtitles_outlined, + size: 18, + color: Colors.white, + ), + fuc: () => Get.back(), + ), + const SizedBox(width: 4), + const Spacer(), + const SizedBox(width: 4), + ComBtn( + icon: const Icon( + Icons.hd_outlined, + size: 18, + color: Colors.white, + ), + fuc: () => {}, + ), + const SizedBox(width: 4), + Obx( + () => ComBtn( + icon: Icon( + widget.liveRoomCtr!.volumeOff.value + ? Icons.volume_off_outlined + : Icons.volume_up_outlined, + size: 18, + color: Colors.white, + ), + fuc: () => {}, + ), + ), + const SizedBox(width: 4), + ComBtn( + icon: const Icon( + Icons.fullscreen, + size: 20, + color: Colors.white, + ), + fuc: () => widget.controller!.triggerFullScreen(), + ), + ], + ), + ); + } +} + +class MSliderTrackShape extends RoundedRectSliderTrackShape { + @override + Rect getPreferredRect({ + required RenderBox parentBox, + Offset offset = Offset.zero, + SliderThemeData? sliderTheme, + bool isEnabled = false, + bool isDiscrete = false, + }) { + const double trackHeight = 3; + final double trackLeft = offset.dx; + final double trackTop = + offset.dy + (parentBox.size.height - trackHeight) / 2 + 4; + final double trackWidth = parentBox.size.width; + return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight); + } +} diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 386524b9..81c20d99 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -105,6 +105,7 @@ class PlPlayerController { ]; PreferredSizeWidget? headerControl; + PreferredSizeWidget? bottomControl; Widget? danmuWidget; /// 数据加载监听 @@ -819,6 +820,7 @@ class PlPlayerController { child: PLVideoPlayer( controller: this, headerControl: headerControl, + bottomControl: bottomControl, danmuWidget: danmuWidget, ), ), @@ -867,6 +869,9 @@ class PlPlayerController { if (!_enableHeart) { return false; } + if (videoType.value == 'live') { + return; + } // 播放状态变化时,更新 if (type == 'status') { await VideoHttp.heartBeat( diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index 1b3703d4..5e7416bf 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -29,11 +29,13 @@ import 'widgets/forward_seek.dart'; class PLVideoPlayer extends StatefulWidget { final PlPlayerController controller; final PreferredSizeWidget? headerControl; + final PreferredSizeWidget? bottomControl; final Widget? danmuWidget; const PLVideoPlayer({ required this.controller, this.headerControl, + this.bottomControl, this.danmuWidget, super.key, }); @@ -120,6 +122,7 @@ class _PLVideoPlayerState extends State vsync: this, duration: const Duration(milliseconds: 300)); videoController = widget.controller.videoController!; widget.controller.headerControl = widget.headerControl; + widget.controller.bottomControl = widget.bottomControl; widget.controller.danmuWidget = widget.danmuWidget; defaultBtmProgressBehavior = setting.get(SettingBoxKey.btmProgressBehavior, defaultValue: BtmProgresBehavior.values.first.code); @@ -562,34 +565,33 @@ class _PLVideoPlayerState extends State // 头部、底部控制条 Obx( - () => Visibility( - visible: _.videoType.value != 'live', - child: Column( - children: [ - if (widget.headerControl != null) - ClipRect( - clipBehavior: Clip.hardEdge, - child: AppBarAni( - controller: animationController, - visible: !_.controlsLock.value && _.showControls.value, - position: 'top', - child: widget.headerControl!, - ), - ), - const Spacer(), + () => Column( + children: [ + if (widget.headerControl != null) ClipRect( clipBehavior: Clip.hardEdge, child: AppBarAni( controller: animationController, visible: !_.controlsLock.value && _.showControls.value, - position: 'bottom', - child: BottomControl( - controller: widget.controller, - triggerFullScreen: widget.controller.triggerFullScreen), + position: 'top', + child: widget.headerControl!, ), ), - ], - ), + const Spacer(), + ClipRect( + clipBehavior: Clip.hardEdge, + child: AppBarAni( + controller: animationController, + visible: !_.controlsLock.value && _.showControls.value, + position: 'bottom', + child: widget.bottomControl ?? + BottomControl( + controller: widget.controller, + triggerFullScreen: + widget.controller.triggerFullScreen), + ), + ), + ], ), ), @@ -608,6 +610,10 @@ class _PLVideoPlayerState extends State !_.isFullScreen.value) { return Container(); } + + if (_.videoType.value == 'live') { + return Container(); + } if (value > max || max <= 0) { return Container(); }