mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-17 20:29:30 +02:00
feat: Add LitePlayerView widget for IPTV stream playback with integrated zapping controls and error handling.
This commit is contained in:
1 parent
18d2e0a0ee
commit
23c634ddb7
3 files changed
+49
-5
No files matched your search
@@ -11,6 +11,39 @@ import '../providers/settings_provider.dart';
|
|||||||
import '../widgets/lite_player_view.dart';
|
import '../widgets/lite_player_view.dart';
|
||||||
|
|
||||||
// ... (existing imports)
|
// ... (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> {
|
class _PlayerScreenState extends ConsumerState<PlayerScreen> {
|
||||||
bool _isPlaying = true;
|
bool _isPlaying = true;
|
||||||
@@ -24,6 +57,10 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
|
|||||||
StreamSubscription? _messageSubscription;
|
StreamSubscription? _messageSubscription;
|
||||||
String _aspectRatio = 'contain';
|
String _aspectRatio = 'contain';
|
||||||
bool _isSeeking = false;
|
bool _isSeeking = false;
|
||||||
|
String _viewId = 'iptv-player';
|
||||||
|
String? _currentStreamUrl;
|
||||||
|
String _statusMessage = 'Loading...';
|
||||||
|
String? _errorMessage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -129,9 +166,9 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
|
|||||||
// Update watch history if relevant
|
// Update watch history if relevant
|
||||||
if (currentTime > 0) {
|
if (currentTime > 0) {
|
||||||
ref.read(playbackPositionsProvider.notifier).savePosition(
|
ref.read(playbackPositionsProvider.notifier).savePosition(
|
||||||
widget.playlist.id,
|
|
||||||
widget.streamId,
|
widget.streamId,
|
||||||
currentTime
|
currentTime,
|
||||||
|
duration
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class _LitePlayerViewState extends ConsumerState<LitePlayerView> {
|
|||||||
looping: false,
|
looping: false,
|
||||||
isLive: widget.isLive,
|
isLive: widget.isLive,
|
||||||
aspectRatio: _videoController.value.aspectRatio > 0 ? _videoController.value.aspectRatio : 16/9,
|
aspectRatio: _videoController.value.aspectRatio > 0 ? _videoController.value.aspectRatio : 16/9,
|
||||||
colors: ChewieProgressColors(
|
materialProgressColors: ChewieProgressColors(
|
||||||
playedColor: AppColors.primary,
|
playedColor: AppColors.primary,
|
||||||
handleColor: Colors.white,
|
handleColor: Colors.white,
|
||||||
backgroundColor: Colors.white24,
|
backgroundColor: Colors.white24,
|
||||||
@@ -67,13 +67,19 @@ class _LitePlayerViewState extends ConsumerState<LitePlayerView> {
|
|||||||
return <OptionItem>[
|
return <OptionItem>[
|
||||||
if (widget.onNext != null)
|
if (widget.onNext != null)
|
||||||
OptionItem(
|
OptionItem(
|
||||||
onTap: widget.onNext!,
|
onTap: (context) {
|
||||||
|
widget.onNext!();
|
||||||
|
Navigator.of(context).pop(); // Close options menu
|
||||||
|
},
|
||||||
iconData: Icons.skip_next,
|
iconData: Icons.skip_next,
|
||||||
title: 'Next Channel',
|
title: 'Next Channel',
|
||||||
),
|
),
|
||||||
if (widget.onPrevious != null)
|
if (widget.onPrevious != null)
|
||||||
OptionItem(
|
OptionItem(
|
||||||
onTap: widget.onPrevious!,
|
onTap: (context) {
|
||||||
|
widget.onPrevious!();
|
||||||
|
Navigator.of(context).pop(); // Close options menu
|
||||||
|
},
|
||||||
iconData: Icons.skip_previous,
|
iconData: Icons.skip_previous,
|
||||||
title: 'Previous Channel',
|
title: 'Previous Channel',
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import '../../../../core/models/playlist_config.dart';
|
|||||||
import '../../../../features/iptv/models/xtream_models.dart';
|
import '../../../../features/iptv/models/xtream_models.dart';
|
||||||
import '../../../../features/iptv/providers/xtream_provider.dart';
|
import '../../../../features/iptv/providers/xtream_provider.dart';
|
||||||
import '../../../../features/iptv/providers/watch_history_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 'mobile_player_screen.dart';
|
||||||
import '../../../../core/theme/app_colors.dart';
|
import '../../../../core/theme/app_colors.dart';
|
||||||
import '../../../../core/widgets/glass_container.dart';
|
import '../../../../core/widgets/glass_container.dart';
|
||||||
|
|||||||
Reference in new issue
Block a user