fix(player): 收敛播放入口缓冲提示
This commit is contained in:
1 parent
f302b396b7
commit
7ad4681049
12 files changed
+218
-42
No files matched your search
@@ -99,13 +99,8 @@ void main() {
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
final sessionLoading = find.byKey(const Key('player-session-loading'));
|
||||
expect(sessionLoading, findsOneWidget);
|
||||
expect(tester.getSize(sessionLoading), const Size(24, 24));
|
||||
expect(
|
||||
tester.widget<CircularProgressIndicator>(sessionLoading).strokeWidth,
|
||||
2,
|
||||
);
|
||||
expect(find.byKey(const Key('player-session-loading')), findsNothing);
|
||||
expect(find.byKey(const Key('progress-loading')), findsNothing);
|
||||
|
||||
initialization.complete();
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
@@ -127,6 +122,8 @@ void main() {
|
||||
await _openSeriesPlayer(tester);
|
||||
final player = players.firstWhere((item) => item.playing);
|
||||
expect(player.playing, isTrue);
|
||||
expect(find.byKey(const Key('progress-loading')), findsNothing);
|
||||
expect(find.byKey(const Key('progress-inactive')), findsOneWidget);
|
||||
|
||||
final navigator = tester.state<NavigatorState>(
|
||||
find.byType(Navigator).first,
|
||||
@@ -147,6 +144,8 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(player.playing, isTrue);
|
||||
expect(find.byKey(const Key('progress-loading')), findsNothing);
|
||||
expect(find.byKey(const Key('progress-inactive')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_pause_feed_when_auth_page_is_pushed_and_resume_on_pop', (
|
||||
@@ -571,7 +570,8 @@ void main() {
|
||||
tester.getSize(find.byKey(const Key('player-bottom-clear-screen'))),
|
||||
const Size(40, 40),
|
||||
);
|
||||
expect(find.byKey(const Key('progress-loading')), findsOneWidget);
|
||||
expect(find.byKey(const Key('progress-loading')), findsNothing);
|
||||
expect(find.byKey(const Key('progress-inactive')), findsOneWidget);
|
||||
expect(find.byType(Slider), findsNothing);
|
||||
|
||||
expect(bottom.height, lessThanOrEqualTo(200));
|
||||
@@ -1301,7 +1301,8 @@ void _expectFullscreenOverlay(WidgetTester tester) {
|
||||
expect(find.byKey(const Key('player-pip')), findsNothing);
|
||||
expect(find.byKey(const Key('player-rail-comments')), findsOneWidget);
|
||||
expect(find.byKey(const Key('player-fullscreen-toggle')), findsNothing);
|
||||
expect(find.byKey(const Key('progress-loading')), findsOneWidget);
|
||||
expect(find.byKey(const Key('progress-loading')), findsNothing);
|
||||
expect(find.byKey(const Key('progress-inactive')), findsOneWidget);
|
||||
expect(find.byType(Slider), findsNothing);
|
||||
expect(find.byKey(const Key('player-title')), findsNothing);
|
||||
expect(find.byKey(const Key('player-subtitle')), findsNothing);
|
||||
|
||||
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:video_player_platform_interface/video_player_platform_interface.dart';
|
||||
import 'package:fruitshorts/core/data/models/drama.dart';
|
||||
import 'package:fruitshorts/core/data/models/play_ticket.dart';
|
||||
import 'package:fruitshorts/core/data/models/player_port.dart';
|
||||
@@ -287,6 +289,44 @@ void main() {
|
||||
await tester.pump();
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('should_seek_cached_position_before_play_when_rebuilding', (
|
||||
tester,
|
||||
) async {
|
||||
final previousPlatform = VideoPlayerPlatform.instance;
|
||||
VideoPlayerPlatform.instance = _VideoPlayerPlatformStub();
|
||||
addTearDown(() => VideoPlayerPlatform.instance = previousPlatform);
|
||||
final cache = PlaybackPositionCache();
|
||||
cache.save(
|
||||
episodeId: 'signal-1',
|
||||
dramaId: 'signal',
|
||||
position: const Duration(seconds: 42),
|
||||
duration: const Duration(minutes: 1),
|
||||
);
|
||||
final factory = _VideoRecordingFactory();
|
||||
late PlayerLogic logic;
|
||||
await tester.runAsync(() async {
|
||||
logic = _logic(FakeWatchHistory(), positionCache: cache);
|
||||
logic.attach(
|
||||
PlayerPage(drama: _drama('signal'), initialIndex: 0),
|
||||
isMounted: () => true,
|
||||
);
|
||||
logic.start(
|
||||
factory: factory.create,
|
||||
coordinator: PlaybackCoordinator(),
|
||||
);
|
||||
await _drain(logic);
|
||||
await pumpEventQueue();
|
||||
await logic.session.playbackSettled;
|
||||
await logic.session.preloadSettled;
|
||||
});
|
||||
|
||||
final player = logic.session.active! as _VideoRecordingPlayer;
|
||||
expect(player.events, containsAllInOrder(['initialize', 'seek', 'play']));
|
||||
expect(player.controller.value.position, const Duration(seconds: 42));
|
||||
logic.dispose();
|
||||
await tester.pump();
|
||||
});
|
||||
});
|
||||
|
||||
test('should_play_local_file_without_ticket_when_episode_is_downloaded',
|
||||
@@ -1297,21 +1337,38 @@ class _SessionVideoSurface extends StatelessWidget {
|
||||
|
||||
class _VideoRecordingFactory {
|
||||
final List<_VideoRecordingPlayer> created = [];
|
||||
final List<String> events = [];
|
||||
|
||||
PlayerPort create(Episode episode) {
|
||||
final player = _VideoRecordingPlayer(episode);
|
||||
final player = _VideoRecordingPlayer(episode, events);
|
||||
created.add(player);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
||||
class _VideoPlayerPlatformStub extends VideoPlayerPlatform {
|
||||
@override
|
||||
Future<void> init() async {}
|
||||
|
||||
@override
|
||||
Future<void> dispose(int playerId) async {}
|
||||
|
||||
@override
|
||||
Future<void> setVolume(int playerId, double volume) async {}
|
||||
|
||||
@override
|
||||
Future<void> setPlaybackSpeed(int playerId, double speed) async {}
|
||||
}
|
||||
|
||||
class _VideoRecordingPlayer extends VideoPlayerPort {
|
||||
_VideoRecordingPlayer(super.episode);
|
||||
_VideoRecordingPlayer(super.episode, this.events);
|
||||
|
||||
bool disposed = false;
|
||||
final List<String> events;
|
||||
|
||||
@override
|
||||
Future<void> initialize() async {
|
||||
events.add('initialize');
|
||||
controller.value = const VideoPlayerValue(
|
||||
duration: Duration(minutes: 1),
|
||||
size: Size(1280, 720),
|
||||
@@ -1321,13 +1378,14 @@ class _VideoRecordingPlayer extends VideoPlayerPort {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> play() async {}
|
||||
Future<void> play() async => events.add('play');
|
||||
|
||||
@override
|
||||
Future<void> pause() async {}
|
||||
Future<void> pause() async => events.add('pause');
|
||||
|
||||
@override
|
||||
Future<void> seekTo(Duration position) async {
|
||||
events.add('seek');
|
||||
final current = controller.value;
|
||||
controller.value = VideoPlayerValue(
|
||||
duration: current.duration,
|
||||
|
||||
@@ -59,6 +59,7 @@ void main() {
|
||||
final active = logic.session.active;
|
||||
final index = logic.session.currentIndex;
|
||||
final player = factory.created.first;
|
||||
final createdBeforeDetail = factory.created.length;
|
||||
logic
|
||||
..trackedPlayer = player
|
||||
..trackedEpisode = drama.episodes.first
|
||||
@@ -106,6 +107,7 @@ void main() {
|
||||
expect(logic.session.active, same(active));
|
||||
expect(logic.session.currentIndex, index);
|
||||
expect(logic.session.userWantsPlay, isTrue);
|
||||
expect(factory.created, hasLength(createdBeforeDetail));
|
||||
expect(
|
||||
player.controller.value.position,
|
||||
const Duration(minutes: 1, seconds: 22),
|
||||
@@ -125,6 +127,7 @@ void main() {
|
||||
expect(logic.session.active, same(active));
|
||||
expect(logic.session.currentIndex, index);
|
||||
expect(logic.session.userWantsPlay, isTrue);
|
||||
expect(factory.created, hasLength(createdBeforeDetail));
|
||||
expect(
|
||||
player.controller.value.position,
|
||||
const Duration(minutes: 1, seconds: 22),
|
||||
|
||||
Reference in new issue
Block a user