feat(player): 增加进度条拖动画面预览
This commit is contained in:
1 parent
d06dce9753
commit
51c56d884b
15 files changed
+1493
-77
No files matched your search
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../core/config/app_config.dart';
|
||||
import '../../core/data/models/drama.dart';
|
||||
import '../../core/data/repositories/comment_repository.dart';
|
||||
import '../../core/data/services/favorite_controller.dart';
|
||||
@@ -13,6 +14,7 @@ import '../../core/data/services/download_controller.dart';
|
||||
import '../../core/data/services/interaction_controller.dart';
|
||||
import '../../core/data/services/playback_position_cache.dart';
|
||||
import '../../core/data/services/playback_session.dart';
|
||||
import '../../core/data/services/playback_thumbnail_service.dart';
|
||||
import '../../core/data/services/video_player_port.dart';
|
||||
import '../../core/data/services/wallet_controller.dart';
|
||||
import '../../core/formatting/error_text.dart';
|
||||
@@ -103,6 +105,7 @@ class PlayerPage extends StatefulWidget {
|
||||
class _PlayerPageState extends State<PlayerPage>
|
||||
with WidgetsBindingObserver, RouteAware {
|
||||
late final PlayerLogic logic;
|
||||
late final PlaybackThumbnailService _thumbnailService;
|
||||
PageRoute<dynamic>? _subscribedRoute;
|
||||
bool _chromeVisible = true;
|
||||
double _playbackSpeed = 1.0;
|
||||
@@ -125,6 +128,9 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
downloads: widget.downloads,
|
||||
);
|
||||
logic.attach(widget, isMounted: () => mounted);
|
||||
_thumbnailService = PlaybackThumbnailService(
|
||||
sourceResolver: _resolveThumbnailSource,
|
||||
);
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
logic.start(
|
||||
factory: context.read<PlayerFactory>(),
|
||||
@@ -161,6 +167,57 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
String _feedSignature(List<Drama>? dramas) =>
|
||||
dramas == null ? '' : dramas.map((drama) => drama.id).join('|');
|
||||
|
||||
PlaybackThumbnailSource? _resolveThumbnailSource(String episodeId) {
|
||||
final localPath = widget.downloads?.localPathFor(episodeId);
|
||||
Episode? episode;
|
||||
for (final item in logic.sessionEpisodes) {
|
||||
if (item.id == episodeId) {
|
||||
episode = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (localPath != null && localPath.isNotEmpty) {
|
||||
return PlaybackThumbnailSource(localPath: localPath);
|
||||
}
|
||||
final rawUrl = episode?.videoUrl ?? '';
|
||||
final active = logic.session.active;
|
||||
final activeSource = active is VideoPlayerPort
|
||||
? active.controller.dataSource
|
||||
: '';
|
||||
final currentEpisodeId = logic.sessionEpisodes.isEmpty
|
||||
? null
|
||||
: logic.session.currentEpisode.id;
|
||||
final activeMatches =
|
||||
currentEpisodeId == episodeId && activeSource.isNotEmpty;
|
||||
if (activeMatches && activeSource.startsWith('file:')) {
|
||||
try {
|
||||
return PlaybackThumbnailSource(
|
||||
localPath: Uri.parse(activeSource).toFilePath(),
|
||||
);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (rawUrl.startsWith('file:')) {
|
||||
try {
|
||||
return PlaybackThumbnailSource(
|
||||
localPath: Uri.parse(rawUrl).toFilePath(),
|
||||
);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
final remoteUrl = AppConfig.mediaUrl(
|
||||
rawUrl.isNotEmpty
|
||||
? rawUrl
|
||||
: activeMatches
|
||||
? activeSource
|
||||
: '',
|
||||
);
|
||||
if (remoteUrl.isEmpty) return null;
|
||||
return PlaybackThumbnailSource(remoteUrl: remoteUrl);
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
@@ -190,6 +247,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
appRouteObserver.unsubscribe(this);
|
||||
_thumbnailService.dispose();
|
||||
logic.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
@@ -547,6 +605,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
onSeek: ready
|
||||
? (position) => logic.seekTo(context, videoPort!, position)
|
||||
: null,
|
||||
thumbnailService: _thumbnailService,
|
||||
)
|
||||
else
|
||||
PlayerPlaybackOverlay(
|
||||
@@ -569,6 +628,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
playbackSpeed: _playbackSpeed,
|
||||
totalEpisodes: logic.visibleIndices.length,
|
||||
boosting: _boosting,
|
||||
thumbnailService: _thumbnailService,
|
||||
),
|
||||
actions: PlayerOverlayActions(
|
||||
onBack: widget.embedded
|
||||
|
||||
Reference in new issue
Block a user