使用Unix管道改进Chromecast播放

2020-06-29 12:39:59

从YouTube投射到Chromecast时,音频播放有时会跳过并断断续续。此问题与视频质量、FPS或互联网连接无关。尝试观看某些视频肯定会导致Chromecast出现播放问题。

根据这条帖子,播放问题只出现在Chromecast的最新也是最后一次固件更新中。在过去,成功播放视频是可能的,而播放下载的YouTube视频则完全消除了这个问题。这个问题只存在于使用YouTube应用程序播放某些视频时。

考虑到这个问题只出现在YouTube应用程序上,你可以下载一段视频并通过Castnow或Catt播放,完全跳过YouTube应用程序。

#!/usr/bin/env bash export url=";https://youtu.be/Kas0tIxDvrg";函数CAST(){url=";$1";filename=$(youtube-dl--get-filename";$url";)youtube-dl";$url";#等待下载文件Castnow";$filename";

但不得不跳过使用YouTube应用程序进行选角已经是一个笨拙的解决方案,在播放之前下载每段视频的用户体验更差。即时播放和短暂流是2020年令人愉快的视频流体验的要素,而本解决方案既不实现这两种功能,也不实现这两种功能。

因为youtube-dl允许我们输出到stdout,所以如果我们可以将它的stdout连接到一个转换应用程序上,我们就可以模拟我们期望的即时播放和短暂视频,因为我们不必等待下载整个文件。

不幸的是,Castnow和Catt不会从stdin进行强制转换。您需要向它传递要从中进行转换的文件位置。

通过进程替换,Bash为我们提供了一种创建临时匿名管道的便捷方法。此方法既高效又并发,使此原语成为构建手头问题解决方案的合适选择。读取管道的进程会阻塞,直到另一个进程打开管道进行写入。写入管道的进程将挂起,直到另一个进程读取管道的缓冲区。匿名管道将自动删除,当手动删除时,其从属进程将终止。

在使用进程替换时,进程的stdout连接到匿名管道。可以从文件描述符中访问该管道,并将管道的位置提供给调用进程。

$ECHO<;(ECHO&34;内容发送到PIPE&34;)/dev/fd/63$CAT<;(ECHO&34;内容发送到PIPE";)发送到PIPE的内容。

在上面的示例中,<;(命令)语法是我们在Bash中调用流程替换的方式。命令的输出被写入匿名管道,并为调用进程提供访问该管道的文件描述符的位置。

上面的命令将使用VLC在本地播放YouTube视频,并说明进程替换可以用于我们的用例。

但是,当我们尝试使用Castnow时,我们不能从管道进行强制转换:

我们知道我们可以在本地使用VLC,并且VLC还允许您使用Chromecast的IP地址强制转换为Chromecast。

函数cast_vlc(){path=";$1";#获取chromecast.lan主机IP=$(dig+short chromecast.lan|ail-n 1)vlc-i ncurses\--sout';#chromecast';\--sout-chromecast-ip=";$ip";\--demux-filter=demux_Chromecast\";(youtube-dl-q-o-";$url";)。

另外,我们将VLC的stdin挂接到/dev/tty,这样即使从脚本调用函数,我们也可以使用ncurses接口。

它只显示文件描述符,几乎不显示视频本身。我不是那个的粉丝。

我们可以使用命名管道,而不是使用匿名管道。命名管道类似于匿名管道,不同之处在于它们既不是匿名的(它们有名字),也不是短暂的。命名管道仍然给我们带来匿名管道给我们带来的效率和并发优势,但是Bash在涉及到命名管道时缺乏进程替换所具有的语法优势。

这就是我们创建命名管道、写入它们、读取它们和删除它们的方式。

$mkfio OUR PIPE$ECHO&34;>;OUR PIPE&;$CAT OUR PIPE管道中的内容$rm OURPIPE中的内容。

我们可以为命名管道提供与YouTube视频相同的名称,这样,VLC界面将显示我们正在观看的内容的名称。

函数cast_ytdl(){url=";$1";#创建临时命名管道#为什么?因为如果我们只使用进程替代filename=$(youtube-dl--get-filename";$url";)path=";/tmp/$filename";mkfio";$path";#在后台下载,所以VLC会显示文件描述符路径,所以推送到命名管道youtube-dl-q-o-";$url";>;";$path&。从命名管道CAST_VLC";$PATH";#CLEANUP进程和命名管道KILL-9";$PID";&;&>/dev/null}cast_ytdl";$url";

我们需要使用mkfio手动创建命名管道,在后台运行进程时将youtube-dl的stdout重定向到命名管道,然后在通过VLC从其强制转换后清理该进程,否则它可能会在后台徘徊。这些任务中的每一项都将使用进程替换自动为我们处理。

管道、匿名管道和命名管道也因为它们的行为方式而被称为另一个名称:先进先出(FIFO)或先进先出(First In First Out)。写入管道的内容按照先进先出的顺序从管道读取。此行为很好地映射到视频流。

虽然您可以像处理文件一样与匿名和命名管道交互,但接口与标准文件不是1:1的。您不能在管道中向前或向后查找(),只能读取下一个向前的值。对于我们的用例,这意味着我们不能在流视频中向前或向后跳转。我们只能播放、暂停或停止视频。

这对我来说不是问题,但是如果对你有问题的话,这是可以减轻的。我能想到的第一个解决方案是通过youtube-dl写入临时文件并从中读取。或者,临时假脱机文件可以充当管道的缓冲区,这样您就可以通过缓冲区查找(),但是缓冲区本身与普通文件不同,它是短暂的。