mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-17 20:29:30 +02:00
feat: Introduce a comprehensive video player screen supporting live, VOD, and series streams with full playback controls.
This commit is contained in:
1 parent
0bcfb35a39
commit
c7466af9e4
2 files changed
+44
-48
No files matched your search
@@ -180,7 +180,9 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
|
|||||||
// Check if we are using server-side transcoding for VOD/Series
|
// Check if we are using server-side transcoding for VOD/Series
|
||||||
// If so, we must reload the player because we can't seek in a piped stream directly via JS
|
// If so, we must reload the player because we can't seek in a piped stream directly via JS
|
||||||
final settings = ref.read(iptvSettingsProvider);
|
final settings = ref.read(iptvSettingsProvider);
|
||||||
final isTranscoding = widget.streamType != StreamType.live && settings.streamQuality != StreamQuality.high;
|
// We now force transcoding (API stream) for ALL VOD content to ensure audio compatibility.
|
||||||
|
// So isTranscoding is effectively true for all non-live content.
|
||||||
|
final isTranscoding = widget.streamType != StreamType.live;
|
||||||
|
|
||||||
if (isTranscoding) {
|
if (isTranscoding) {
|
||||||
debugPrint('Seeking in transcoded VOD - reloading player at ${value.round()}s');
|
debugPrint('Seeking in transcoded VOD - reloading player at ${value.round()}s');
|
||||||
@@ -345,54 +347,41 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
|
|||||||
} else {
|
} else {
|
||||||
// For VOD and Series
|
// For VOD and Series
|
||||||
|
|
||||||
// CHECK QUALITY SETTING
|
// FORCE API STREAMING (FFMPEG)
|
||||||
// If Quality is NOT High, we force transcoding to ensure audio compatibility (AAC)
|
// We always use the backend /api/stream endpoint because it handles audio transcoding (to AAC)
|
||||||
// This solves "No Sound" issues with AC3/DTS on mobile/web.
|
// which is required for browsers to play content with AC3/DTS audio.
|
||||||
// NOTE: For MKV files with unsupported audio, user should select Low/Medium quality.
|
// For 'High' quality, the backend uses '-c:v copy', so video quality is preserved (Direct Stream).
|
||||||
final settings = ref.read(iptvSettingsProvider);
|
setState(() {
|
||||||
final useTranscoding = settings.streamQuality != StreamQuality.high;
|
_statusMessage = 'Preparing stream...';
|
||||||
|
});
|
||||||
|
|
||||||
if (useTranscoding) {
|
final baseUrl = html.window.location.origin;
|
||||||
setState(() {
|
final vodStreamUrl = widget.streamType == StreamType.vod
|
||||||
_statusMessage = 'Starting VOD Transcoding (Audio Fix)...';
|
? xtreamService.getVodStreamUrl(currentStreamId, widget.containerExtension)
|
||||||
});
|
: xtreamService.getSeriesStreamUrl(currentStreamId, widget.containerExtension);
|
||||||
|
|
||||||
final baseUrl = html.window.location.origin;
|
final encodedUrl = Uri.encodeComponent(vodStreamUrl);
|
||||||
final vodStreamUrl = widget.streamType == StreamType.vod
|
final qualityParam = switch (settings.streamQuality) {
|
||||||
? xtreamService.getVodStreamUrl(currentStreamId, widget.containerExtension)
|
StreamQuality.low => 'low',
|
||||||
: xtreamService.getSeriesStreamUrl(currentStreamId, widget.containerExtension);
|
StreamQuality.medium => 'medium',
|
||||||
|
StreamQuality.high => 'high',
|
||||||
final encodedUrl = Uri.encodeComponent(vodStreamUrl);
|
};
|
||||||
final qualityParam = switch (settings.streamQuality) {
|
|
||||||
StreamQuality.low => 'low',
|
// Calculate start time for seeking support
|
||||||
StreamQuality.medium => 'medium',
|
// If override provided (seeking), use it. Else check provider resume.
|
||||||
StreamQuality.high => 'high',
|
double startSeconds = startTimeOverride ?? 0;
|
||||||
};
|
if (startTimeOverride == null && _contentId.isNotEmpty) {
|
||||||
|
final positions = ref.read(playbackPositionsProvider);
|
||||||
// Calculate start time for seeking support
|
final saved = positions.getPosition(_contentId);
|
||||||
// If override provided (seeking), use it. Else check provider resume.
|
if (saved > 0) startSeconds = saved;
|
||||||
double startSeconds = startTimeOverride ?? 0;
|
|
||||||
if (startTimeOverride == null && _contentId.isNotEmpty) {
|
|
||||||
final positions = ref.read(playbackPositionsProvider);
|
|
||||||
final saved = positions.getPosition(_contentId);
|
|
||||||
if (saved > 0) startSeconds = saved;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct URL with start param
|
|
||||||
// Note: We force extension to .ts for mpegts.js compatibility
|
|
||||||
final streamEndpoint = '$baseUrl/api/stream/$currentStreamId?url=$encodedUrl&quality=$qualityParam&start=${startSeconds.round()}&ext=.ts';
|
|
||||||
|
|
||||||
debugPrint('PlayerScreen: Streaming Transcoded VOD: $streamEndpoint');
|
|
||||||
hlsUrl = streamEndpoint;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Direct Play (High Quality) - Original behavior
|
|
||||||
final streamUrl = widget.streamType == StreamType.vod
|
|
||||||
? xtreamService.getVodStreamUrl(currentStreamId, widget.containerExtension)
|
|
||||||
: xtreamService.getSeriesStreamUrl(currentStreamId, widget.containerExtension);
|
|
||||||
hlsUrl = streamUrl;
|
|
||||||
debugPrint('PlayerScreen: Direct playback URL (High Quality): $hlsUrl');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Construct URL with start param
|
||||||
|
// Note: We force extension to .ts for mpegts.js compatibility
|
||||||
|
final streamEndpoint = '$baseUrl/api/stream/$currentStreamId?url=$encodedUrl&quality=$qualityParam&start=${startSeconds.round()}&ext=.ts';
|
||||||
|
|
||||||
|
debugPrint('PlayerScreen: Streaming VOD (Audio Fix enabled): $streamEndpoint');
|
||||||
|
hlsUrl = streamEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -418,7 +407,8 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
|
|||||||
// If Direct Play, pass startTime.
|
// If Direct Play, pass startTime.
|
||||||
|
|
||||||
final settings = ref.read(iptvSettingsProvider);
|
final settings = ref.read(iptvSettingsProvider);
|
||||||
final isTranscoding = widget.streamType != StreamType.live && settings.streamQuality != StreamQuality.high;
|
// We force transcoding/proxy usage for all VOD/Series now
|
||||||
|
final isTranscoding = widget.streamType != StreamType.live;
|
||||||
|
|
||||||
final encodedHlsUrl = Uri.encodeComponent(hlsUrl);
|
final encodedHlsUrl = Uri.encodeComponent(hlsUrl);
|
||||||
final playerUrl = (!isTranscoding && startTime > 0)
|
final playerUrl = (!isTranscoding && startTime > 0)
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Audio Investigation in Movies
|
||||||
|
|
||||||
|
- [ ] Investigate `player_screen.dart` to understand how the player is initialized.
|
||||||
|
- [ ] Determine differences between Movie, Series, and TV playback logic.
|
||||||
|
- [ ] Check for codec support or transcoding logic.
|
||||||
|
- [ ] Fix the audio issue for movies.
|
||||||
Reference in new issue
Block a user