fix(player): 优化封面过渡与换集起播

This commit is contained in:
Zhou Weidong committed 2026-10-26 14:01:42 +08:00
1 parent 516593499c
commit 04f034817c
6 files changed
+65 -19

No files matched your search

+6 -3
View File
@@ -174,7 +174,7 @@ void main() {
await session.close();
});
test('should_keep_manual_pause_when_returning_to_same_episode', () async {
test('should_auto_play_previous_after_switching_from_paused_episode', () async {
final factory = _Factory();
final session = PlaybackSession(
episodes: episodes,
@@ -195,13 +195,16 @@ void main() {
factory.players.firstWhere((player) => player.id == 'ep-2').playing,
isTrue,
);
session.setUserWantsPlay(false);
await session.playbackSettled;
expect(session.userWantsPlay, isFalse);
await session.select(1, preloadIndex: 2, previousIndex: 0);
await session.preloadSettled;
expect(session.userWantsPlay, isFalse);
expect(session.userWantsPlay, isTrue);
expect(
factory.players.firstWhere((player) => player.id == 'ep-1').playing,
isFalse,
isTrue,
);
await session.close();
});
@@ -83,6 +83,34 @@ void main() {
expect(find.byKey(const Key('player-opening-poster')), findsOneWidget);
});
testWidgets('should_reuse_decoded_sprite_when_parent_rebuilds', (
tester,
) async {
final loader = _FakeSpriteLoader();
final cache = OpeningFrameCache();
addTearDown(cache.clear);
Widget build() => MaterialApp(
home: PlayerOpeningFrame(
thumbnailsUrl: 'https://cdn.test/thumbnails.vtt',
posterUrl: 'https://cdn.test/poster.jpg',
loader: loader,
cache: cache,
),
);
await tester.pumpWidget(build());
await tester.pumpAndSettle();
expect(loader.vttCalls, 1);
expect(loader.spriteCalls, hasLength(1));
await tester.pumpWidget(build());
await tester.pumpAndSettle();
expect(loader.vttCalls, 1);
expect(loader.spriteCalls, hasLength(1));
expect(find.byKey(const Key('player-opening-sprite')), findsOneWidget);
});
}
class _FakeSpriteLoader implements SpriteThumbnailAssetLoader {
+23 -2
View File
@@ -30,6 +30,7 @@ void main() {
expect(find.byKey(const Key('player-opening-frame')), findsOneWidget);
expect(find.byKey(const Key('fake-opening')), findsOneWidget);
expect(_openingOpacity(tester), 1);
expect(_opacity(tester), 0);
});
@@ -48,7 +49,7 @@ void main() {
expect(find.byKey(const Key('player-opening-frame')), findsNothing);
});
testWidgets('should_fade_video_in_within_200ms_after_first_frame', (
testWidgets('should_cross_fade_video_over_opening_frame', (
tester,
) async {
final controller = await _pumpSurface(
@@ -67,7 +68,7 @@ void main() {
await tester.pump();
expect(_opacity(tester), 1);
expect(find.byKey(const Key('player-opening-frame')), findsNothing);
expect(find.byKey(const Key('player-opening-frame')), findsOneWidget);
expect(
tester
.widget<AnimatedOpacity>(
@@ -80,8 +81,12 @@ void main() {
final halfway = _fadeValue(tester);
expect(halfway, greaterThan(0));
expect(halfway, lessThan(1));
final openingHalfway = _openingFadeValue(tester);
expect(openingHalfway, greaterThan(0));
expect(openingHalfway, lessThan(1));
await tester.pump(const Duration(milliseconds: 100));
expect(_fadeValue(tester), 1);
expect(_openingFadeValue(tester), 0);
});
testWidgets('should_show_video_error_above_retained_fallback', (
@@ -182,6 +187,14 @@ double _opacity(WidgetTester tester) {
.opacity;
}
double _openingOpacity(WidgetTester tester) {
return tester
.widget<AnimatedOpacity>(
find.byKey(const Key('player-opening-frame')),
)
.opacity;
}
double _fadeValue(WidgetTester tester) {
final fade = find.descendant(
of: find.byKey(const Key('player-video-opacity')),
@@ -189,3 +202,11 @@ double _fadeValue(WidgetTester tester) {
);
return tester.widget<FadeTransition>(fade).opacity.value;
}
double _openingFadeValue(WidgetTester tester) {
final fade = find.descendant(
of: find.byKey(const Key('player-opening-frame')),
matching: find.byType(FadeTransition),
);
return tester.widget<FadeTransition>(fade).opacity.value;
}