我正在使用使用谷歌语音到文本API的脚本。 api需要flac编码的文件,因此脚本的录制部分如下所示:
arecord -q -t wav -d 0 -f S16_LE -r 16000 | flac - -f --best --sample-rate 16000 -s -o "$TEMP_FILE"
此命令将记录,直到用户退出ctrl-c并且wav记录的格式应通过管道传输到flac程序以进行flac格式的输出,然后脚本应该继续。
我遇到的问题是按ctrl-c完全结束脚本并切断一些音频(仍然输出flac文件)。如果我在没有管道的情况下运行脚本:
arecord -q -t wav -d 0 -f S16_LE -r 16000 some.wav
然后按ctrl-c将仅结束录制并继续使用脚本。
如何解决这个问题,以便ctrl-c只停止arecord命令并允许脚本的其余部分(包括管道flac编码)完成?
答案 0 :(得分:3)
意识到你想要做的事情无法完成。
免责声明:以下是基于我自己在Ubuntu 12.04上的实验,只有一小部分研究。如果我错了,请告诉我。
症结:
SIGINT
。trap
命令捕获信号 - 但是这样的shell陷阱在管道进程收到信号之后 之后才会执行,并且通常已被信号终止。在您的具体情况下,arecord
设计到陷阱 SIGINT
并以有序的方式退出。
相比之下,flac
似乎没有 - 它被强制终止
但是,即使flac
也 陷阱SIGINT
要完全关闭,根据相关流程收到信号的不确定顺序,您也无法安全使用带有 Ctrl-C 的管道,同时期望整体处理以有序的方式完成。
(暂时不说:arecord
报告以 Ctrl-C 结尾时退出代码1
,这让我想知道如何将其与真正的失败区分开来,例如磁盘空间不足。)
因此:
arecord
作为单独命令 调用,并将输出捕获到(临时)文件中。flac
(并在完成后删除临时文件)。答案 1 :(得分:0)
我会这样试试:
# Create a fifo
FIFO=/tmp/my_fifo
mkfifo $FIFO
# Start arecord in background and redirect its output into the fifo
arecord ... > $FIFO &
# Get the arecord PID
PID=$!
# Trap the SIGINT to send SIGINT to arecord
trap "kill -INT $PID" INT
# Start flac and redirect its input with the fifo.
flac - ... < $FIFO
# The script should be blocked here, and a CTRL+C will run
# the kill -INT to the arecord process only.
# But I don't know how flac will react after ...
# If flac exit correctly, just restore the SIGINT
trap - INT