为什么处理替换不适用于 VLC 播放列表?

Sri*_*bat 5 vlc-media-player bash

符合我的期望

  • cat <(shuf my_ordered_playlist.m3u)
  • echo <(shuf my_ordered_playlist.m3u)
  • vlc my_ordered_playlist.m3u

不符合我的期望

  • vlc <(shuf my_ordered_playlist.m3u)

我想做的事

  • 在每次调用 vlc 和
  • 按下后退按钮时能够后退(这--random提供了较差的支持)。

其他注意事项

  • 我可以使用此处的文档或 来实现我想要做的事情<<<吗?

Kam*_*ski 7

为什么处理替换不适用于 VLC 播放列表?

因为vlc 在这件事上设计得很差。更糟糕的是,它两次设计得很差:
可能有其原因* 以造成以下两个缺点的方式工作:

  • inotifywait -m my_ordered_playlist.m3u显示在vlc my_ordered_playlist.m3u文件被打开并读取多次后。我没有调查是否涉及寻求。当您使用<(shuf my_ordered_playlist.m3u) vlc从管道中获取数据时shuf,它可以准确地读取一次。显然这还不够。在一个完美的世界中vlc,只需读取一次数据就足够了。

  • vlc拒绝使用没有扩展名的播放列表。在 Zsh 中,=()语法类似于<(); 不同之处在于 shell 创建一个临时的常规文件而不是管道。这样的文件可以被多次读取并且是可查找的。这似乎是您问题的一个很好的解决方案(如果您对 Zsh 没问题),但通常文件名没有扩展名,因此vlc =(shuf my_ordered_playlist.m3u)仍然无法正常工作。

    但是有一个办法

    # in zsh
    TMPSUFFIX=.m3u; vlc =(shuf my_ordered_playlist.m3u)
    
    Run Code Online (Sandbox Code Playgroud)

    如果您希望更改TMPSUFFIX不影响主 shell,请在子 shell 中运行命令。


*声明“vlc设计不佳”收到了有用的评论:

我怀疑至少通过文件查找之一是确定文件是 ANSI、UTF-8 还是 UTF-16(带或不带字节顺序标记),然后使用内部应用的适当格式重新扫描文件。当然,这并不能阻止 VLC 期待扩展的事实,当您考虑 VLC 可能会看到的格式数量时,这并不是那么愚蠢……您真的不能指望它首先扫描文件,并且将它与每个内部解码器摩擦以查看哪个有效,其操作将在第一次搜索后清空管道并使数据再次无用......


Mok*_*bai 5

另一种选择是分两个阶段进行,并将已经洗牌的播放列表在文件中而不是在命令行中传递给 VLC。

shuf my_ordered_playlist.m3u > /tmp/random_playlist.m3u && vlc /tmp/random_playlist.m3u
Run Code Online (Sandbox Code Playgroud)

你甚至可以将它扩展到

shuf my_ordered_playlist.m3u > /tmp/random_playlist.m3u && vlc /tmp/random_playlist.m3u && rm /tmp/random_playlist.m3u 
Run Code Online (Sandbox Code Playgroud)

在 VLC 退出后进行清理。

您甚至可以使用bash 别名

alias shuf_vlc="shuf my_ordered_playlist.m3u > /tmp/random_playlist.m3u && vlc /tmp/random_playlist.m3u && rm /tmp/random_playlist.m3u"
Run Code Online (Sandbox Code Playgroud)

然后运行shuf_vlc以随机播放您的播放列表。


您的命令不起作用的原因是它仍然是一个管道并且受到管道的限制。

过程替换的限制

进程替换有一些限制:

  • 无文件查找:创建的“文件”是不可查找的,即读写文件的进程不能进行随机访问;它必须从头到尾读或写一次。在打开文件之前明确检查文件类型的程序可能拒绝使用进程替换,因为进程替换产生的“文件”不是常规文件。

  • 无退出代码:“无法从创建进程替换的 shell 获取进程替换命令的退出代码。”

根据您所看到的行为,VLC 可能正在寻找有效的播放列表(以检查 UTF-8/16 等或文件构造是否正确),但实际上并没有在第一个读取播放列表经过。它尝试返回以实际加载文件,但由于“无文件搜索”无法读取播放列表。第一遍有效地清空了给定文件描述符的管道,然后就没有任何东西可以使用了。

或者,VLC 会检查文件是否“真实”并且能够被seek编辑,并且发现它不能简单地拒绝打开它,因为它将无法向前和向后解析文件。

你的前两个命令很简单,只期望一个可读的流,VLC 想要一些它可以坚持的真实的东西。