我在终端上运行这个命令:
for i in $(ls -1 /home/pi/Desktop/Music/Acapella/*.mp3|sort -R); do sox -t mp3 $i -t wav - ; done | sudo ./pi_fm_rds -freq 102.1 -audio - -ps ZSFM -rt "ZSFM"
基本上,它使用 forloop 遍历目录中的所有文件并将它们即时转换为 wav 文件,然后通过管道将其输入 pifm 命令。不过,唯一的问题是,在第一个文件之后它说:
sox WARN sox: `-' output clipped 773 samples; decrease volume?
Could not rewind in audio file, terminating
Terminating: cleanly deactivated the DMA engine and killed the carrier
我不确定这是袜子问题还是终端问题。这是什么意思(以及如何解决它)?
我确实在 pifm 命令后面加上了“done”,但随后它为每个文件运行一次 pifm 命令,但我希望 pifm 命令不断运行,并且 forloop 只会在其播放的文件上运行。
答案1
您正在向 sox 提供一份文件。它进行转换和流式传输,然后在获取下一个文件之前结束。
您可以通过多种方式做到这一点。并且,不,不要ls
那样使用
我用于play
测试目的:
#! /bin/sh -
path="/home/pi/Desktop/Music/Acapella/"
find "$path" -name '*.mp3' -print0 |
sort -z -R |
xargs -0 cat |
sox -t mp3 - -t wav - |
play -
这里有人说
find
$path
以where-name
结尾的文件并打印以零字节.mp3
分隔的文件名。\0
sort
-R
来自管道 / 的随机输入find
以-z
零分隔。 (又名随机播放)xargs
连接由-0
零分隔的文件名给出的文件。sox
-t mp3 -
:输入从 stdin 读取的 mp3(标准输入)-t wav -
:输入 wav 写入标准输出(标准输出)
play
来自标准输入的数据-
如果您可以保证文件名中没有换行符,您也可以使用临时播放列表。这里是M3U,如果你想了解更多,请参阅维基百科。
#! /bin/sh -
# ARG 1 is path
path="$1"
# Create temporary file to use as playlist
playlist="$(mktemp /tmp/sox.XXXXXXXX.m3u)"
# Delete playlist on exit
trap 'rm "$playlist"' EXIT
#Create playlist
find "$path" -name '*.mp3' -print |
sort -R >"$playlist"
sox "$playlist" -t wav - | play -