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
事件至少会触发 Opening
和 Playing
状态。
- 正如其他人所指出的,您不能在媒体结束后简单地调用
Play()
。您需要在 EndReached
触发后 Stop()
,并且 - 与许多回调一样 - 您需要确保以非死锁方式处理它。它可以而且将会悄无声息地陷入僵局。即使使用 Dispatcher
也可能在同一个线程上选择 运行 ,所以你必须保证一个单独的线程。到目前为止,我已经很幸运了。 ThreadPool.QueueUserWorkItem(_ => yourMediaPlayer.Stop());
然后您可以挂钩 Stopped
以触发进一步的行为,例如 Play()
.
- 我仍然不确定
ErrorEncountered
周围的确切行为并再次恢复到 Play()
;触发此行为并不容易。
最终,这个状态机允许我在它之上构建一个来处理诸如“到达结尾时使文件再次播放”之类的行为。
感谢@mfkl 和许多其他人的辛勤工作 - 经过一些挖掘,这是一个很棒的库!
有谁知道 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
事件至少会触发Opening
和Playing
状态。- 正如其他人所指出的,您不能在媒体结束后简单地调用
Play()
。您需要在EndReached
触发后Stop()
,并且 - 与许多回调一样 - 您需要确保以非死锁方式处理它。它可以而且将会悄无声息地陷入僵局。即使使用Dispatcher
也可能在同一个线程上选择 运行 ,所以你必须保证一个单独的线程。到目前为止,我已经很幸运了。ThreadPool.QueueUserWorkItem(_ => yourMediaPlayer.Stop());
然后您可以挂钩Stopped
以触发进一步的行为,例如Play()
. - 我仍然不确定
ErrorEncountered
周围的确切行为并再次恢复到Play()
;触发此行为并不容易。
最终,这个状态机允许我在它之上构建一个来处理诸如“到达结尾时使文件再次播放”之类的行为。
感谢@mfkl 和许多其他人的辛勤工作 - 经过一些挖掘,这是一个很棒的库!