fix(video): sync first-frame background state
This commit is contained in:
+45
-6
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'player/player.dart';
|
import 'player/player.dart';
|
||||||
@@ -23,8 +24,15 @@ class Video extends StatefulWidget {
|
|||||||
final Player player;
|
final Player player;
|
||||||
final Widget Function(BuildContext context)? controls;
|
final Widget Function(BuildContext context)? controls;
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
|
final ValueListenable<bool>? hasFirstFrame;
|
||||||
|
|
||||||
const Video({super.key, required this.player, this.controls, this.backgroundColor = Colors.black});
|
const Video({
|
||||||
|
super.key,
|
||||||
|
required this.player,
|
||||||
|
this.controls,
|
||||||
|
this.backgroundColor = Colors.black,
|
||||||
|
this.hasFirstFrame,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<Video> createState() => _VideoState();
|
State<Video> createState() => _VideoState();
|
||||||
@@ -38,19 +46,50 @@ class _VideoState extends State<Video> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_playbackRestartSubscription = widget.player.streams.playbackRestart.listen((_) {
|
_hasFirstFrame = widget.hasFirstFrame?.value ?? false;
|
||||||
if (!_hasFirstFrame && mounted) {
|
widget.hasFirstFrame?.addListener(_syncExternalFirstFrame);
|
||||||
setState(() => _hasFirstFrame = true);
|
_listenForPlaybackRestart();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(covariant Video oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
if (oldWidget.hasFirstFrame != widget.hasFirstFrame) {
|
||||||
|
oldWidget.hasFirstFrame?.removeListener(_syncExternalFirstFrame);
|
||||||
|
widget.hasFirstFrame?.addListener(_syncExternalFirstFrame);
|
||||||
|
_syncExternalFirstFrame();
|
||||||
|
}
|
||||||
|
if (oldWidget.player != widget.player) {
|
||||||
|
_playbackRestartSubscription?.cancel();
|
||||||
|
_listenForPlaybackRestart();
|
||||||
|
_syncExternalFirstFrame();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
widget.hasFirstFrame?.removeListener(_syncExternalFirstFrame);
|
||||||
_playbackRestartSubscription?.cancel();
|
_playbackRestartSubscription?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _listenForPlaybackRestart() {
|
||||||
|
_playbackRestartSubscription = widget.player.streams.playbackRestart.listen((_) {
|
||||||
|
_setHasFirstFrame(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _syncExternalFirstFrame() {
|
||||||
|
final external = widget.hasFirstFrame;
|
||||||
|
if (external == null) return;
|
||||||
|
_setHasFirstFrame(external.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setHasFirstFrame(bool value) {
|
||||||
|
if (_hasFirstFrame == value || !mounted) return;
|
||||||
|
setState(() => _hasFirstFrame = value);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ColoredBox(
|
return ColoredBox(
|
||||||
|
|||||||
@@ -256,6 +256,7 @@ extension _VideoPlayerBuildMethods on VideoPlayerScreenState {
|
|||||||
|
|
||||||
return Video(
|
return Video(
|
||||||
player: player!,
|
player: player!,
|
||||||
|
hasFirstFrame: _hasFirstFrame,
|
||||||
controls: (context) => PlexVideoControls(
|
controls: (context) => PlexVideoControls(
|
||||||
player: player!,
|
player: player!,
|
||||||
metadata: _currentMetadata,
|
metadata: _currentMetadata,
|
||||||
|
|||||||
Reference in New Issue
Block a user