fix(player): 收敛播放入口缓冲提示

This commit is contained in:
Zhou Weidong committed 2026-10-22 10:47:16 +08:00
1 parent f302b396b7
commit 7ad4681049
12 files changed
+218 -42

No files matched your search

+62 -4
View File
@@ -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,