diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 10e8f7dd..a72e0df2 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -46,6 +46,7 @@ class PlPlayerController { // 播放位置 final Rx _position = Rx(Duration.zero); final Rx _sliderPosition = Rx(Duration.zero); + // 展示使用 final Rx _sliderTempPosition = Rx(Duration.zero); final Rx _duration = Rx(Duration.zero); final Rx _buffered = Rx(Duration.zero); @@ -450,7 +451,7 @@ class PlPlayerController { } /// 跳转至指定位置 - Future seekTo(Duration position) async { + Future seekTo(Duration position, {type = 'seek'}) async { // if (position >= duration.value) { // position = duration.value - const Duration(milliseconds: 100); // } @@ -459,7 +460,10 @@ class PlPlayerController { } _position.value = position; if (duration.value.inSeconds != 0) { - await _videoPlayerController!.stream.buffer.first; + if (type != 'slider') { + /// 拖动进度条调节时,不等待第一帧,防止抖动 + await _videoPlayerController!.stream.buffer.first; + } await _videoPlayerController?.seek(position); // if (playerStatus.stopped) { // play(); diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index cfb9dad8..7789de62 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -253,13 +253,16 @@ class _PLVideoPlayerState extends State clipBehavior: Clip.hardEdge, fit: StackFit.passthrough, children: [ - Video( - controller: videoController, - controls: NoVideoControls, - subtitleViewConfiguration: SubtitleViewConfiguration( - style: subTitleStyle, - textAlign: TextAlign.center, - padding: const EdgeInsets.all(24.0), + Obx( + () => Video( + controller: videoController, + controls: NoVideoControls, + subtitleViewConfiguration: SubtitleViewConfiguration( + style: subTitleStyle, + textAlign: TextAlign.center, + padding: const EdgeInsets.all(24.0), + ), + fit: _.videoFit.value, ), ), @@ -312,38 +315,40 @@ class _PLVideoPlayerState extends State curve: Curves.easeInOut, opacity: _.isSliderMoving.value ? 1.0 : 0.0, duration: const Duration(milliseconds: 150), - child: Container( - alignment: Alignment.center, - decoration: BoxDecoration( - color: const Color(0x88000000), - borderRadius: BorderRadius.circular(64.0), - ), - height: 34.0, - width: 100.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Obx(() { - return Text( - _.sliderTempPosition.value.inMinutes >= 60 - ? printDurationWithHours( - _.sliderTempPosition.value) - : printDuration(_.sliderTempPosition.value), - style: textStyle, - ); - }), - const SizedBox(width: 2), - const Text('/', style: textStyle), - const SizedBox(width: 2), - Obx( - () => Text( - _.duration.value.inMinutes >= 60 - ? printDurationWithHours(_.duration.value) - : printDuration(_.duration.value), - style: textStyle, + child: IntrinsicWidth( + child: Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: const Color(0x88000000), + borderRadius: BorderRadius.circular(64.0), + ), + height: 34.0, + padding: const EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Obx(() { + return Text( + _.sliderTempPosition.value.inMinutes >= 60 + ? printDurationWithHours( + _.sliderTempPosition.value) + : printDuration(_.sliderTempPosition.value), + style: textStyle, + ); + }), + const SizedBox(width: 2), + const Text('/', style: textStyle), + const SizedBox(width: 2), + Obx( + () => Text( + _.duration.value.inMinutes >= 60 + ? printDurationWithHours(_.duration.value) + : printDuration(_.duration.value), + style: textStyle, + ), ), - ), - ], + ], + ), ), ), ), @@ -539,7 +544,7 @@ class _PLVideoPlayerState extends State return; } _.onChangedSliderEnd(); - _.seekTo(_.sliderPosition.value); + _.seekTo(_.sliderPosition.value, type: 'slider'); }, // 垂直方向 音量/亮度调节 onVerticalDragUpdate: (DragUpdateDetails details) async { @@ -695,9 +700,19 @@ class _PLVideoPlayerState extends State Obx(() { if (_.dataStatus.loading || _.isBuffering.value) { return Center( - child: Image.asset( - 'assets/images/loading.gif', - height: 25, + child: Container( + padding: const EdgeInsets.all(30), + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: RadialGradient( + center: Alignment.center, + colors: [Colors.black26, Colors.transparent], + ), + ), + child: Image.asset( + 'assets/images/loading.gif', + height: 25, + ), ), ); } else { diff --git a/lib/plugin/pl_player/widgets/bottom_control.dart b/lib/plugin/pl_player/widgets/bottom_control.dart index 1cd4c20d..995aef59 100644 --- a/lib/plugin/pl_player/widgets/bottom_control.dart +++ b/lib/plugin/pl_player/widgets/bottom_control.dart @@ -44,29 +44,33 @@ class BottomControl extends StatelessWidget implements PreferredSizeWidget { if (value > max || max <= 0) { return Container(); } - return ProgressBar( - progress: Duration(seconds: value), - buffered: Duration(seconds: buffer), - total: Duration(seconds: max), - progressBarColor: colorTheme, - baseBarColor: Colors.white.withOpacity(0.2), - bufferedBarColor: colorTheme.withOpacity(0.4), - timeLabelLocation: TimeLabelLocation.none, - thumbColor: colorTheme, - barHeight: 3.0, - thumbRadius: 5.5, - onDragStart: (duration) { - feedBack(); - _.onChangedSliderStart(); - }, - onDragUpdate: (duration) { - _.onUodatedSliderProgress(duration.timeStamp); - }, - onSeek: (duration) { - _.onChangedSliderEnd(); - _.onChangedSlider(duration.inSeconds.toDouble()); - _.seekTo(Duration(seconds: duration.inSeconds)); - }, + return Padding( + padding: const EdgeInsets.only(left: 5, right: 5, bottom: 5), + child: ProgressBar( + progress: Duration(seconds: value), + buffered: Duration(seconds: buffer), + total: Duration(seconds: max), + progressBarColor: colorTheme, + baseBarColor: Colors.white.withOpacity(0.2), + bufferedBarColor: colorTheme.withOpacity(0.4), + timeLabelLocation: TimeLabelLocation.none, + thumbColor: colorTheme, + barHeight: 3.0, + thumbRadius: 5.5, + onDragStart: (duration) { + feedBack(); + _.onChangedSliderStart(); + }, + onDragUpdate: (duration) { + _.onUodatedSliderProgress(duration.timeStamp); + }, + onSeek: (duration) { + _.onChangedSliderEnd(); + _.onChangedSlider(duration.inSeconds.toDouble()); + _.seekTo(Duration(seconds: duration.inSeconds), + type: 'slider'); + }, + ), ); }, ),