diff --git a/lib/pages/video/video_controller.dart b/lib/pages/video/video_controller.dart index 6ac08cb..bb6b39d 100644 --- a/lib/pages/video/video_controller.dart +++ b/lib/pages/video/video_controller.dart @@ -63,6 +63,10 @@ abstract class _VideoController with Store { @observable double brightness = 0; + // 播放器倍速 + @observable + double playerSpeed = 1.0; + // 安卓全屏状态 @observable bool androidFullscreen = false; @@ -72,6 +76,16 @@ abstract class _VideoController with Store { String title = ''; String from = '/tab/popular/'; + Future setPlaybackSpeed(double playerSpeed) async { + final PlayerController playerController = Modular.get(); + try { + playerController.mediaPlayer.setRate(playerSpeed); + } catch(e) { + debugPrint(e.toString()); + } + this.playerSpeed = playerSpeed; + } + Future changeEpisode(int episode) async { final PlayerController playerController = Modular.get(); final PopularController popularController = @@ -92,6 +106,7 @@ abstract class _VideoController with Store { } catch (e) { debugPrint(e.toString()); } + playerSpeed = 1.0; await playerController.init(); } diff --git a/lib/pages/video/video_controller.g.dart b/lib/pages/video/video_controller.g.dart index 7177f0f..464cec8 100644 --- a/lib/pages/video/video_controller.g.dart +++ b/lib/pages/video/video_controller.g.dart @@ -249,6 +249,22 @@ mixin _$VideoController on _VideoController, Store { }); } + late final _$playerSpeedAtom = + Atom(name: '_VideoController.playerSpeed', context: context); + + @override + double get playerSpeed { + _$playerSpeedAtom.reportRead(); + return super.playerSpeed; + } + + @override + set playerSpeed(double value) { + _$playerSpeedAtom.reportWrite(value, super.playerSpeed, () { + super.playerSpeed = value; + }); + } + late final _$androidFullscreenAtom = Atom(name: '_VideoController.androidFullscreen', context: context); @@ -283,6 +299,7 @@ showBrightness: ${showBrightness}, showVolume: ${showVolume}, volume: ${volume}, brightness: ${brightness}, +playerSpeed: ${playerSpeed}, androidFullscreen: ${androidFullscreen} '''; } diff --git a/lib/pages/video/video_page.dart b/lib/pages/video/video_page.dart index f56612c..683604f 100644 --- a/lib/pages/video/video_page.dart +++ b/lib/pages/video/video_page.dart @@ -61,7 +61,7 @@ class _VideoPageState extends State with WindowListener { @override void initState() { super.initState(); - // videoController.episode = 1; + videoController.playerSpeed = 1.0; playerController.videoUrl = videoController.videoUrl; playerController.videoCookie = videoController.videoCookie; playerController.init(); @@ -73,6 +73,11 @@ class _VideoPageState extends State with WindowListener { debugPrint(e.toString()); } playerTimer = getPlayerTimer(); + try { + playerController.mediaPlayer.setRate(videoController.playerSpeed); + } catch(e) { + debugPrint(e.toString()); + } } @override @@ -146,26 +151,79 @@ class _VideoPageState extends State with WindowListener { } catch (_) {} } - Future raiseVolume(double value) async { - try { - FlutterVolumeController.updateShowSystemUI(false); - await FlutterVolumeController.raiseVolume(value); - } catch (_) {} - } - - Future lowerVolume(double value) async { - try { - FlutterVolumeController.updateShowSystemUI(false); - await FlutterVolumeController.lowerVolume(value); - } catch (_) {} - } - Future setBrightness(double value) async { try { await ScreenBrightness().setScreenBrightness(value); } catch (_) {} } + // 选择倍速 + void showSetSpeedSheet() { + final double currentSpeed = videoController.playerSpeed; + final List speedsList = [ + 0.25, + 0.5, + 0.75, + 1.0, + 1.25, + 1.5, + 1.75, + 2.0 + ]; + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('播放速度'), + content: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return Wrap( + spacing: 8, + runSpacing: 2, + children: [ + for (final double i in speedsList) ...[ + if (i == currentSpeed) ...[ + FilledButton( + onPressed: () async { + await videoController.setPlaybackSpeed(i); + Modular.to.pop(); + }, + child: Text(i.toString()), + ), + ] else ...[ + FilledButton.tonal( + onPressed: () async { + await videoController.setPlaybackSpeed(i); + Modular.to.pop(); + }, + child: Text(i.toString()), + ), + ] + ] + ], + ); + }), + actions: [ + TextButton( + onPressed: () => Modular.to.pop(), + child: Text( + '取消', + style: TextStyle(color: Theme.of(context).colorScheme.outline), + ), + ), + TextButton( + onPressed: () async { + await videoController.setPlaybackSpeed(1.0); + Modular.to.pop(); + }, + child: const Text('默认速度'), + ), + ], + ); + }, + ); + } + @override Widget build(BuildContext context) { navigationBarState = Platform.isWindows @@ -449,6 +507,33 @@ class _VideoPageState extends State with WindowListener { ) : Container(), + // 倍速条 + (videoController.showPositioned || + !playerController.mediaPlayer.state.playing) + ? Positioned( + top: 0, + right: 0, + child: SizedBox( + width: 45, + height: 34, + child: TextButton( + style: ButtonStyle( + padding: MaterialStateProperty.all( + EdgeInsets.zero), + ), + onPressed: () => showSetSpeedSheet(), + child: Text( + '${videoController.playerSpeed}X', + style: const TextStyle( + color: Colors.white, + fontSize: 12, + ), + ), + ), + ), + ) + : Container(), + // 自定义播放器底部组件 (videoController.showPositioned || !playerController.mediaPlayer.state.playing)