【问题标题】:C# LibVLCSharp issue with playing YouTube播放 YouTube 的 C# LibVLCSharp 问题
【发布时间】:2021-10-05 06:22:59
【问题描述】:

我正在尝试在 WPF 应用程序中的多个实例上使用 LibVLC 播放 YouTube。 这可能在 75% 的情况下都可以正常工作,但流会冻结一两秒,而在另外 25% 的情况下会被像素化。这似乎是随机的。

这是我的代码:

public async void PlayUri(string path, bool isMuted, bool repeat)
{
    await Dispatcher.InvokeAsync(new Action(async () =>
    {
        Core.Initialize();

        using (LibVLC libVLC = new LibVLC(MediaOptions(repeat)))
        {
            using (var media = new Media(libVLC, path, FromType.FromLocation))
            {
                await media.Parse(MediaParseOptions.ParseNetwork);
                vlcPlayer = new MediaPlayer(media.SubItems.FirstOrDefault());
                if (!repeat)
                    vlcPlayer.EndReached += (sender, args) => ThreadPool.QueueUserWorkItem(_ => waitHandle.Set());
                VideoView.MediaPlayer = vlcPlayer;
                VideoView.MediaPlayer.Play();
            }

            // Set the sound and audio output device            
            SetAudioToDirectsound(isMuted);
        }
    }));            
}

MediaOptions 只是传递一个字符串[]

mediaOptions = new[]
{
    "--input-repeat=5",
    "--sout-mux-caching=12000"
};

And(为了完整性)SetAudioToDirectSount(bool)

var directsound = VideoView.MediaPlayer.SetAudioOutput("directsound");
IsMuted = isMuted;

这个“--sout-mux-caching=12000”选项应该缓存接下来 12 秒的视频。
这是正确的,我需要任何其他选择吗?我查看了所有 cmd 行选项,似乎找不到任何明显的东西。

阅读最佳实践here,它提到
“VL​​C 核心开发人员建议在应用程序的生命周期中仅创建一个类型为 LibVLC 的实例。您可以从单个 LibVLC 对象创建任意数量的 MediaPlayer 对象。”

就我而言,它嵌套在 using 语句中,因此我似乎没有遵循最佳实践。所以我应该声明:

Core.Initialize();
public LibVLC libVLC {get; set; } = new LibVLC();

只有一次,并且只在卸载时处理 MediaPlayer?


最小化测试解决方案

名为 VLCStream 的新 WPF 项目

NuGet 安装:

  • VideoLAN.LibVLC.Windows
  • LibVLCSharp.WPF
  • LibVLCSharp

MainWindow.xaml

<Window x:Class="VLCStream.MainWindow"
        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:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
        xmlns:local="clr-namespace:VLCStream"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        Loaded="Window_Loaded">
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Button Content="Play" Click="Button_Click" />

        <vlc:VideoView x:Name="VideoView" Grid.Row="1" />
    </Grid>
</Window>

MainWindow.xaml.cs

using LibVLCSharp.Shared;
using LibVLCSharp.WPF;
using System;
using System.Linq;
using System.Windows;

namespace VLCStream
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Dispatcher.InvokeAsync(new Action(async () =>
            {
                using (LibVLC libVLC = new LibVLC("--sout-mux-caching=12000"))
                {
                    using (var media = new Media(libVLC, "https://youtu.be/pW-iVG0_D34", FromType.FromLocation))
                    {
                        await media.Parse(MediaParseOptions.ParseNetwork);
                        MediaPlayer vlcPlayer = new MediaPlayer(media.SubItems.FirstOrDefault());
                        VideoView.MediaPlayer = vlcPlayer;
                        VideoView.MediaPlayer.Play();
                    }
                }
            }));
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Core.Initialize();
        }
    }
}

问题似乎是随机的,需要运行 1 次以上。

【问题讨论】:

  • 在应用程序的生命周期中只创建一个类型为 LibVLC 的实例”对我来说似乎是相当直截了当的措辞。试试看是否有同样的问题
  • 感谢您的建议。我将 libvlc 和初始化移动到 mainviewmodel,并从引用它的不同虚拟机创建媒体播放器。不幸的是,这并没有帮助。差不多吧……
  • 最小的复制代码在哪里,我们可以在本地尝试?
  • 向问题添加了最小代码。没有用于缩短测试解决方案的处置代码。
  • 删除sout-mux-caching,这与你的用例完全无关

标签: c# wpf libvlcsharp


【解决方案1】:

对您的代码的一般反馈。

  • 在您使用媒体播放器时对其进行跟踪,并在完成后将其丢弃。
  • 不要在使用时丢弃 LibVLC。
  • 将每个媒体播放器与视图集成,现在您只是在没有绘图目标的媒体播放器上调用播放。 LibVLC 将创建随机窗口然后绘制。可能不是你想要的。

现在,在 VLC 桌面应用程序中播放您的流并打开日志将提供一些见解:

main error: ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to 2926 ms)
main debug: Received first picture
main error: Timestamp conversion failed for 9480001: no reference clock
main error: Could not convert timestamp 0 for FFmpeg
main debug: Buffering 0%
main debug: Buffering 8%
main debug: Buffering 17%
main debug: Buffering 25%
main debug: Buffering 34%
main debug: Buffering 42%
main debug: Buffering 51%
main debug: Buffering 59%
main debug: Buffering 68%
main debug: Buffering 76%
main debug: Buffering 85%
main debug: Buffering 93%
main debug: Stream buffering done (3000 ms in 7056 ms)
main debug: Decoder wait done in 0 ms
main debug: inserting 307 zeroes
mmdevice debug: state changed: 1
main warning: buffer too late (-217851 us): dropped
main warning: buffer too late (-194631 us): dropped
main error: ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to 3774 ms)
main debug: ES_OUT_RESET_PCR called
main warning: buffer too late (-171411 us): dropped
main debug: Received first picture
main error: Timestamp conversion failed for 15800001: no reference clock
main error: Could not convert timestamp 0 for FFmpeg
mmdevice debug: state changed: 0

这看起来不太好。也许 YouTube 对视频进行了错误编码?或者更可能是 LibVLC 的问题?我不确定。

【讨论】:

  • 我发现了一个最近的页面forum.videolan.org/viewtopic.php?p=516017,它指向了forum.videolan.org/viewtopic.php?p=483226#p483226。创建 youtube.luac 并将其放入 VLC 文件夹确实可以修复 VLC 桌面。现在,我们如何为 libvlc 做同样的事情?
  • 好的,lua 去那里:\packages\VideoLAN.LibVLC.Windows.3.0.16\build\x64\lua\playlist 并在 LibVLC 初始化中添加了以下选项:“--network-caching =8000”,“--directx-use-sysmem”。这会在系统内存而不是视频内存中创建视频缓冲区,并增加缓存,这最初似乎已经解决了最初的问题。在更长的测试中,这完全一样...您显示的错误仍然存​​在..
【解决方案2】:

问题似乎与 youtube.luac 文件相关联。
该文件于 2021 年 10 月 19 日左右更新,似乎运行良好。谢谢马丁的帮助。

一个基本项目可用here

安装的 3 个包是:



在开始之前,删除项目文件夹中的 .vs,以及解决方案中的 bin 和 obj 文件夹。

转到here,复制文本块,然后将其粘贴到记事本中。单击文件 ---> 另存为并将其命名为 youtube.luac 在该字段下方,通过下拉菜单将“文本文档”(txt) 更改为所有文件,然后单击保存。

将包文件夹中的文件替换为 32 和 64。
例如\packages\VideoLAN.LibVLC.Windows.3.0.16\build\x64\lua\playlist

重建你的项目,瞧。
这为我解决了这个问题,并且由于可用的文档很少,希望这会对某人有所帮助.. :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-20
    • 2017-04-21
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 2022-01-04
    • 2013-06-05
    • 2011-11-29
    相关资源
    最近更新 更多