VLC libvlc_state_t 状态机?

VLC libvlc_state_t State Machine?

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

更新

我希望看到它在某个时候被整合到 VLC 文档中。虽然状态机看起来很明显,但我遇到了一些小问题,比如调用了 Buffering 事件,但媒体似乎没有通过 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 界面进行阅读的事实,因此您的情况可能会有所不同。

一些注意事项:

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

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

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