feat(app): 完善播放协议搜索与空状态
This commit is contained in:
1 parent
671e0ce143
commit
ef29fc5f15
85 files changed
+2976
-768
No files matched your search
@@ -10,16 +10,18 @@ const Duration _videoFadeDuration = Duration(milliseconds: 200);
|
||||
const double _errorHorizontal = 32;
|
||||
const int _errorMaxLines = 3;
|
||||
|
||||
/// 黑色底层与视频层共用同一控制器,视频首帧就绪后再淡入。
|
||||
/// 黑色底层与视频层共用同一控制器。清晰度切换时用仍在播放的旧画面盖住新纹理的黑帧。
|
||||
class PlayerVideoSurface extends StatefulWidget {
|
||||
const PlayerVideoSurface({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.videoUrl,
|
||||
required this.theater,
|
||||
this.handoff,
|
||||
});
|
||||
|
||||
final VideoPlayerController? controller;
|
||||
final VideoPlayerController? handoff;
|
||||
final String videoUrl;
|
||||
final bool theater;
|
||||
|
||||
@@ -48,7 +50,8 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
|
||||
|
||||
Widget _frame(VideoPlayerValue? value) {
|
||||
final controller = widget.controller;
|
||||
final reveal = _shouldReveal(value);
|
||||
final handoff = _liveHandoff(controller);
|
||||
final reveal = _shouldReveal(value, handoff != null);
|
||||
_logStateChange(value);
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
@@ -60,7 +63,7 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
|
||||
AnimatedOpacity(
|
||||
key: const Key('player-video-opacity'),
|
||||
opacity: reveal ? 1 : 0,
|
||||
duration: _videoFadeDuration,
|
||||
duration: handoff != null ? Duration.zero : _videoFadeDuration,
|
||||
curve: Curves.easeOut,
|
||||
child: reveal && controller != null
|
||||
? _VideoLayer(
|
||||
@@ -70,6 +73,13 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
|
||||
)
|
||||
: const SizedBox.expand(),
|
||||
),
|
||||
if (handoff != null)
|
||||
_VideoLayer(
|
||||
key: const Key('player-video-handoff'),
|
||||
controller: handoff,
|
||||
value: handoff.value,
|
||||
theater: widget.theater,
|
||||
),
|
||||
if (kDebugMode && value?.hasError == true)
|
||||
Center(
|
||||
child: Padding(
|
||||
@@ -88,12 +98,18 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
|
||||
);
|
||||
}
|
||||
|
||||
bool _shouldReveal(VideoPlayerValue? value) {
|
||||
return value != null &&
|
||||
!value.hasError &&
|
||||
value.isInitialized &&
|
||||
value.size.width > 0 &&
|
||||
(value.position > Duration.zero || value.isPlaying);
|
||||
bool _shouldReveal(VideoPlayerValue? value, bool covered) {
|
||||
if (value == null || value.hasError || !value.isInitialized) return false;
|
||||
if (value.size.width <= 0) return false;
|
||||
if (covered) return true;
|
||||
return value.position > Duration.zero || value.isPlaying;
|
||||
}
|
||||
|
||||
/// 只画会话仍持有的旧画面,控制器一旦被换掉就不再引用。
|
||||
VideoPlayerController? _liveHandoff(VideoPlayerController? controller) {
|
||||
final handoff = widget.handoff;
|
||||
if (handoff == null || identical(handoff, controller)) return null;
|
||||
return handoff;
|
||||
}
|
||||
|
||||
void _logStateChange(VideoPlayerValue? value) {
|
||||
@@ -135,6 +151,7 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
|
||||
|
||||
class _VideoLayer extends StatelessWidget {
|
||||
const _VideoLayer({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.value,
|
||||
required this.theater,
|
||||
|
||||
Reference in new issue
Block a user