Got WPF version work
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:TV_Player"
|
||||
StartupUri="MainWindow.xaml">
|
||||
>
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
@@ -0,0 +1,22 @@
|
||||
using DirectShowLib.BDA;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Windows;
|
||||
using TV_Player.ViewModels;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
private TVPlayerViewModel _tvPlayer;
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
_tvPlayer = new TVPlayerViewModel();
|
||||
|
||||
base.OnStartup(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
@@ -3,7 +3,6 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:TV_Player"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="100" d:DesignWidth="200">
|
||||
<Viewbox Grid.Row="1">
|
||||
@@ -6,13 +6,13 @@
|
||||
xmlns:local="clr-namespace:TV_Player"
|
||||
mc:Ignorable="d"
|
||||
Title="TV" Height="450" Width="800">
|
||||
<Window.Resources>
|
||||
<local:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
|
||||
</Window.Resources>
|
||||
<Window.DataContext>
|
||||
<local:MainViewModel/>
|
||||
</Window.DataContext>
|
||||
<Grid>
|
||||
<Grid.Background>
|
||||
<ImageBrush ImageSource="Assets/bkground.jpg" />
|
||||
</Grid.Background>
|
||||
<ContentControl Name="ControlContainer" />
|
||||
<ContentControl Name="ControlContainer" Content="{Binding Control}" />
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<UserControl x:Class="TV_Player.ProgramsGroupGrid"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:TV_Player"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid x:Name="groupsGrid">
|
||||
<ScrollViewer>
|
||||
<ListBox ItemsSource="{Binding Programs}"
|
||||
SelectionMode="Single"
|
||||
SelectedItem="{Binding SelectedItem}"
|
||||
SelectionChanged="ListBox_SelectionChanged">
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ProgramsGroupGrid.xaml
|
||||
/// </summary>
|
||||
public partial class ProgramsGroupGrid : UserControl
|
||||
{
|
||||
public ProgramsGroupGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (DataContext is ProgramsGroupViewModel viewModel)
|
||||
{
|
||||
viewModel.ItemSelectedCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<UserControl x:Class="TV_Player.ProgramsList"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid x:Name="groupsGrid">
|
||||
<ScrollViewer>
|
||||
<ListBox ItemsSource="{Binding Programs}"
|
||||
SelectionMode="Single"
|
||||
SelectedItem="{Binding SelectedItem}"
|
||||
SelectionChanged="ListBox_SelectionChanged">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<Image Source="{Binding Logo}" Width="50" Height="50"/>
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ProgramsGroupGrid.xaml
|
||||
/// </summary>
|
||||
public partial class ProgramsList : UserControl
|
||||
{
|
||||
public ProgramsList()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (DataContext is ProgramsListViewModel viewModel)
|
||||
{
|
||||
viewModel.ItemSelectedCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.20" />
|
||||
<PackageReference Include="Vlc.DotNet.Wpf" Version="3.1.0" />
|
||||
<PackageReference Include="LibVLCSharp" Version="3.8.2" />
|
||||
<PackageReference Include="LibVLCSharp.WPF" Version="3.8.2" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.0" />
|
||||
<PackageReference Include="WPFMediaKitCore" Version="0.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -26,4 +27,13 @@
|
||||
</Resource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="VideoPlayer.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="ProgramsList.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,31 @@
|
||||
<UserControl x:Class="TV_Player.VideoPlayer"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
>
|
||||
|
||||
<Grid>
|
||||
<Grid x:Name="videoPlayer">
|
||||
<vlc:VideoView x:Name="VideoView" Panel.ZIndex="1">
|
||||
<StackPanel Panel.ZIndex="2" Opacity="0.9"
|
||||
IsHitTestVisible="True"
|
||||
HorizontalAlignment="Stretch" MouseLeftButtonDown="MyUserControl_MouseDown"
|
||||
TouchDown="MyUserControl_TouchDown" >
|
||||
<Grid x:Name="overlayPanel" Visibility="Collapsed" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="0" Content="Pause" HorizontalAlignment="Stretch" Click="PauseButton_Click" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</vlc:VideoView>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,114 @@
|
||||
using LibVLCSharp.Shared;
|
||||
using LibVLCSharp.WPF;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ProgramsGroupGrid.xaml
|
||||
/// </summary>
|
||||
public partial class VideoPlayer : UserControl
|
||||
{
|
||||
private readonly DirectoryInfo vlcLibDirectory;
|
||||
|
||||
public static readonly DependencyProperty SourceUrlProperty =
|
||||
DependencyProperty.Register(
|
||||
"SourceUrl", // Name of the property
|
||||
typeof(string), // Type of the property
|
||||
typeof(VideoPlayer), // Type of the owner class
|
||||
new PropertyMetadata(string.Empty) // Default value
|
||||
);
|
||||
|
||||
LibVLC _libVLC;
|
||||
MediaPlayer _mediaPlayer;
|
||||
|
||||
public string SourceUrl
|
||||
{
|
||||
get { return (string)GetValue(SourceUrlProperty); }
|
||||
set { SetValue(SourceUrlProperty, value);}
|
||||
}
|
||||
public VideoPlayer()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_libVLC = new LibVLC(enableDebugLogs: true);
|
||||
_mediaPlayer = new MediaPlayer(_libVLC);
|
||||
|
||||
VideoView.Loaded += (sender, e) =>
|
||||
{
|
||||
VideoView.MediaPlayer = _mediaPlayer;
|
||||
VideoView.MouseLeftButtonDown += VideoView_MouseLeftButtonDown;
|
||||
VideoView.MediaPlayer.EnableMouseInput = false;
|
||||
VideoView.PreviewMouseLeftButtonDown += VideoView_MouseLeftButtonDown;
|
||||
AutoPlay();
|
||||
};
|
||||
Unloaded += VideoPlayer_Unloaded;
|
||||
|
||||
}
|
||||
|
||||
private void VideoView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ToggleOverlay();
|
||||
}
|
||||
|
||||
private void VideoPlayer_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
VideoView.Dispose();
|
||||
}
|
||||
|
||||
|
||||
void PauseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (VideoView.MediaPlayer.IsPlaying)
|
||||
{
|
||||
VideoView.MediaPlayer.Pause();
|
||||
}
|
||||
}
|
||||
|
||||
private void AutoPlay()
|
||||
{
|
||||
if (!VideoView.MediaPlayer.IsPlaying)
|
||||
{
|
||||
|
||||
using (var media = new Media(_libVLC, new Uri(SourceUrl)))
|
||||
VideoView.MediaPlayer.Play(media);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void MyUserControl_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ToggleOverlay();
|
||||
}
|
||||
|
||||
private void MyUserControl_TouchDown(object sender, TouchEventArgs e)
|
||||
{
|
||||
ToggleOverlay();
|
||||
}
|
||||
|
||||
private void ToggleOverlay()
|
||||
{
|
||||
if (overlayPanel.Visibility == Visibility.Visible)
|
||||
{
|
||||
HideOverlay();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowOverlay()
|
||||
{
|
||||
overlayPanel.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
public void HideOverlay()
|
||||
{
|
||||
overlayPanel.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace TV_Player
|
||||
{
|
||||
public class GroupInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Count { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ namespace TV_Player
|
||||
GroupTitle = match.Groups["GroupTitle"].Value,
|
||||
Logo = match.Groups["Logo"].Value,
|
||||
Name = match.Groups["Name"].Value,
|
||||
Url = match.Groups["Url"].Value
|
||||
Url = match.Groups["URL"].Value
|
||||
};
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public class MainViewModel : ObservableViewModelBase
|
||||
{
|
||||
private ContentControl _control;
|
||||
public ContentControl Control
|
||||
{
|
||||
get => _control;
|
||||
set => SetProperty(ref _control, value);
|
||||
}
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
var vm = new ProgramsGroupViewModel();
|
||||
|
||||
var control = new ProgramsGroupGrid();
|
||||
control.DataContext = vm;
|
||||
Control = control;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public abstract class ObservableViewModelBase : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void RaisePropertyChanged(string propertyName)
|
||||
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
|
||||
/// <summary>
|
||||
/// Set a property and raise a property changed event if it has changed
|
||||
/// </summary>
|
||||
protected bool SetProperty<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(property, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
property = value;
|
||||
RaisePropertyChanged(propertyName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
|
||||
public class PlayerViewModel: ObservableViewModelBase
|
||||
{
|
||||
|
||||
private readonly M3UInfo _currentProgram;
|
||||
|
||||
private string _urlSource;
|
||||
public string URLSource
|
||||
{
|
||||
get => _urlSource;
|
||||
set => SetProperty(ref _urlSource, value);
|
||||
}
|
||||
|
||||
public GroupInfo SelectedItem { get; set; }
|
||||
public ICommand PlayCommand { get; }
|
||||
|
||||
public PlayerViewModel(M3UInfo selectedProgram)
|
||||
{
|
||||
_currentProgram = selectedProgram;
|
||||
//PlayM3U8(_currentProgram.Url);
|
||||
//_libVLC = new LibVLC();
|
||||
//_mediaPlayer = new MediaPlayer(new Media(_libVLC, new Uri(_currentProgram.Url)));
|
||||
//_mediaPlayer.Play();
|
||||
//PlayCommand = new Command(OnPlayButtonClicked);
|
||||
}
|
||||
|
||||
private void OnPlayButtonClicked()
|
||||
{
|
||||
PlayM3U8(_currentProgram.Url);
|
||||
}
|
||||
|
||||
private void PlayM3U8(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
URLSource = _currentProgram.Url;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Handle exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Reactive.Subjects;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public class ProgramsData
|
||||
{
|
||||
private static ProgramsData _instance;
|
||||
public static ProgramsData Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
_instance ??= new ProgramsData();
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ReplaySubject<List<M3UInfo>> programsSubject = new ReplaySubject<List<M3UInfo>>();
|
||||
private readonly ReplaySubject<List<GroupInfo>> groupsSubject = new ReplaySubject<List<GroupInfo>>();
|
||||
public IObservable<List<M3UInfo>> AllPrograms => programsSubject;
|
||||
public IObservable<List<GroupInfo>> GroupsInformation => groupsSubject;
|
||||
|
||||
private ProgramsData()
|
||||
{
|
||||
_=Initialize();
|
||||
}
|
||||
private async Task Initialize()
|
||||
{
|
||||
string m3uLink = "http://pl.da-tv.vip/a71e77fa/835b3216/tv.m3u";
|
||||
var programs = await M3UParser.DownloadM3UFromWebAsync(m3uLink);
|
||||
|
||||
programsSubject.OnNext(programs);
|
||||
|
||||
var groupping = programs.GroupBy(item => item.GroupTitle)
|
||||
.Select(group => new GroupInfo() { Name = group.Key, Count = group.Count() })
|
||||
.ToList();
|
||||
groupsSubject.OnNext(groupping);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using System.Windows.Input;
|
||||
using TV_Player.ViewModels;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public class ProgramsGroupViewModel : ObservableViewModelBase
|
||||
{
|
||||
private List<GroupInfo> _programs;
|
||||
public List<GroupInfo> Programs
|
||||
{
|
||||
get => _programs;
|
||||
set => SetProperty(ref _programs, value);
|
||||
}
|
||||
|
||||
public GroupInfo SelectedItem { get; set; }
|
||||
public ICommand ItemSelectedCommand { get; }
|
||||
|
||||
public ProgramsGroupViewModel()
|
||||
{
|
||||
ItemSelectedCommand = new RelayCommand(OnItemSelected);
|
||||
ProgramsData.Instance.GroupsInformation.Subscribe(x=>Programs = x);
|
||||
}
|
||||
|
||||
private void OnItemSelected()
|
||||
{
|
||||
//var navigation = (INavigation)Application.Current.MainPage.Navigation;
|
||||
|
||||
var programListViewModel = new ProgramsListViewModel(SelectedItem);
|
||||
var conrtrol = new ProgramsList();
|
||||
TVPlayerViewModel.Instance.SetPageContext(conrtrol, programListViewModel);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using System.Windows.Input;
|
||||
using TV_Player.ViewModels;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public class ProgramsListViewModel : ObservableViewModelBase
|
||||
{
|
||||
private List<M3UInfo> _programs;
|
||||
public List<M3UInfo> Programs
|
||||
{
|
||||
get => _programs;
|
||||
set => SetProperty(ref _programs, value);
|
||||
}
|
||||
|
||||
public M3UInfo SelectedItem { get; set; }
|
||||
public ICommand ItemSelectedCommand { get; }
|
||||
|
||||
public ProgramsListViewModel(GroupInfo groupInfo)
|
||||
{
|
||||
ItemSelectedCommand = new RelayCommand(OnItemSelected);
|
||||
ProgramsData.Instance.AllPrograms.Subscribe(x=>Programs = x.Where(p=>p.GroupTitle== groupInfo.Name).ToList());
|
||||
}
|
||||
|
||||
private void OnItemSelected()
|
||||
{
|
||||
|
||||
var playerViewModel = new PlayerViewModel(SelectedItem);
|
||||
var conrtrol = new VideoPlayer();
|
||||
conrtrol.SourceUrl = SelectedItem.Url;
|
||||
TVPlayerViewModel.Instance.SetPageContext(conrtrol, playerViewModel);
|
||||
//var navigation = (INavigation)Application.Current.MainPage.Navigation;
|
||||
|
||||
//var playerViewModel = new PlayerViewModel(SelectedItem);
|
||||
|
||||
//// Create a new SecondPage and set its BindingContext to the ViewModel
|
||||
//var playerPage = new PlayerPage
|
||||
//{
|
||||
// BindingContext = playerViewModel
|
||||
//};
|
||||
//// Navigate to the OtherPage
|
||||
//navigation.PushAsync(playerPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace TV_Player.ViewModels
|
||||
{
|
||||
//public class RelayCommand : ICommand
|
||||
//{
|
||||
// private readonly Action _execute;
|
||||
// private readonly Func<bool> _canExecute;
|
||||
|
||||
// public event EventHandler CanExecuteChanged;
|
||||
|
||||
// public RelayCommand(Action execute, Func<bool> canExecute = null)
|
||||
// {
|
||||
// _execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||
// _canExecute = canExecute;
|
||||
// }
|
||||
|
||||
// public bool CanExecute(object parameter)
|
||||
// {
|
||||
// return _canExecute == null || _canExecute();
|
||||
// }
|
||||
|
||||
// public void Execute(object parameter)
|
||||
// {
|
||||
// _execute();
|
||||
// }
|
||||
|
||||
// public void RaiseCanExecuteChanged()
|
||||
// {
|
||||
// CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace TV_Player.ViewModels
|
||||
{
|
||||
public class TVPlayerViewModel
|
||||
{
|
||||
private readonly MainViewModel _mainViewModel;
|
||||
|
||||
private static TVPlayerViewModel _instance;
|
||||
public static TVPlayerViewModel Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_instance==null)
|
||||
_instance = new TVPlayerViewModel();
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public TVPlayerViewModel()
|
||||
{
|
||||
_mainViewModel = new MainViewModel();
|
||||
var mainWindow=new MainWindow();
|
||||
mainWindow.DataContext = _mainViewModel;
|
||||
|
||||
mainWindow.Show();
|
||||
_instance = this;
|
||||
}
|
||||
|
||||
public void SetPageContext(ContentControl control, object viewModel)
|
||||
{
|
||||
control.DataContext = viewModel;
|
||||
_mainViewModel.Control = control;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?xml version = "1.0" encoding = "UTF-8" ?>
|
||||
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:TV_Player"
|
||||
x:Class="TV_Player.App">
|
||||
xmlns:local="clr-namespace:TV_Player.MAUI"
|
||||
x:Class="TV_Player.MAUI.App">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<Shell
|
||||
x:Class="TV_Player.AppShell"
|
||||
x:Class="TV_Player.MAUI.AppShell"
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:TV_Player"
|
||||
xmlns:local="clr-namespace:TV_Player.MAUI"
|
||||
Shell.FlyoutBehavior="Disabled">
|
||||
|
||||
<ShellContent
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public partial class AppShell : Shell
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:TV_Player"
|
||||
x:Class="TV_Player.MainPage">
|
||||
xmlns:local="clr-namespace:TV_Player.MAUI"
|
||||
x:Class="TV_Player.MAUI.MainPage">
|
||||
<ContentPage.BindingContext>
|
||||
<local:MainViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
@@ -15,7 +15,7 @@
|
||||
SelectedItem="{Binding SelectedItem}"
|
||||
SelectionChangedCommand="{Binding ItemSelectedCommand}">
|
||||
<CollectionView.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:GroupInfo">
|
||||
<DataTemplate x:DataType="local:M3UInfo">
|
||||
<Label Text="{Binding Name}"/>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public partial class MainPage : ContentPage
|
||||
{
|
||||
@@ -6,18 +6,6 @@
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
//private void OnCounterClicked(object sender, EventArgs e)
|
||||
//{
|
||||
// count++;
|
||||
|
||||
// if (count == 1)
|
||||
// CounterBtn.Text = $"Clicked {count} time";
|
||||
// else
|
||||
// CounterBtn.Text = $"Clicked {count} times";
|
||||
|
||||
// SemanticScreenReader.Announce(CounterBtn.Text);
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using CommunityToolkit.Maui;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public static class MauiProgram
|
||||
{
|
||||
@@ -9,6 +10,7 @@ namespace TV_Player
|
||||
var builder = MauiApp.CreateBuilder();
|
||||
builder
|
||||
.UseMauiApp<App>()
|
||||
.UseMauiCommunityToolkitMediaElement()
|
||||
.ConfigureFonts(fonts =>
|
||||
{
|
||||
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using LibVLCSharp.Shared;
|
||||
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public class MediaViewer : ContentView
|
||||
{
|
||||
private LibVLC _libVLC;
|
||||
private MediaPlayer _mediaPlayer;
|
||||
|
||||
public static BindableProperty StreamUrlProperty = BindableProperty.Create(nameof(StreamUrl)
|
||||
, typeof(string)
|
||||
, typeof(MediaViewer)
|
||||
, ""
|
||||
, defaultBindingMode: BindingMode.TwoWay);
|
||||
|
||||
public string StreamUrl
|
||||
{
|
||||
get => (string)GetValue(StreamUrlProperty);
|
||||
set
|
||||
{
|
||||
SetValue(StreamUrlProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public MediaViewer()
|
||||
{
|
||||
InitializeMediaPlayer();
|
||||
}
|
||||
|
||||
private void InitializeMediaPlayer()
|
||||
{
|
||||
_libVLC = new LibVLC();
|
||||
_mediaPlayer = new MediaPlayer(_libVLC);
|
||||
// var media = new Media(_libVLC, new Uri("http://ost.da-tv.vip/uPVtzdGJfdG9rZW5dIiwibCI6ImE3MWU3N2ZhIiwicCI6ImE3MWU3N2ZhODM1YjMyMTYiLCJjIjoiNDk3IiwidCI6ImUzNjAwZTEwZmFmMGVhYjhhYWY1YTU2YzRkN2VjZTE5IiwiZCI6IjIzMTQ2IiwiciI6IjIzMDM4IiwibSI6InR2IiwiZHQiOiIwIn0eyJ1IjoiaHR0cDovLzQ1LjkzLjQ2LjI3Ojg4ODcvODM2MS92aWRlby5tM3U4P3Rva2V/video.m3u8"));
|
||||
//_mediaPlayer.Play();
|
||||
}
|
||||
|
||||
public void Play()
|
||||
{
|
||||
var media = new Media(_libVLC, new Uri("http://ost.da-tv.vip/uPVtzdGJfdG9rZW5dIiwibCI6ImE3MWU3N2ZhIiwicCI6ImE3MWU3N2ZhODM1YjMyMTYiLCJjIjoiNDk3IiwidCI6ImUzNjAwZTEwZmFmMGVhYjhhYWY1YTU2YzRkN2VjZTE5IiwiZCI6IjIzMTQ2IiwiciI6IjIzMDM4IiwibSI6InR2IiwiZHQiOiIwIn0eyJ1IjoiaHR0cDovLzQ1LjkzLjQ2LjI3Ojg4ODcvODM2MS92aWRlby5tM3U4P3Rva2V/video.m3u8"));
|
||||
_mediaPlayer.Play(media);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Android.App;
|
||||
using Android.Runtime;
|
||||
using TV_Player.MAUI;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using Foundation;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : MauiUIApplicationDelegate
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/appicon.appiconset</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,16 +0,0 @@
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using Microsoft.Maui;
|
||||
using Microsoft.Maui.Hosting;
|
||||
using System;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
internal class Program : MauiApplication
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var app = new Program();
|
||||
app.Run(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="maui-application-id-placeholder" version="0.0.0" api-version="7" xmlns="http://tizen.org/ns/packages">
|
||||
<profile name="common" />
|
||||
<ui-application appid="maui-application-id-placeholder" exec="TV Player.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
|
||||
<label>maui-application-title-placeholder</label>
|
||||
<icon>maui-appicon-placeholder</icon>
|
||||
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
|
||||
</ui-application>
|
||||
<shortcut-list />
|
||||
<privileges>
|
||||
<privilege>http://tizen.org/privilege/internet</privilege>
|
||||
</privileges>
|
||||
<dependencies />
|
||||
<provides-appdefined-privileges />
|
||||
</manifest>
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using TV_Player.MAUI;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using Foundation;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : MauiUIApplicationDelegate
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/appicon.appiconset</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,16 +0,0 @@
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TV_Player.MAUI.PlayerPage"
|
||||
xmlns:local="clr-namespace:TV_Player.MAUI"
|
||||
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
|
||||
Title="PlayerPage"
|
||||
Loaded="ContentPage_Loaded">
|
||||
|
||||
<StackLayout>
|
||||
<toolkit:MediaElement x:Name="mediaElement"
|
||||
ShouldAutoPlay="True"
|
||||
ShouldShowPlaybackControls="True"
|
||||
Source="http://ost.da-tv.vip/uPVtzdGJfdG9rZW5dIiwibCI6ImE3MWU3N2ZhIiwicCI6ImE3MWU3N2ZhODM1YjMyMTYiLCJjIjoiNDk3IiwidCI6ImUzNjAwZTEwZmFmMGVhYjhhYWY1YTU2YzRkN2VjZTE5IiwiZCI6IjIzMTQ2IiwiciI6IjIzMDM4IiwibSI6InR2IiwiZHQiOiIwIn0eyJ1IjoiaHR0cDovLzQ1LjkzLjQ2LjI3Ojg4ODcvODM2MS92aWRlby5tM3U4P3Rva2V/video.m3u8"
|
||||
HeightRequest="300"
|
||||
WidthRequest="400"
|
||||
/>
|
||||
<!--<local:MediaViewer x:Name="libVLCSharpView" WidthRequest="300" HeightRequest="300" HorizontalOptions="CenterAndExpand" StreamUrl="{Binding URLSource,Source={x:Reference MyCustomView}}"/>-->
|
||||
<Button Text="Play" Command="{Binding PlayCommand}" />
|
||||
</StackLayout>
|
||||
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace TV_Player.MAUI;
|
||||
|
||||
public partial class PlayerPage : ContentPage
|
||||
{
|
||||
public PlayerPage()
|
||||
{
|
||||
this.BindingContext = this;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void ContentPage_Loaded(object sender, EventArgs e)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:TV_Player.MAUI"
|
||||
x:Class="TV_Player.MAUI.ProgramPage">
|
||||
|
||||
<ScrollView>
|
||||
<VerticalStackLayout
|
||||
Padding="30,0"
|
||||
VerticalOptions="Center">
|
||||
|
||||
<CollectionView ItemsSource="{Binding Programs}"
|
||||
ItemsLayout="VerticalGrid, 5" SelectionMode="Single"
|
||||
SelectedItem="{Binding SelectedItem}"
|
||||
SelectionChangedCommand="{Binding ItemSelectedCommand}">
|
||||
<CollectionView.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:M3UInfo">
|
||||
<VerticalStackLayout>
|
||||
<Image Source="{Binding Logo}" WidthRequest="50" HeightRequest="50"/>
|
||||
<Label Text="{Binding Name}" HorizontalTextAlignment="Center"/>
|
||||
</VerticalStackLayout>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public partial class ProgramPage : ContentPage
|
||||
{
|
||||
public ProgramPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,9 @@
|
||||
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
|
||||
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -49,8 +46,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Maui.MediaElement" Version="3.0.1" />
|
||||
<PackageReference Include="LibVLCSharp" Version="3.8.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.0" />
|
||||
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.20" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0-ios'">
|
||||
@@ -65,4 +65,25 @@
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="ProgramPage.xaml.cs">
|
||||
<DependentUpon>ProgramPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<MauiXaml Update="PlayerPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="ProgramPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="PlayerPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public class GroupInfo
|
||||
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Count { get; set; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public class M3UInfo
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public static class M3UParser
|
||||
{
|
||||
@@ -89,7 +89,7 @@ namespace TV_Player
|
||||
GroupTitle = match.Groups["GroupTitle"].Value,
|
||||
Logo = match.Groups["Logo"].Value,
|
||||
Name = match.Groups["Name"].Value,
|
||||
Url = match.Groups["Url"].Value
|
||||
Url = match.Groups["URL"].Value
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public class MainViewModel : ObservableViewModelBase
|
||||
{
|
||||
@@ -22,7 +22,17 @@ namespace TV_Player
|
||||
|
||||
private void OnItemSelected()
|
||||
{
|
||||
var navigation = (INavigation)Application.Current.MainPage.Navigation;
|
||||
|
||||
var programPageViewModel = new ProgramViewModel(SelectedItem);
|
||||
|
||||
// Create a new SecondPage and set its BindingContext to the ViewModel
|
||||
var programPage = new ProgramPage
|
||||
{
|
||||
BindingContext = programPageViewModel
|
||||
};
|
||||
// Navigate to the OtherPage
|
||||
navigation.PushAsync(programPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public abstract class ObservableViewModelBase : INotifyPropertyChanged
|
||||
{
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
using LibVLCSharp.Shared;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
|
||||
public class PlayerViewModel: ObservableViewModelBase
|
||||
{
|
||||
|
||||
private readonly M3UInfo _currentProgram;
|
||||
|
||||
private string _urlSource;
|
||||
public string URLSource
|
||||
{
|
||||
get => _urlSource;
|
||||
set => SetProperty(ref _urlSource, value);
|
||||
}
|
||||
|
||||
public GroupInfo SelectedItem { get; set; }
|
||||
public ICommand PlayCommand { get; }
|
||||
|
||||
public PlayerViewModel(M3UInfo selectedProgram)
|
||||
{
|
||||
_currentProgram = selectedProgram;
|
||||
//PlayM3U8(_currentProgram.Url);
|
||||
//_libVLC = new LibVLC();
|
||||
//_mediaPlayer = new MediaPlayer(new Media(_libVLC, new Uri(_currentProgram.Url)));
|
||||
//_mediaPlayer.Play();
|
||||
PlayCommand = new Command(OnPlayButtonClicked);
|
||||
}
|
||||
|
||||
private void OnPlayButtonClicked()
|
||||
{
|
||||
PlayM3U8(_currentProgram.Url);
|
||||
}
|
||||
|
||||
private void PlayM3U8(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
URLSource = _currentProgram.Url;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Handle exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public class ProgramViewModel : ObservableViewModelBase
|
||||
{
|
||||
private List<M3UInfo> _programs;
|
||||
public List<M3UInfo> Programs
|
||||
{
|
||||
get => _programs;
|
||||
set => SetProperty(ref _programs, value);
|
||||
}
|
||||
|
||||
public M3UInfo SelectedItem { get; set; }
|
||||
public ICommand ItemSelectedCommand { get; }
|
||||
|
||||
public ProgramViewModel(GroupInfo groupInfo)
|
||||
{
|
||||
ItemSelectedCommand = new Command(OnItemSelected);
|
||||
ProgramsData.Instance.AllPrograms.Subscribe(x=>Programs = x.Where(p=>p.GroupTitle== groupInfo.Name).ToList());
|
||||
}
|
||||
|
||||
private void OnItemSelected()
|
||||
{
|
||||
var navigation = (INavigation)Application.Current.MainPage.Navigation;
|
||||
|
||||
var playerViewModel = new PlayerViewModel(SelectedItem);
|
||||
|
||||
// Create a new SecondPage and set its BindingContext to the ViewModel
|
||||
var playerPage = new PlayerPage
|
||||
{
|
||||
BindingContext = playerViewModel
|
||||
};
|
||||
// Navigate to the OtherPage
|
||||
navigation.PushAsync(playerPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Reactive.Subjects;
|
||||
|
||||
namespace TV_Player
|
||||
namespace TV_Player.MAUI
|
||||
{
|
||||
public class ProgramsData
|
||||
{
|
||||
@@ -14,10 +14,10 @@ namespace TV_Player
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Subject<List<M3UInfo>> programsSubject = new Subject<List<M3UInfo>>();
|
||||
private readonly Subject<List<GroupInfo>> groupsSubject = new Subject<List<GroupInfo>>();
|
||||
private readonly ReplaySubject<List<M3UInfo>> programsSubject = new ReplaySubject<List<M3UInfo>>();
|
||||
private readonly ReplaySubject<List<GroupInfo>> groupsSubject = new ReplaySubject<List<GroupInfo>>();
|
||||
public IObservable<List<M3UInfo>> AllPrograms => programsSubject;
|
||||
public Subject<List<GroupInfo>> GroupsInformation => groupsSubject;
|
||||
public IObservable<List<GroupInfo>> GroupsInformation => groupsSubject;
|
||||
|
||||
private ProgramsData()
|
||||
{
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Windows;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Vlc.DotNet.Wpf;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private readonly DirectoryInfo vlcLibDirectory;
|
||||
private VlcControl control;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
var currentAssembly = Assembly.GetEntryAssembly();
|
||||
var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;
|
||||
// Default installation path of VideoLAN.LibVLC.Windows
|
||||
vlcLibDirectory = new DirectoryInfo(Path.Combine(currentDirectory, "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64"));
|
||||
|
||||
this.control = new VlcControl();
|
||||
this.control.SourceProvider.CreatePlayer(vlcLibDirectory/* pass your player parameters here */);
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override void OnClosing(CancelEventArgs e)
|
||||
{
|
||||
this.control?.Dispose();
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
private void OnPlayButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
//this.control?.Dispose();
|
||||
//this.control = new VlcControl();
|
||||
//this.ControlContainer.Content = this.control;
|
||||
//this.control.SourceProvider.CreatePlayer(this.vlcLibDirectory);
|
||||
|
||||
// This can also be called before EndInit
|
||||
this.control.SourceProvider.MediaPlayer.Log += (_, args) =>
|
||||
{
|
||||
string message = $"libVlc : {args.Level} {args.Message} @ {args.Module}";
|
||||
System.Diagnostics.Debug.WriteLine(message);
|
||||
};
|
||||
|
||||
control.SourceProvider.MediaPlayer.Play(new Uri("http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi"));
|
||||
}
|
||||
|
||||
private void OnStopButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.control?.Dispose();
|
||||
this.control = null;
|
||||
}
|
||||
|
||||
private void OnForwardButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.control == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.control.SourceProvider.MediaPlayer.Rate = 2;
|
||||
}
|
||||
|
||||
private void GetLength_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.control == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//GetLength.Content = this.control.SourceProvider.MediaPlayer.Length + " ms";
|
||||
}
|
||||
|
||||
private void GetCurrentTime_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.control == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//GetCurrentTime.Content = this.control.SourceProvider.MediaPlayer.Time + " ms";
|
||||
}
|
||||
|
||||
private void SetCurrentTime_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.control == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.control.SourceProvider.MediaPlayer.Time = 5000;
|
||||
//SetCurrentTime.Content = this.control.SourceProvider.MediaPlayer.Time + " ms";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
public class MainWindowViewModel
|
||||
{
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
private async Task Initialize()
|
||||
{
|
||||
string m3uLink = "http://pl.da-tv.vip/a71e77fa/835b3216/tv.m3u";
|
||||
var programs = await M3UParser.DownloadM3UFromWebAsync(m3uLink);
|
||||
var groupedPrograms = programs.GroupBy(item => item.GroupTitle)
|
||||
.ToDictionary(
|
||||
group => group.Key,
|
||||
group => group.Select(item => item).ToList()
|
||||
);
|
||||
|
||||
var row = 0;
|
||||
var column = 0;
|
||||
|
||||
foreach (var group in groupedPrograms)
|
||||
{
|
||||
var button = new GroupButton(group.Key, group.Value.Count());
|
||||
button.TouchDown += (s, e) =>
|
||||
{
|
||||
|
||||
};
|
||||
Grid.SetRow(button, row);
|
||||
Grid.SetColumn(button, column);
|
||||
groupsGrid.Children.Add(button);
|
||||
column++;
|
||||
if (column > 4)
|
||||
{
|
||||
row++;
|
||||
column = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<UserControl x:Class="TV_Player.ProgramsGroupGrid"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:TV_Player"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid x:Name="groupsGrid" Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace TV_Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ProgramsGroupGrid.xaml
|
||||
/// </summary>
|
||||
public partial class ProgramsGroupGrid : UserControl
|
||||
{
|
||||
public ProgramsGroupGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-7
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34330.188
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TV Player", "TV Player\TV Player.csproj", "{A2ADD73B-0E50-4D86-9E1B-35FB2A31F5BF}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TV Player WPF", "TV Player WPF\TV Player WPF.csproj", "{556AB42C-8961-4051-B0DC-A6B907121B9E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TV Player MAUI", "TV Player\TV Player MAUI.csproj", "{4AEADD32-BAF5-4FB8-AB5B-63050CF46D29}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -11,12 +13,16 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A2ADD73B-0E50-4D86-9E1B-35FB2A31F5BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2ADD73B-0E50-4D86-9E1B-35FB2A31F5BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2ADD73B-0E50-4D86-9E1B-35FB2A31F5BF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{A2ADD73B-0E50-4D86-9E1B-35FB2A31F5BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2ADD73B-0E50-4D86-9E1B-35FB2A31F5BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A2ADD73B-0E50-4D86-9E1B-35FB2A31F5BF}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{556AB42C-8961-4051-B0DC-A6B907121B9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{556AB42C-8961-4051-B0DC-A6B907121B9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{556AB42C-8961-4051-B0DC-A6B907121B9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{556AB42C-8961-4051-B0DC-A6B907121B9E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4AEADD32-BAF5-4FB8-AB5B-63050CF46D29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4AEADD32-BAF5-4FB8-AB5B-63050CF46D29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4AEADD32-BAF5-4FB8-AB5B-63050CF46D29}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{4AEADD32-BAF5-4FB8-AB5B-63050CF46D29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4AEADD32-BAF5-4FB8-AB5B-63050CF46D29}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4AEADD32-BAF5-4FB8-AB5B-63050CF46D29}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user