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() 将是常态。如果您需要不同的选项,您可以将不同的选项作为媒体选项传递(尽管某些选项在媒体级别不可用,例如冗长选项(在这种情况下,我会在那里注册一个日志回调和过滤器))