You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.7 KiB
179 lines
4.7 KiB
import 'package:flutter/material.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:video_player/video_player.dart';
|
|
import 'chewie_progress_colors.dart';
|
|
|
|
class MaterialVideoProgressBar extends StatefulWidget {
|
|
MaterialVideoProgressBar(
|
|
this.controller, {
|
|
ChewieProgressColors colors,
|
|
this.onDragEnd,
|
|
this.onDragStart,
|
|
this.onDragUpdate,
|
|
}) : colors = colors ?? ChewieProgressColors();
|
|
|
|
final VideoPlayerController controller;
|
|
final ChewieProgressColors colors;
|
|
final Function() onDragStart;
|
|
final Function() onDragEnd;
|
|
final Function() onDragUpdate;
|
|
|
|
@override
|
|
_VideoProgressBarState createState() {
|
|
return _VideoProgressBarState();
|
|
}
|
|
}
|
|
|
|
class _VideoProgressBarState extends State<MaterialVideoProgressBar> {
|
|
_VideoProgressBarState() {
|
|
listener = () {
|
|
setState(() {});
|
|
};
|
|
}
|
|
|
|
VoidCallback listener;
|
|
bool _controllerWasPlaying = false;
|
|
|
|
VideoPlayerController get controller => widget.controller;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
controller.addListener(listener);
|
|
}
|
|
|
|
@override
|
|
void deactivate() {
|
|
controller.removeListener(listener);
|
|
super.deactivate();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
void seekToRelativePosition(Offset globalPosition) {
|
|
final box = context.findRenderObject() as RenderBox;
|
|
final Offset tapPos = box.globalToLocal(globalPosition);
|
|
final double relative = tapPos.dx / box.size.width;
|
|
final Duration position = controller.value.duration * relative;
|
|
controller.seekTo(position);
|
|
}
|
|
|
|
return GestureDetector(
|
|
child: Center(
|
|
child: Container(
|
|
height: MediaQuery.of(context).size.height / 2,
|
|
width: MediaQuery.of(context).size.width,
|
|
color: Colors.transparent,
|
|
child: CustomPaint(
|
|
painter: _ProgressBarPainter(
|
|
controller.value,
|
|
widget.colors,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
onHorizontalDragStart: (DragStartDetails details) {
|
|
if (!controller.value.isInitialized) {
|
|
return;
|
|
}
|
|
_controllerWasPlaying = controller.value.isPlaying;
|
|
if (_controllerWasPlaying) {
|
|
controller.pause();
|
|
}
|
|
|
|
if (widget.onDragStart != null) {
|
|
widget.onDragStart();
|
|
}
|
|
},
|
|
onHorizontalDragUpdate: (DragUpdateDetails details) {
|
|
if (!controller.value.isInitialized) {
|
|
return;
|
|
}
|
|
seekToRelativePosition(details.globalPosition);
|
|
|
|
if (widget.onDragUpdate != null) {
|
|
widget.onDragUpdate();
|
|
}
|
|
},
|
|
onHorizontalDragEnd: (DragEndDetails details) {
|
|
if (_controllerWasPlaying) {
|
|
controller.play();
|
|
}
|
|
|
|
if (widget.onDragEnd != null) {
|
|
widget.onDragEnd();
|
|
}
|
|
},
|
|
onTapDown: (TapDownDetails details) {
|
|
if (!controller.value.isInitialized) {
|
|
return;
|
|
}
|
|
seekToRelativePosition(details.globalPosition);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
class _ProgressBarPainter extends CustomPainter {
|
|
_ProgressBarPainter(this.value, this.colors);
|
|
|
|
VideoPlayerValue value;
|
|
ChewieProgressColors colors;
|
|
|
|
@override
|
|
bool shouldRepaint(CustomPainter painter) {
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final height = 2.0;
|
|
|
|
canvas.drawRRect(
|
|
RRect.fromRectAndRadius(
|
|
Rect.fromPoints(
|
|
Offset(0.0, size.height / 2),
|
|
Offset(size.width, size.height / 2 + height),
|
|
),
|
|
Radius.circular(4.0),
|
|
),
|
|
colors.backgroundPaint,
|
|
);
|
|
if (!value.isInitialized) {
|
|
return;
|
|
}
|
|
final double playedPartPercent =
|
|
value.position.inMilliseconds / value.duration.inMilliseconds;
|
|
final double playedPart =
|
|
playedPartPercent > 1 ? size.width : playedPartPercent * size.width;
|
|
for (DurationRange range in value.buffered) {
|
|
final double start = range.startFraction(value.duration) * size.width;
|
|
final double end = range.endFraction(value.duration) * size.width;
|
|
canvas.drawRRect(
|
|
RRect.fromRectAndRadius(
|
|
Rect.fromPoints(
|
|
Offset(start, size.height / 2),
|
|
Offset(end, size.height / 2 + height),
|
|
),
|
|
Radius.circular(4.0),
|
|
),
|
|
colors.bufferedPaint,
|
|
);
|
|
}
|
|
canvas.drawRRect(
|
|
RRect.fromRectAndRadius(
|
|
Rect.fromPoints(
|
|
Offset(0.0, size.height / 2),
|
|
Offset(playedPart, size.height / 2 + height),
|
|
),
|
|
Radius.circular(4.0),
|
|
),
|
|
colors.playedPaint,
|
|
);
|
|
canvas.drawCircle(
|
|
Offset(playedPart, size.height / 2 + height / 2),
|
|
height * 3,
|
|
colors.handlePaint,
|
|
);
|
|
}
|
|
} |