LibVLCSharp 播放列表实现
LibVLCSharp Playlist implementation
我正在尝试将 LibVLCSharp 与播放列表(或者这就是计划)一起使用,并在两个不同视频之间使用基本循环对其进行测试。我在 WPF 中使用它。 UI 有一个按钮可以开始播放第一个视频。如果我不循环并每次单击按钮,下一个视频将按预期播放。让它循环并在第二个视频上发生线程错误。我已经查看了 SO - 上的其他一些帖子以及其中的各种链接,但我遗漏了一些东西。我希望有人有一个建议 - 或者两个!谢谢
XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
xmlns:local="clr-namespace:testVLC"
xmlns:Properties="clr-namespace:testVLC.Properties" x:Class="testVLC.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width=".2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=".25*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height=".25*"/>
<RowDefinition Height=".25*"/>
</Grid.RowDefinitions>
<wpf:VideoView x:Name="VLC_player" Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="3" Background="Black" Loaded="VLC_player_Loaded"/>
<Button x:Name="go_Btn" Content="Press to view video" Grid.Column="2" HorizontalAlignment="Right" Grid.Row="3" Padding="4,1" Margin="0,0,1,0" Click="Button_click"/>
<TextBox x:Name="countTBox" Grid.Column="2" HorizontalAlignment="Left" Grid.Row="3" Width="30" VerticalContentAlignment="Stretch"/>
</Grid>
</Window>
CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
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;
using LibVLCSharp.Shared;
using MediaPlayer = LibVLCSharp.Shared.MediaPlayer;
namespace testVLC
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
LibVLC _libVLC;
MediaPlayer media_player;
bool init_flag = false;
bool Web_flag = false;
int count = 0;
public MainWindow()
{
InitializeComponent();
}
private async void Media_play (string URI)
{
if (init_flag)
{
if(Web_flag)
{
_libVLC = new LibVLC("--verbose=2");
Media media = new Media(_libVLC, (URI), FromType.FromLocation);
await media.Parse(MediaParseOptions.ParseNetwork);
media_player = new MediaPlayer(media.SubItems.First());
VLC_player.MediaPlayer = media_player;
media_player.EndReached += Video_Ended;
media_player.Play();
//MessageBox.Show(Thread.CurrentThread.Name);
}
else
{
_libVLC = new LibVLC();
media_player = new MediaPlayer(_libVLC);
VLC_player.MediaPlayer = media_player;
media_player.EndReached += Video_Ended;
media_player.Play(new Media(_libVLC, URI));
}
}
}
private void Button_click(object sender, RoutedEventArgs e)
{
count++;
this.Dispatcher.Invoke((Action)(() =>
{
countTBox.Text = count.ToString();
}));
Main_List();
}
private async void Video_Ended(object sender, EventArgs e)
{
//ThreadPool.QueueUserWorkItem(_ => media_player.Stop());//doesn't work
await Task.Run(() => media_player.Stop());
Web_flag = false;
//Button_click(this, null);//Works fine when commented out and the "Press to view video" button is clicked each time. Not so much when looping.
}
private void Main_List()
{
if (count%2 == 0)//even
{
Media_play("C:\Users\echo_\Downloads\videoplayback (1).mp4");
}
else//odd
{
Web_flag = true;
Media_play("https://youtu.be/UK4t59mhIhs");
}
}
private void VLC_player_Loaded(object sender, RoutedEventArgs e)
{
init_flag = true;
Core.Initialize();
}
}
}
不要尝试在 VideoEnded 事件中调用 Stop,我认为 libvlc 3 中的这个区域存在一个挂起程序的已知问题。
使用新媒体调用 .Play。
此外,如果可以避免,我不建议使用两个不同的 libvlc 实例。 1 个 LibVlc 和 1 个 Media Player,但同一个 MediaPlayer 上的多个 Play() 将是常态。如果您需要不同的选项,您可以将不同的选项作为媒体选项传递(尽管某些选项在媒体级别不可用,例如冗长选项(在这种情况下,我会在那里注册一个日志回调和过滤器))
我正在尝试将 LibVLCSharp 与播放列表(或者这就是计划)一起使用,并在两个不同视频之间使用基本循环对其进行测试。我在 WPF 中使用它。 UI 有一个按钮可以开始播放第一个视频。如果我不循环并每次单击按钮,下一个视频将按预期播放。让它循环并在第二个视频上发生线程错误。我已经查看了 SO -
XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
xmlns:local="clr-namespace:testVLC"
xmlns:Properties="clr-namespace:testVLC.Properties" x:Class="testVLC.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width=".2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=".25*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height=".25*"/>
<RowDefinition Height=".25*"/>
</Grid.RowDefinitions>
<wpf:VideoView x:Name="VLC_player" Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="3" Background="Black" Loaded="VLC_player_Loaded"/>
<Button x:Name="go_Btn" Content="Press to view video" Grid.Column="2" HorizontalAlignment="Right" Grid.Row="3" Padding="4,1" Margin="0,0,1,0" Click="Button_click"/>
<TextBox x:Name="countTBox" Grid.Column="2" HorizontalAlignment="Left" Grid.Row="3" Width="30" VerticalContentAlignment="Stretch"/>
</Grid>
</Window>
CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
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;
using LibVLCSharp.Shared;
using MediaPlayer = LibVLCSharp.Shared.MediaPlayer;
namespace testVLC
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
LibVLC _libVLC;
MediaPlayer media_player;
bool init_flag = false;
bool Web_flag = false;
int count = 0;
public MainWindow()
{
InitializeComponent();
}
private async void Media_play (string URI)
{
if (init_flag)
{
if(Web_flag)
{
_libVLC = new LibVLC("--verbose=2");
Media media = new Media(_libVLC, (URI), FromType.FromLocation);
await media.Parse(MediaParseOptions.ParseNetwork);
media_player = new MediaPlayer(media.SubItems.First());
VLC_player.MediaPlayer = media_player;
media_player.EndReached += Video_Ended;
media_player.Play();
//MessageBox.Show(Thread.CurrentThread.Name);
}
else
{
_libVLC = new LibVLC();
media_player = new MediaPlayer(_libVLC);
VLC_player.MediaPlayer = media_player;
media_player.EndReached += Video_Ended;
media_player.Play(new Media(_libVLC, URI));
}
}
}
private void Button_click(object sender, RoutedEventArgs e)
{
count++;
this.Dispatcher.Invoke((Action)(() =>
{
countTBox.Text = count.ToString();
}));
Main_List();
}
private async void Video_Ended(object sender, EventArgs e)
{
//ThreadPool.QueueUserWorkItem(_ => media_player.Stop());//doesn't work
await Task.Run(() => media_player.Stop());
Web_flag = false;
//Button_click(this, null);//Works fine when commented out and the "Press to view video" button is clicked each time. Not so much when looping.
}
private void Main_List()
{
if (count%2 == 0)//even
{
Media_play("C:\Users\echo_\Downloads\videoplayback (1).mp4");
}
else//odd
{
Web_flag = true;
Media_play("https://youtu.be/UK4t59mhIhs");
}
}
private void VLC_player_Loaded(object sender, RoutedEventArgs e)
{
init_flag = true;
Core.Initialize();
}
}
}
不要尝试在 VideoEnded 事件中调用 Stop,我认为 libvlc 3 中的这个区域存在一个挂起程序的已知问题。 使用新媒体调用 .Play。
此外,如果可以避免,我不建议使用两个不同的 libvlc 实例。 1 个 LibVlc 和 1 个 Media Player,但同一个 MediaPlayer 上的多个 Play() 将是常态。如果您需要不同的选项,您可以将不同的选项作为媒体选项传递(尽管某些选项在媒体级别不可用,例如冗长选项(在这种情况下,我会在那里注册一个日志回调和过滤器))