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.

350 lines
8.5 KiB

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:recook/widgets/play_widget/utils.dart';
import 'package:video_player/video_player.dart';
import 'chewie_progress_colors.dart';
import 'material_progress_bar.dart';
class ShortVideoController extends StatefulWidget {
VideoPlayerController controller;
@override
State<StatefulWidget> createState() {
return _MaterialControlsState(controller);
}
ShortVideoController(this.controller);
}
class _MaterialControlsState extends State<ShortVideoController> {
VideoPlayerValue _latestValue;
double _latestVolume;
bool _hideStuff = true;
Timer _hideTimer;
Timer _initTimer;
Timer _showAfterExpandCollapseTimer;
bool _dragging = false;
bool _displayTapped = false;
bool _isChangeTime = false;
final barHeight = 48.0;
final marginSize = 5.0;
VideoPlayerController controller;
_MaterialControlsState(this.controller) {
_latestValue = this.controller.value;
}
@override
void initState() {
// TODO: implement initState
super.initState();
_initialize();
}
@override
Widget build(BuildContext context) {
return MouseRegion(
onHover: (_) {
_cancelAndRestartTimer();
},
child: GestureDetector(
onTap: () {
_cancelAndRestartTimer();
_playPause();
},
child: AbsorbPointer(
absorbing: _hideStuff,
child: Column(
children: <Widget>[
// _latestValue != null &&
// !_latestValue.isPlaying &&
// _latestValue.duration == null ||
if (_latestValue.isBuffering)
const Expanded(
child: Center(
child: CircularProgressIndicator(),
),
)
else
_buildHitArea(),
_buildBottomBar(context),
SizedBox(height: 20,)
],
),
),
),
);
}
@override
void dispose() {
_dispose();
super.dispose();
}
void _dispose() {
controller.removeListener(_updateState);
_hideTimer?.cancel();
_initTimer?.cancel();
_showAfterExpandCollapseTimer?.cancel();
}
AnimatedOpacity _buildBottomBar(
BuildContext context,
) {
final iconColor = Colors.white;
return AnimatedOpacity(
opacity: _hideStuff ? 0.0 : 1.0,
duration: Duration(milliseconds: 300),
child: Container(
height: barHeight,
color: Colors.transparent,
child: Column(
children: <Widget>[
//_buildPlayPause(controller),
_isChangeTime?_buildPosition(iconColor):SizedBox(height: 15.5,),
_buildProgressBar(),
//_buildMuteButton(controller),
],
),
),
);
}
Expanded _buildHitArea() {
return Expanded(
child: GestureDetector(
onTap: () {
_playPause();
if ( _latestValue.isPlaying) {
if (_displayTapped) {
setState(() {
_hideStuff = true;
});
} else
_cancelAndRestartTimer();
} else {
setState(() {
_hideStuff = false;
});
}
},
child: Container(
color: Colors.transparent,
child: Center(
child: AnimatedOpacity(
opacity:
!_latestValue.isPlaying && !_dragging
? 1.0
: 0.0,
duration: Duration(milliseconds: 300),
child: GestureDetector(
child: Container(
// decoration: BoxDecoration(
// color: Colors.white.withOpacity(0.3),
// borderRadius: BorderRadius.circular(48.0),
// ),
child: Padding(
padding: EdgeInsets.all(12.0),
child: Icon(Icons.play_arrow_rounded, size: 112.0,color: Colors.white.withOpacity(0.3),),
),
),
),
),
),
),
),
);
}
GestureDetector _buildMuteButton(
VideoPlayerController controller,
) {
return GestureDetector(
onTap: () {
_cancelAndRestartTimer();
if (_latestValue.volume == 0) {
controller.setVolume(_latestVolume ?? 0.5);
} else {
_latestVolume = controller.value.volume;
controller.setVolume(0.0);
}
},
child: AnimatedOpacity(
opacity: _hideStuff ? 0.0 : 1.0,
duration: Duration(milliseconds: 300),
child: ClipRect(
child: Container(
child: Container(
height: barHeight,
padding: EdgeInsets.only(
left: 8.0,
right: 8.0,
),
child: Icon(
(_latestValue != null && _latestValue.volume > 0)
? Icons.volume_up
: Icons.volume_off,
),
),
),
),
),
);
}
GestureDetector _buildPlayPause(VideoPlayerController controller) {
return GestureDetector(
onTap: _playPause,
child: Container(
height: barHeight,
color: Colors.transparent,
margin: EdgeInsets.only(left: 8.0, right: 4.0),
padding: EdgeInsets.only(
left: 12.0,
right: 12.0,
),
child: Icon(
controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
);
}
Widget _buildPosition(Color iconColor) {
final position = _latestValue != null && _latestValue.position != null
? _latestValue.position
: Duration.zero;
final duration = _latestValue != null && _latestValue.duration != null
? _latestValue.duration
: Duration.zero;
return Padding(
padding: EdgeInsets.only(right: 24.0),
child: Text(
'${formatDuration(position)} / ${formatDuration(duration)}',
style: TextStyle(
fontSize: 14.0,
),
),
);
}
void _cancelAndRestartTimer() {
_hideTimer?.cancel();
_startHideTimer();
setState(() {
_hideStuff = false;
_displayTapped = true;
});
}
Future<Null> _initialize() async {
controller.addListener(_updateState);
_updateState();
if (controller.value.isPlaying) {
_startHideTimer();
}
_initTimer = Timer(Duration(milliseconds: 200), () {
setState(() {
_hideStuff = false;
});
});
}
void _playPause() {
bool isFinished;
if (_latestValue.duration != null) {
isFinished = _latestValue.position >= _latestValue.duration;
} else {
isFinished = false;
}
setState(() {
if (controller.value.isPlaying) {
_hideStuff = false;
_hideTimer?.cancel();
controller.pause();
} else {
_cancelAndRestartTimer();
controller.play();
if (!controller.value.isInitialized) {
controller.initialize().then((_) {
controller.play();
});
} else {
print('_playPause.else');
if (isFinished) {
controller.seekTo(Duration(seconds: 0));
}
controller.play();
}
}
});
}
void _startHideTimer() {
_hideTimer = Timer(const Duration(seconds: 3), () {
setState(() {
_hideStuff = true;
});
});
}
void _updateState() {
setState(() {
_latestValue = controller.value;
});
}
Widget _buildProgressBar() {
return Expanded(
child: Padding(
padding: EdgeInsets.only(right: 20.0,left: 20.0),
child: MaterialVideoProgressBar(
controller,
onDragStart: () {
setState(() {
_dragging = true;
_isChangeTime = true;
});
_hideTimer?.cancel();
},
onDragEnd: () {
setState(() {
_dragging = false;
_isChangeTime = false;
});
_startHideTimer();
},
onDragUpdate: (){
if(!controller.value.isPlaying)
controller.play();
},
colors: ChewieProgressColors(
playedColor: Colors.white,
handleColor: Colors.white,
bufferedColor: Color(0xFF999999),
backgroundColor: Color(0xFF999999),
),
),
)
);
}
}