feat: 快进、快退、拖动时时间戳展示、关闭自动播放时处理、单p播放完成处理

This commit is contained in:
guozhigq
2023-08-01 22:51:33 +08:00
parent b947397333
commit e97abb545f
9 changed files with 585 additions and 40 deletions

View File

@ -0,0 +1,84 @@
import 'dart:async';
import 'package:flutter/material.dart';
class BackwardSeekIndicator extends StatefulWidget {
final void Function(Duration) onChanged;
final void Function(Duration) onSubmitted;
const BackwardSeekIndicator({
Key? key,
required this.onChanged,
required this.onSubmitted,
}) : super(key: key);
@override
State<BackwardSeekIndicator> createState() => BackwardSeekIndicatorState();
}
class BackwardSeekIndicatorState extends State<BackwardSeekIndicator> {
Duration value = const Duration(seconds: 10);
Timer? timer;
@override
void initState() {
super.initState();
timer = Timer(const Duration(milliseconds: 400), () {
widget.onSubmitted.call(value);
});
}
void increment() {
timer?.cancel();
timer = Timer(const Duration(milliseconds: 400), () {
widget.onSubmitted.call(value);
});
widget.onChanged.call(value);
// 重复点击 快退秒数累加10
setState(() {
value += const Duration(seconds: 10);
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0x88767676),
Color(0x00767676),
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
child: InkWell(
splashColor: const Color(0x44767676),
onTap: increment,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.fast_rewind,
size: 24.0,
color: Color(0xFFFFFFFF),
),
const SizedBox(height: 8.0),
Text(
'快退${value.inSeconds}',
style: const TextStyle(
fontSize: 12.0,
color: Color(0xFFFFFFFF),
),
),
],
),
),
),
);
}
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
import 'package:pilipala/plugin/pl_player/index.dart';
import 'package:pilipala/plugin/pl_player/widgets/play_pause_btn.dart';
import '../utils.dart';
@ -56,6 +57,9 @@ class BottomControl extends StatelessWidget implements PreferredSizeWidget {
onDragStart: (duration) {
_.onChangedSliderStart();
},
onDragUpdate: (duration) {
_.onUodatedSliderProgress(duration.timeStamp);
},
onSeek: (duration) {
_.onChangedSliderEnd();
_.onChangedSlider(duration.inSeconds.toDouble());
@ -80,7 +84,10 @@ class BottomControl extends StatelessWidget implements PreferredSizeWidget {
// fuc: () => _.togglePlay(),
// ),
// ),
// const SizedBox(width: 6),
PlayOrPauseButton(
controller: _,
),
const SizedBox(width: 4),
// 播放时间
Obx(() {
return Text(

View File

@ -0,0 +1,84 @@
import 'dart:async';
import 'package:flutter/material.dart';
class ForwardSeekIndicator extends StatefulWidget {
final void Function(Duration) onChanged;
final void Function(Duration) onSubmitted;
const ForwardSeekIndicator({
Key? key,
required this.onChanged,
required this.onSubmitted,
}) : super(key: key);
@override
State<ForwardSeekIndicator> createState() => ForwardSeekIndicatorState();
}
class ForwardSeekIndicatorState extends State<ForwardSeekIndicator> {
Duration value = const Duration(seconds: 10);
Timer? timer;
@override
void initState() {
super.initState();
timer = Timer(const Duration(milliseconds: 400), () {
widget.onSubmitted.call(value);
});
}
void increment() {
timer?.cancel();
timer = Timer(const Duration(milliseconds: 400), () {
widget.onSubmitted.call(value);
});
widget.onChanged.call(value);
// 重复点击 快进秒数累加10
setState(() {
value += const Duration(seconds: 10);
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0x00767676),
Color(0x88767676),
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
child: InkWell(
splashColor: const Color(0x44767676),
onTap: increment,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.fast_forward,
size: 24.0,
color: Color(0xFFFFFFFF),
),
const SizedBox(height: 8.0),
Text(
'快进${value.inSeconds}',
style: const TextStyle(
fontSize: 12.0,
color: Color(0xFFFFFFFF),
),
),
],
),
),
),
);
}
}

View File

@ -0,0 +1,89 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:media_kit/media_kit.dart';
import 'package:pilipala/plugin/pl_player/index.dart';
class PlayOrPauseButton extends StatefulWidget {
final double? iconSize;
final Color? iconColor;
final PlPlayerController? controller;
const PlayOrPauseButton({
super.key,
this.iconSize,
this.iconColor,
this.controller,
});
@override
PlayOrPauseButtonState createState() => PlayOrPauseButtonState();
}
class PlayOrPauseButtonState extends State<PlayOrPauseButton>
with SingleTickerProviderStateMixin {
late final AnimationController animation;
StreamSubscription<bool>? subscription;
late Player player;
bool isOpacity = false;
@override
void initState() {
super.initState();
player = widget.controller!.videoPlayerController!;
animation = AnimationController(
vsync: this,
value: player.state.playing ? 1 : 0,
duration: const Duration(milliseconds: 200),
);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
subscription ??= player.stream.playing.listen((event) {
if (event) {
animation.forward().then((value) => {
isOpacity = true,
});
} else {
animation.reverse().then((value) => {isOpacity = false});
}
setState(() {});
});
}
@override
void dispose() {
animation.dispose();
subscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: 34,
height: 34,
child: IconButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: player.playOrPause,
color: Colors.white,
iconSize: 20,
// iconSize: widget.iconSize ?? _theme(context).buttonBarButtonSize,
// color: widget.iconColor ?? _theme(context).buttonBarButtonColor,
icon: AnimatedIcon(
progress: animation,
icon: AnimatedIcons.play_pause,
color: Colors.white,
size: 20,
// size: widget.iconSize ?? _theme(context).buttonBarButtonSize,
// color: widget.iconColor ?? _theme(context).buttonBarButtonColor,
),
),
);
}
}