在 libvlc 中重新计算 EOF 的持续时间
Recalculating duration on EOF in libvlc
我有一个非常具体的用例,在产品中我必须在我的 java 应用程序中播放连续附加的 wav 文件(我无法修改这种情况)。
我的问题是,当我打开这个 wav 文件进行播放时,libvlc 会处理持续时间计算,一段时间后它会检测到 EOF,尽管文件实际长度比我们打开它要大得多(我猜是因为缓冲回放)。这会导致播放器停止(引发 finished
事件)。从今天开始,我重新开始播放并将时间设置为这个已完成事件的结束位置。这会在最终产品中造成很少的停顿和不可接受的。
我尝试在 libvlc(vlc 3.0.6 版本)中实现一个逻辑来处理这个问题,但我真的找不到正确的方法。
我的方法是重新计算 wav 文件的持续时间,以防它检测到 EOF。如果新的持续时间等于旧的持续时间而不是真正的 EOF 否则它可以继续播放。
我已经修改了input.c
中的VLC_DEMUXER_EOF
处理,按照文件结束跟踪,修改demux-run.c
和wav.c
过程,并尝试事件处理 (finished
/stopped
),但无法更接近有效的解决方案。
我真的很感激这方面的帮助,因为在过去的几天里我的头发掉得很快。 (如果您有想法,我也愿意接受其他选择。)
我不确定您使用的是哪种绑定,但我假设是 vlcj,因为您提到了 Java。
无论如何,一种解决方案是使用 libvlc_media_new_callbacks
。文档:https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__media.html#ga591c3cbe56444f1949165b2b9b75d8e2
实现这些自定义回调将允许您明确告诉 libvlc 等待。您可以在 libvlc_media_read_cb
回调中执行此操作,其中文档指出:
If no data is immediately available, then the callback should sleep.
您应该找到这个 API 是如何通过您使用的任何绑定公开的,然后在 Java 代码中使用它。
我的解决方案是修改 libvlc 源中的 wav 文件处理,并针对这个特定问题构建一个新的 vlc 播放器。
通过更新 wav.c Control
方法中的 i_data_size
,使用 stearm_Size(p_demux->s)
播放器能够管理附加,并像播放文件一样播放文件是流(这可能会导致 lenght_change 事件出现问题)。
其次,我必须管理偶尔的冲突,当附加程序分配文件时,无法执行流块操作。我通过对 stream.c vlc_stream_ReadRaw
方法实施重试机制来解决这个问题。这将重试 s->pf_read(s, buf, len)
调用 x 次,如果它 returns 0(这意味着通常播放中的 EOF,但在这里它可能表示操作失败)。
这无论如何都不是一个合适的解决方案,但我很着急,不得不让它发挥作用。我将接受 .
描述的解决方案
我有一个非常具体的用例,在产品中我必须在我的 java 应用程序中播放连续附加的 wav 文件(我无法修改这种情况)。
我的问题是,当我打开这个 wav 文件进行播放时,libvlc 会处理持续时间计算,一段时间后它会检测到 EOF,尽管文件实际长度比我们打开它要大得多(我猜是因为缓冲回放)。这会导致播放器停止(引发 finished
事件)。从今天开始,我重新开始播放并将时间设置为这个已完成事件的结束位置。这会在最终产品中造成很少的停顿和不可接受的。
我尝试在 libvlc(vlc 3.0.6 版本)中实现一个逻辑来处理这个问题,但我真的找不到正确的方法。
我的方法是重新计算 wav 文件的持续时间,以防它检测到 EOF。如果新的持续时间等于旧的持续时间而不是真正的 EOF 否则它可以继续播放。
我已经修改了input.c
中的VLC_DEMUXER_EOF
处理,按照文件结束跟踪,修改demux-run.c
和wav.c
过程,并尝试事件处理 (finished
/stopped
),但无法更接近有效的解决方案。
我真的很感激这方面的帮助,因为在过去的几天里我的头发掉得很快。 (如果您有想法,我也愿意接受其他选择。)
我不确定您使用的是哪种绑定,但我假设是 vlcj,因为您提到了 Java。
无论如何,一种解决方案是使用 libvlc_media_new_callbacks
。文档:https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__media.html#ga591c3cbe56444f1949165b2b9b75d8e2
实现这些自定义回调将允许您明确告诉 libvlc 等待。您可以在 libvlc_media_read_cb
回调中执行此操作,其中文档指出:
If no data is immediately available, then the callback should sleep.
您应该找到这个 API 是如何通过您使用的任何绑定公开的,然后在 Java 代码中使用它。
我的解决方案是修改 libvlc 源中的 wav 文件处理,并针对这个特定问题构建一个新的 vlc 播放器。
通过更新 wav.c Control
方法中的 i_data_size
,使用 stearm_Size(p_demux->s)
播放器能够管理附加,并像播放文件一样播放文件是流(这可能会导致 lenght_change 事件出现问题)。
其次,我必须管理偶尔的冲突,当附加程序分配文件时,无法执行流块操作。我通过对 stream.c vlc_stream_ReadRaw
方法实施重试机制来解决这个问题。这将重试 s->pf_read(s, buf, len)
调用 x 次,如果它 returns 0(这意味着通常播放中的 EOF,但在这里它可能表示操作失败)。
这无论如何都不是一个合适的解决方案,但我很着急,不得不让它发挥作用。我将接受