Skip to content

Commit 4c5eb5f

Browse files
Ortesprateekmedia
authored andcommitted
Add keyboard controls seek forward and backward and fullscreen escape
1 parent 8c76bff commit 4c5eb5f

File tree

1 file changed

+79
-31
lines changed

1 file changed

+79
-31
lines changed

lib/src/material/material_desktop_controls.dart

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:chewie/src/models/option_item.dart';
1212
import 'package:chewie/src/models/subtitle_model.dart';
1313
import 'package:chewie/src/notifiers/index.dart';
1414
import 'package:flutter/material.dart';
15+
import 'package:flutter/services.dart';
1516
import 'package:provider/provider.dart';
1617
import 'package:video_player/video_player.dart';
1718

@@ -49,6 +50,7 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
4950

5051
late VideoPlayerController controller;
5152
ChewieController? _chewieController;
53+
late final FocusNode _focusNode;
5254

5355
// We know that _chewieController is set in didChangeDependencies
5456
ChewieController get chewieController => _chewieController!;
@@ -75,39 +77,55 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
7577
);
7678
}
7779

78-
return MouseRegion(
79-
onHover: (_) {
80-
_cancelAndRestartTimer();
80+
return KeyboardListener(
81+
focusNode: _focusNode,
82+
onKeyEvent: (event) {
83+
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.space) {
84+
_playPause();
85+
} else if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.arrowRight) {
86+
_seekForward();
87+
} else if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.arrowLeft) {
88+
_seekBackward();
89+
} else if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.escape) {
90+
if (chewieController.isFullScreen) {
91+
_onExpandCollapse();
92+
}
93+
}
8194
},
82-
child: GestureDetector(
83-
onTap: () => _cancelAndRestartTimer(),
84-
child: AbsorbPointer(
85-
absorbing: notifier.hideStuff,
86-
child: Stack(
87-
children: [
88-
if (_displayBufferingIndicator)
89-
_chewieController?.bufferingBuilder?.call(context) ??
90-
const Center(
91-
child: CircularProgressIndicator(),
92-
)
93-
else
94-
_buildHitArea(),
95-
Column(
96-
mainAxisAlignment: MainAxisAlignment.end,
97-
children: <Widget>[
98-
if (_subtitleOn)
99-
Transform.translate(
100-
offset: Offset(
101-
0.0,
102-
notifier.hideStuff ? barHeight * 0.8 : 0.0,
95+
child: MouseRegion(
96+
onHover: (_) {
97+
_cancelAndRestartTimer();
98+
},
99+
child: GestureDetector(
100+
onTap: () => _cancelAndRestartTimer(),
101+
child: AbsorbPointer(
102+
absorbing: notifier.hideStuff,
103+
child: Stack(
104+
children: [
105+
if (_displayBufferingIndicator)
106+
_chewieController?.bufferingBuilder?.call(context) ??
107+
const Center(
108+
child: CircularProgressIndicator(),
109+
)
110+
else
111+
_buildHitArea(),
112+
Column(
113+
mainAxisAlignment: MainAxisAlignment.end,
114+
children: <Widget>[
115+
if (_subtitleOn)
116+
Transform.translate(
117+
offset: Offset(
118+
0.0,
119+
notifier.hideStuff ? barHeight * 0.8 : 0.0,
120+
),
121+
child:
122+
_buildSubtitles(context, chewieController.subtitle!),
103123
),
104-
child:
105-
_buildSubtitles(context, chewieController.subtitle!),
106-
),
107-
_buildBottomBar(context),
108-
],
109-
),
110-
],
124+
_buildBottomBar(context),
125+
],
126+
),
127+
],
128+
),
111129
),
112130
),
113131
),
@@ -566,6 +584,36 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
566584
});
567585
}
568586

587+
void _seekBackward() {
588+
_seekRelative(
589+
const Duration(
590+
seconds: -10,
591+
),
592+
);
593+
}
594+
595+
void _seekForward() {
596+
_seekRelative(
597+
const Duration(
598+
seconds: 10,
599+
),
600+
);
601+
}
602+
603+
void _seekRelative(Duration relativeSeek) {
604+
_cancelAndRestartTimer();
605+
final position = _latestValue.position + relativeSeek;
606+
final duration = _latestValue.duration;
607+
608+
if (position < Duration.zero) {
609+
controller.seekTo(Duration.zero);
610+
} else if (position > duration) {
611+
controller.seekTo(duration);
612+
} else {
613+
controller.seekTo(position);
614+
}
615+
}
616+
569617
Widget _buildProgressBar() {
570618
return Expanded(
571619
child: MaterialVideoProgressBar(

0 commit comments

Comments
 (0)