247 lines
6.9 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:common_utils/common_utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:video_player/video_player.dart';
import '../after_layout.dart';
import 'controller_widget.dart';
import 'video_player_control.dart';
class VideoPlayerPan extends StatefulWidget {
VideoPlayerPan({
// this.controlKey,
required this.child,
});
// final GlobalKey<VideoPlayerControlState> controlKey;
final Widget child;
@override
_VideoPlayerPanState createState() => _VideoPlayerPanState();
}
class _VideoPlayerPanState extends State<VideoPlayerPan>
with AfterLayoutMixin<VideoPlayerPan> {
late Offset startPosition; // 起始位置
late double movePan; // 偏移量累计总和
late double layoutWidth; // 组件宽度
late double layoutHeight; // 组件高度
String volumePercentage = ''; // 组件位移描述
double playDialogOpacity = 0.0;
bool allowHorizontal = false; // 是否允许快进
Duration position = const Duration(seconds: 0); // 当前时间
double brightness = 0.0; //亮度
bool brightnessOk = false; // 是否允许调节亮度
VideoPlayerController get controller => ControllerWidget.of(context)!.controller;
bool get videoInit => ControllerWidget.of(context)!.videoInit;
String get title=>ControllerWidget.of(context)!.title;
@override
void afterFirstLayout(BuildContext context) {
_reset(context);
}
@override
void dispose() {
super.dispose();
brightnessOk = false;
allowHorizontal = false;
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onVerticalDragStart: _onVerticalDragStart,
onVerticalDragUpdate: _onVerticalDragUpdate,
onVerticalDragEnd: _onVerticalDragEnd,
onHorizontalDragStart: _onHorizontalDragStart,
onHorizontalDragUpdate: _onHorizontalDragUpdate,
onHorizontalDragEnd: _onHorizontalDragEnd,
child: Container(
child: Stack(
children: <Widget>[
widget.child,
Center(
child: AnimatedOpacity(
opacity: playDialogOpacity,
duration: const Duration(milliseconds: 500),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 6.0),
decoration: const BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.all(Radius.circular(5.0))),
child: Text(
volumePercentage,
style: const TextStyle(color: Colors.white, fontSize: 12),
),
),
),
),
VideoPlayerControl(
key: ControllerWidget.of(context)!.controlKey,
)
],
),
),
);
}
void _onVerticalDragStart(details) async {
_reset(context);
startPosition = details.globalPosition;
if (startPosition.dx < (layoutWidth / 2)) {
/// 左边触摸
// brightness = await Screen.brightness;
brightnessOk = true;
}
}
void _onVerticalDragUpdate(details) {
if (!videoInit) {
return;
}
/// 累计计算偏移量(下滑减少百分比,上滑增加百分比)
movePan += (-details.delta.dy);
if (startPosition.dx < (layoutWidth / 2)) {
/// 左边触摸
if (brightnessOk = true) {
setState(() {
volumePercentage = '${'亮度'.tr}${(_setBrightnessValue() * 100).toInt()}%';
playDialogOpacity = 1.0;
});
}
} else {
/// 右边触摸
setState(() {
volumePercentage = '${'音量'.tr}${(_setVerticalValue(num: 2) * 100).toInt()}%';
playDialogOpacity = 1.0;
});
}
}
void _onVerticalDragEnd(_) async {
if (!videoInit) {
return;
}
if (startPosition.dx < (layoutWidth / 2)) {
if (brightnessOk) {
// await Screen.setBrightness(_setBrightnessValue());
brightnessOk = false;
// 左边触摸
setState(() {
playDialogOpacity = 0.0;
});
}
} else {
// 右边触摸
await controller.setVolume(_setVerticalValue());
setState(() {
playDialogOpacity = 0.0;
});
}
}
double _setBrightnessValue() {
// 亮度百分控制
double value =
double.parse((movePan / layoutHeight + brightness).toStringAsFixed(2));
if (value >= 1.00) {
value = 1.00;
} else if (value <= 0.00) {
value = 0.00;
}
return value;
}
double _setVerticalValue({int num = 1}) {
// 声音亮度百分控制
double value = double.parse(
(movePan / layoutHeight + controller.value.volume)
.toStringAsFixed(num));
if (value >= 1.0) {
value = 1.0;
} else if (value <= 0.0) {
value = 0.0;
}
return value;
}
void _reset(BuildContext context) {
startPosition = const Offset(0, 0);
movePan = 0;
layoutHeight = context.size!.height;
layoutWidth = context.size!.width;
volumePercentage = '';
}
void _onHorizontalDragStart(DragStartDetails details) async {
_reset(context);
if (!videoInit) {
return;
}
// 获取当前时间
position = controller.value.position;
// 暂停成功后才允许快进手势
allowHorizontal = true;
}
void _onHorizontalDragUpdate(DragUpdateDetails details) {
if (!videoInit && !allowHorizontal) {
return;
}
// 累计计算偏移量
movePan += details.delta.dx;
double value = _setHorizontalValue();
// 用百分比计算出当前的秒数
String currentSecond = DateUtil.formatDateMs(
(value * controller.value.duration.inMilliseconds).toInt(),
format: 'mm:ss',
);
if (value >= 0) {
setState(() {
volumePercentage = '${'快进至'.tr}$currentSecond';
playDialogOpacity = 1.0;
});
} else {
setState(() {
volumePercentage = '${'快退至'.tr}${(value * 100).toInt()}%';
playDialogOpacity = 1.0;
});
}
}
void _onHorizontalDragEnd(DragEndDetails details) async {
if (!videoInit && !allowHorizontal) {
return;
}
double value = _setHorizontalValue();
int current =
(value * controller.value.duration.inMilliseconds).toInt();
await controller.seekTo(Duration(milliseconds: current));
allowHorizontal = false;
setState(() {
playDialogOpacity = 0.0;
});
}
double _setHorizontalValue() {
// 进度条百分控制
double valueHorizontal =
double.parse((movePan / layoutWidth).toStringAsFixed(2));
// 当前进度条百分比
double currentValue = position.inMilliseconds /
controller.value.duration.inMilliseconds;
double value =
double.parse((currentValue + valueHorizontal).toStringAsFixed(2));
if (value >= 1.00) {
value = 1.00;
} else if (value <= 0.00) {
value = 0.00;
}
return value;
}
}