我的目标是计算使用该say
命令时将文本输出到音频需要多长时间。
例如,say
将实时讲话:
$ say -v Alex "Hello there"
然后我可以结合say
来time
回答文本中的问题,尽管我们要等到实际音频输出结束:
$ time say -v Alex "Hello there. How long will this take?"
real 0m2.993s
user 0m0.006s
sys 0m0.009s
say
有没有办法计算输出任何命令而不实际执行它需要多长时间?如何?- 如果没有的话,我该如何使用
grep
来拉出真实的线呢?
我正在尝试这样的事情:
time say -v Alex "Hello there. How long will this take?" | grep "^real .*$"
但当然没有结果。
输出是否未传递到grep
,grep
不适用于此多行输出,或者我使用了错误的模式匹配?
如果grep
行不通,那什么行呢?
更新#1
实际上,我认为我真正要寻找的是生成的音频文件的持续时间say
。
答案1
计时运行say
- 有没有办法计算输出任何 say 命令而不实际执行它需要多长时间?如何?
我认为无法使用该say
命令提供的任何开关来完成此操作。
- 如果没有,我怎样才能使用grep来拉出真实的行?
要解析time
输出,您可以执行以下操作:
$ ( time say -v Alex "Hello there. How long will this take?" ) |& grep real
real 0m2.987s
或者:
$ ( time say -v Alex "Hello there. How long will this take?" ) 2>&1 | grep real
real 0m2.987s
在上面,我们将time ...
命令包装在子 shell 中,然后将 STDOUT 和 STDERROR ( |&
) 重定向到grep
.在不适用于您的特定 Bash 版本的情况下,该2>&1
表单会执行相同的操作。|&
/dev/空
顺便说一句,如果您使用-o <file>
参数 to ,say
您可以加快文本到音频的翻译速度。由于我们实际上并不需要音频文件,/dev/null
因此我们将指向:
$ ( time say -v Alex "Hello there. How long will this take?" -o /dev/null ) |& grep real
real 0m0.310s
或者:
$ ( time say -v Alex "Hello there. How long will this take?" -o /dev/null ) 2>&1 | grep real
real 0m0.283s
请注意,当不需要使用扬声器来执行此操作时,速度要快得多,这就是使用音频 I/O 时的延迟。通过直接指向文件,效率会更高。
计算音频的持续时间
要确定生成的音频文件的持续时间,say
您可以执行以下操作:
$ say -v Alex "Hello there. How long will this take?" -o a.aiff && \
ffmpeg -i a.aiff 2>&1 | grep Duration && rm a.aiff
Duration: 00:00:02.85, start: 0.000000, bitrate: 364 kb/s
在这里我们可以看到生成的音频的持续时间是 2.85 秒。
进一步改进?
我研究过将输出直接通过管道输送say
到ffmpeg
但say
显然无法做到这一点。其他人根据标题为“Ask Q&A”的问答得出了相同的结论:如何将“say”的输出通过管道传输到另一个命令。