VLC libvlc_state_t 状态机?

问题描述

有谁知道 VLC 项目是否为 libvlc_state_t 状态定义了状态机?状态机状态通过 libvlc 公开,然后再次通过绑定到其他语言(例如,LibVLCSharp)公开。枚举记录为 here,但我找不到转换或其他详细信息的说明。

更新

我希望在某个时候将其纳入 VLC 文档。虽然状态机可能看起来很明显,但我遇到了一些奇怪的事情,例如 Buffering 事件被调用,但 Media 似乎没有通过 Buffering 状态 - 它仍处于 Playing 状态。

这些小东西加起来可能有助于改善开发人员的体验来添加它们。我正在寻找的解决方案是一个典型的状态机,它至少包括状态、转换以及关于哪些事件在哪些转换上实际触发的注释(以及它们是否发生在状态实际更改之前或之后)。任何与线程相关的问题(例如同步与异步转换)以及在给定状态下允许的操作都是额外的。

解决方法

media.State

应该给你你想要的。

libvlc_state_t C 枚举在 libvlcsharp 中被简单地定义为 C# 枚举,如下所示:

/// <summary>Note the order of libvlc_state_t enum must match exactly the order of</summary>
    /// <remarks>
    /// <para>mediacontrol_PlayerStatus,</para>
    /// <para>input_state_e enums,</para>
    /// <para>and VideoLAN.LibVLCSharp.State (at bindings/cil/src/media.cs).</para>
    /// <para>Expected states by web plugins are:</para>
    /// <para>IDLE/CLOSE=0,OPENING=1,PLAYING=3,PAUSED=4,</para>
    /// <para>STOPPING=5,ENDED=6,ERROR=7</para>
    /// </remarks>
    public enum VLCState
    {
        /// <summary>
        /// Nothing special happening
        /// </summary>
        NothingSpecial = 0,/// <summary>
        /// Opening media
        /// </summary>
        Opening = 1,/// <summary>
        /// Buffering media
        /// </summary>
        Buffering = 2,/// <summary>
        /// Playing media
        /// </summary>
        Playing = 3,/// <summary>
        /// Paused media
        /// </summary>
        Paused = 4,/// <summary>
        /// Stopped media
        /// </summary>
        Stopped = 5,/// <summary>
        /// Ended media
        /// </summary>
        Ended = 6,/// <summary>
        /// Error media
        /// </summary>
        Error = 7
    }

您还可以订阅媒体上的 StateChanged 事件,以获取有关 State 状态更改的通知。

,

我做了一些工作来捕捉观察到的行为。这是不完整和不完美的,但也许它可以帮助其他人,因为他们建立在 libvlc/LibVLCSharp 之上(我使用的是 v3.5.1,VideoLAN.LibVLC.Windows v3.0.14)。指向右侧的虚线箭头用于显示某些事件何时触发。请注意,其中一些行为可能特定于媒体类型或通过 MediaInput 界面进行阅读的事实,因此您的里程可能会有所不同。

State Machine

一些注意事项:

  • 如果您尝试过,事情似乎并不总是正常工作,例如在媒体为 Opening 时寻找。例如,我看到 .Time.Position 永久不同步。我强烈建议等到 Play() 操作之后再做很多事情。
  • 未发现 Buffering 状态正在使用中,但 Buffering 事件至少会触发 OpeningPlaying 状态。
  • 正如其他人所指出的,一旦媒体结束,您不能简单地调用 Play()。您需要在 Stop() 触发后 EndReached,并且 - 与许多回调一样 - 您需要确保以非死锁方式处理此问题。它可以而且将会悄悄地陷入僵局。即使使用 Dispatcher 也可能选择在同一个线程上运行,所以你必须保证一个单独的线程。到目前为止,我很幸运,例如ThreadPool.QueueUserWorkItem(_ => yourMediaPlayer.Stop()); 然后您可以钩住 Stopped 以触发进一步的行为,例如 Play()
  • 我仍然不确定 ErrorEncountered 周围的确切行为并再次恢复到 Play();触发这种行为并不容易。

最终,这个状态机允许我在它之上构建一个状态机来处理诸如“到达结尾时再次播放文件”之类的行为。

感谢@mfkl 和许多其他人的辛勤工作 - 通过一些挖掘,这是一个很棒的库!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...