feat: Add LitePlayerView widget for IPTV stream playback with integrated zapping controls and error handling.

This commit is contained in:
Michael committed 2025-12-13 11:04:08 +01:00
1 parent 18d2e0a0ee
commit 23c634ddb7
3 files changed
+49 -5

No files matched your search

+39 -2
View File
@@ -11,6 +11,39 @@ import '../providers/settings_provider.dart';
import '../widgets/lite_player_view.dart';
// ... (existing imports)
// ... (existing imports)
import '../../../core/models/playlist_config.dart';
import '../../../core/widgets/tv_focusable_card.dart';
import '../../../core/widgets/glass_container.dart';
import '../../../core/theme/app_colors.dart';
import '../models/xtream_models.dart';
import '../widgets/epg_overlay.dart';
enum StreamType { live, vod, series }
class PlayerScreen extends ConsumerStatefulWidget {
final String streamId;
final String title;
final PlaylistConfig playlist;
final StreamType streamType;
final String containerExtension;
final List<LiveChannel>? channels;
final double? startTime;
const PlayerScreen({
super.key,
required this.streamId,
required this.title,
required this.playlist,
this.streamType = StreamType.live,
this.containerExtension = 'mp4',
this.channels,
this.startTime,
});
@override
ConsumerState<PlayerScreen> createState() => _PlayerScreenState();
}
class _PlayerScreenState extends ConsumerState<PlayerScreen> {
bool _isPlaying = true;
@@ -24,6 +57,10 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
StreamSubscription? _messageSubscription;
String _aspectRatio = 'contain';
bool _isSeeking = false;
String _viewId = 'iptv-player';
String? _currentStreamUrl;
String _statusMessage = 'Loading...';
String? _errorMessage;
@override
void initState() {
@@ -129,9 +166,9 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
// Update watch history if relevant
if (currentTime > 0) {
ref.read(playbackPositionsProvider.notifier).savePosition(
widget.playlist.id,
widget.streamId,
currentTime
currentTime,
duration
);
}
@@ -55,7 +55,7 @@ class _LitePlayerViewState extends ConsumerState<LitePlayerView> {
looping: false,
isLive: widget.isLive,
aspectRatio: _videoController.value.aspectRatio > 0 ? _videoController.value.aspectRatio : 16/9,
colors: ChewieProgressColors(
materialProgressColors: ChewieProgressColors(
playedColor: AppColors.primary,
handleColor: Colors.white,
backgroundColor: Colors.white24,
@@ -67,13 +67,19 @@ class _LitePlayerViewState extends ConsumerState<LitePlayerView> {
return <OptionItem>[
if (widget.onNext != null)
OptionItem(
onTap: widget.onNext!,
onTap: (context) {
widget.onNext!();
Navigator.of(context).pop(); // Close options menu
},
iconData: Icons.skip_next,
title: 'Next Channel',
),
if (widget.onPrevious != null)
OptionItem(
onTap: widget.onPrevious!,
onTap: (context) {
widget.onPrevious!();
Navigator.of(context).pop(); // Close options menu
},
iconData: Icons.skip_previous,
title: 'Previous Channel',
),
@@ -6,6 +6,7 @@ import '../../../../core/models/playlist_config.dart';
import '../../../../features/iptv/models/xtream_models.dart';
import '../../../../features/iptv/providers/xtream_provider.dart';
import '../../../../features/iptv/providers/watch_history_provider.dart';
import '../../../../features/iptv/screens/player_screen.dart'; // Explicit import for StreamType
import 'mobile_player_screen.dart';
import '../../../../core/theme/app_colors.dart';
import '../../../../core/widgets/glass_container.dart';