fix: audio null 、 播放器面板响应式优化

This commit is contained in:
guozhigq
2023-09-11 23:21:13 +08:00
parent 74ec4cccea
commit 6d2e0f2049
2 changed files with 238 additions and 221 deletions

View File

@ -48,25 +48,26 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
with TickerProviderStateMixin {
late AnimationController animationController;
late VideoController videoController;
final PLVideoPlayerController _ctr = Get.put(PLVideoPlayerController());
bool _mountSeekBackwardButton = false;
bool _mountSeekForwardButton = false;
bool _hideSeekBackwardButton = false;
bool _hideSeekForwardButton = false;
// bool _mountSeekBackwardButton = false;
// bool _mountSeekForwardButton = false;
// bool _hideSeekBackwardButton = false;
// bool _hideSeekForwardButton = false;
double _brightnessValue = 0.0;
bool _brightnessIndicator = false;
// double _brightnessValue = 0.0;
// bool _brightnessIndicator = false;
Timer? _brightnessTimer;
double _volumeValue = 0.0;
bool _volumeIndicator = false;
// double _volumeValue = 0.0;
// bool _volumeIndicator = false;
Timer? _volumeTimer;
double _distance = 0.0;
// 初始手指落下位置
double _initTapPositoin = 0.0;
bool _volumeInterceptEventStream = false;
// bool _volumeInterceptEventStream = false;
Box setting = GStrorage.setting;
late FullScreenMode mode;
@ -75,15 +76,11 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
late bool enableBackgroundPlay;
void onDoubleTapSeekBackward() {
setState(() {
_mountSeekBackwardButton = true;
});
_ctr.onDoubleTapSeekBackward();
}
void onDoubleTapSeekForward() {
setState(() {
_mountSeekForwardButton = true;
});
_ctr.onDoubleTapSeekForward();
}
// 双击播放、暂停
@ -135,12 +132,10 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Future.microtask(() async {
try {
FlutterVolumeController.showSystemUI = true;
_volumeValue = (await FlutterVolumeController.getVolume())!;
_ctr.volumeValue.value = (await FlutterVolumeController.getVolume())!;
FlutterVolumeController.addListener((value) {
if (mounted && !_volumeInterceptEventStream) {
setState(() {
_volumeValue = value;
});
if (mounted && !_ctr.volumeInterceptEventStream.value) {
_ctr.volumeValue.value = value;
}
});
} catch (_) {}
@ -148,12 +143,10 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Future.microtask(() async {
try {
_brightnessValue = await ScreenBrightness().current;
_ctr.brightnessValue.value = await ScreenBrightness().current;
ScreenBrightness().onCurrentBrightnessChanged.listen((value) {
if (mounted) {
setState(() {
_brightnessValue = value;
});
_ctr.brightnessValue.value = value;
}
});
} catch (_) {}
@ -165,18 +158,14 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
FlutterVolumeController.showSystemUI = false;
await FlutterVolumeController.setVolume(value);
} catch (_) {}
setState(() {
_volumeValue = value;
_volumeIndicator = true;
_volumeInterceptEventStream = true;
});
_ctr.volumeValue.value = value;
_ctr.volumeIndicator.value = true;
_ctr.volumeInterceptEventStream.value = true;
_volumeTimer?.cancel();
_volumeTimer = Timer(const Duration(milliseconds: 200), () {
if (mounted) {
setState(() {
_volumeIndicator = false;
_volumeInterceptEventStream = false;
});
_ctr.volumeIndicator.value = false;
_ctr.volumeInterceptEventStream.value = false;
}
});
}
@ -185,15 +174,11 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
try {
await ScreenBrightness().setScreenBrightness(value);
} catch (_) {}
setState(() {
_brightnessIndicator = true;
});
_ctr.brightnessIndicator.value = true;
_brightnessTimer?.cancel();
_brightnessTimer = Timer(const Duration(milliseconds: 200), () {
if (mounted) {
setState(() {
_brightnessIndicator = false;
});
_ctr.brightnessIndicator.value = false;
}
});
widget.controller.brightness.value = value;
@ -322,103 +307,107 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
),
/// 音量🔊 控制条展示
Align(
alignment: Alignment.center,
child: AnimatedOpacity(
curve: Curves.easeInOut,
opacity: _volumeIndicator ? 1.0 : 0.0,
duration: const Duration(milliseconds: 150),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0x88000000),
borderRadius: BorderRadius.circular(64.0),
),
height: 34.0,
width: 70.0,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 34.0,
width: 28.0,
alignment: Alignment.centerRight,
child: Icon(
_volumeValue == 0.0
? Icons.volume_off
: _volumeValue < 0.5
? Icons.volume_down
: Icons.volume_up,
color: const Color(0xFFFFFFFF),
size: 20.0,
),
),
Expanded(
child: Text(
'${(_volumeValue * 100.0).round()}%',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 13.0,
color: Color(0xFFFFFFFF),
Obx(
() => Align(
alignment: Alignment.center,
child: AnimatedOpacity(
curve: Curves.easeInOut,
opacity: _ctr.volumeIndicator.value ? 1.0 : 0.0,
duration: const Duration(milliseconds: 150),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0x88000000),
borderRadius: BorderRadius.circular(64.0),
),
height: 34.0,
width: 70.0,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 34.0,
width: 28.0,
alignment: Alignment.centerRight,
child: Icon(
_ctr.volumeValue.value == 0.0
? Icons.volume_off
: _ctr.volumeValue.value < 0.5
? Icons.volume_down
: Icons.volume_up,
color: const Color(0xFFFFFFFF),
size: 20.0,
),
),
),
const SizedBox(width: 6.0),
],
Expanded(
child: Text(
'${(_ctr.volumeValue.value * 100.0).round()}%',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 13.0,
color: Color(0xFFFFFFFF),
),
),
),
const SizedBox(width: 6.0),
],
),
),
),
),
),
/// 亮度🌞 控制条展示
Align(
alignment: Alignment.center,
child: AnimatedOpacity(
curve: Curves.easeInOut,
opacity: _brightnessIndicator ? 1.0 : 0.0,
duration: const Duration(milliseconds: 150),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0x88000000),
borderRadius: BorderRadius.circular(64.0),
),
height: 34.0,
width: 70.0,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 30.0,
width: 28.0,
alignment: Alignment.centerRight,
child: Icon(
_brightnessValue < 1.0 / 3.0
? Icons.brightness_low
: _brightnessValue < 2.0 / 3.0
? Icons.brightness_medium
: Icons.brightness_high,
color: const Color(0xFFFFFFFF),
size: 18.0,
),
),
const SizedBox(width: 2.0),
Expanded(
child: Text(
'${(_brightnessValue * 100.0).round()}%',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 13.0,
color: Color(0xFFFFFFFF),
Obx(
() => Align(
alignment: Alignment.center,
child: AnimatedOpacity(
curve: Curves.easeInOut,
opacity: _ctr.brightnessIndicator.value ? 1.0 : 0.0,
duration: const Duration(milliseconds: 150),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0x88000000),
borderRadius: BorderRadius.circular(64.0),
),
height: 34.0,
width: 70.0,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 30.0,
width: 28.0,
alignment: Alignment.centerRight,
child: Icon(
_ctr.brightnessValue.value < 1.0 / 3.0
? Icons.brightness_low
: _ctr.brightnessValue.value < 2.0 / 3.0
? Icons.brightness_medium
: Icons.brightness_high,
color: const Color(0xFFFFFFFF),
size: 18.0,
),
),
),
const SizedBox(width: 6.0),
],
const SizedBox(width: 2.0),
Expanded(
child: Text(
'${(_ctr.brightnessValue.value * 100.0).round()}%',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 13.0,
color: Color(0xFFFFFFFF),
),
),
),
const SizedBox(width: 6.0),
],
),
),
),
),
@ -525,7 +514,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
}
if (tapPosition < sectionWidth) {
// 左边区域 👈
final brightness = _brightnessValue - delta / 100.0;
final brightness = _ctr.brightnessValue.value - delta / 100.0;
final result = brightness.clamp(0.0, 1.0);
setBrightness(result);
} else if (tapPosition < sectionWidth * 2) {
@ -548,7 +537,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
_distance = dy;
} else {
// 右边区域 👈
final volume = _volumeValue - delta / 100.0;
final volume = _ctr.volumeValue.value - delta / 100.0;
final result = volume.clamp(0.0, 1.0);
setVolume(result);
}
@ -704,103 +693,129 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
}),
/// 点击 快进/快退
if (_mountSeekBackwardButton || _mountSeekForwardButton)
Positioned.fill(
child: Row(
children: [
Expanded(
child: _mountSeekBackwardButton
? TweenAnimationBuilder<double>(
tween: Tween<double>(
begin: 0.0,
end: _hideSeekBackwardButton ? 0.0 : 1.0,
),
duration: const Duration(milliseconds: 500),
builder: (context, value, child) => Opacity(
opacity: value,
child: child,
),
onEnd: () {
if (_hideSeekBackwardButton) {
setState(() {
_hideSeekBackwardButton = false;
_mountSeekBackwardButton = false;
});
}
},
child: BackwardSeekIndicator(
onChanged: (value) {
// _seekBarDeltaValueNotifier.value = -value;
Obx(
() => Visibility(
visible: _ctr.mountSeekBackwardButton.value ||
_ctr.mountSeekForwardButton.value,
child: Positioned.fill(
child: Row(
children: [
Expanded(
child: _ctr.mountSeekBackwardButton.value
? TweenAnimationBuilder<double>(
tween: Tween<double>(
begin: 0.0,
end:
_ctr.hideSeekBackwardButton.value ? 0.0 : 1.0,
),
duration: const Duration(milliseconds: 500),
builder: (context, value, child) => Opacity(
opacity: value,
child: child,
),
onEnd: () {
if (_ctr.hideSeekBackwardButton.value) {
_ctr.hideSeekBackwardButton.value = false;
_ctr.mountSeekBackwardButton.value = false;
}
},
onSubmitted: (value) {
setState(() {
_hideSeekBackwardButton = true;
});
Player player =
widget.controller.videoPlayerController!;
var result = player.state.position - value;
result = result.clamp(
Duration.zero,
player.state.duration,
);
player.seek(result);
widget.controller.play();
},
),
)
: const SizedBox(),
),
Expanded(
child: SizedBox(
width: MediaQuery.of(context).size.width / 4,
child: BackwardSeekIndicator(
onChanged: (value) {
// _seekBarDeltaValueNotifier.value = -value;
},
onSubmitted: (value) {
_ctr.hideSeekBackwardButton.value = true;
Player player =
widget.controller.videoPlayerController!;
var result = player.state.position - value;
result = result.clamp(
Duration.zero,
player.state.duration,
);
player.seek(result);
widget.controller.play();
},
),
)
: const SizedBox(),
),
),
Expanded(
child: _mountSeekForwardButton
? TweenAnimationBuilder<double>(
tween: Tween<double>(
begin: 0.0,
end: _hideSeekForwardButton ? 0.0 : 1.0,
),
duration: const Duration(milliseconds: 500),
builder: (context, value, child) => Opacity(
opacity: value,
child: child,
),
onEnd: () {
if (_hideSeekForwardButton) {
setState(() {
_hideSeekForwardButton = false;
_mountSeekForwardButton = false;
});
}
},
child: ForwardSeekIndicator(
onChanged: (value) {
// _seekBarDeltaValueNotifier.value = value;
Expanded(
child: SizedBox(
width: MediaQuery.of(context).size.width / 4,
),
),
Expanded(
child: _ctr.mountSeekForwardButton.value
? TweenAnimationBuilder<double>(
tween: Tween<double>(
begin: 0.0,
end: _ctr.hideSeekForwardButton.value ? 0.0 : 1.0,
),
duration: const Duration(milliseconds: 500),
builder: (context, value, child) => Opacity(
opacity: value,
child: child,
),
onEnd: () {
if (_ctr.hideSeekForwardButton.value) {
_ctr.hideSeekForwardButton.value = false;
_ctr.mountSeekForwardButton.value = false;
}
},
onSubmitted: (value) {
setState(() {
_hideSeekForwardButton = true;
});
Player player =
widget.controller.videoPlayerController!;
var result = player.state.position + value;
result = result.clamp(
Duration.zero,
player.state.duration,
);
player.seek(result);
widget.controller.play();
},
),
)
: const SizedBox(),
),
],
child: ForwardSeekIndicator(
onChanged: (value) {
// _seekBarDeltaValueNotifier.value = value;
},
onSubmitted: (value) {
_ctr.hideSeekForwardButton.value = true;
Player player =
widget.controller.videoPlayerController!;
var result = player.state.position + value;
result = result.clamp(
Duration.zero,
player.state.duration,
);
player.seek(result);
widget.controller.play();
},
),
)
: const SizedBox(),
),
],
),
),
),
),
],
);
}
}
class PLVideoPlayerController extends GetxController {
RxBool mountSeekBackwardButton = false.obs;
RxBool mountSeekForwardButton = false.obs;
RxBool hideSeekBackwardButton = false.obs;
RxBool hideSeekForwardButton = false.obs;
RxDouble brightnessValue = 0.0.obs;
RxBool brightnessIndicator = false.obs;
RxDouble volumeValue = 0.0.obs;
RxBool volumeIndicator = false.obs;
RxDouble distance = 0.0.obs;
// 初始手指落下位置
RxDouble initTapPositoin = 0.0.obs;
RxBool volumeInterceptEventStream = false.obs;
// 双击快进 展示样式
void onDoubleTapSeekForward() {
mountSeekForwardButton.value = true;
}
void onDoubleTapSeekBackward() {
mountSeekBackwardButton.value = true;
}
}