ffmpeg搞乱了变量。
ffmpeg搞乱了变量。
我正在尝试根据音频文件的章节来拆分它们。我使用yt-dlp
下载了这个音频,并包含了章节信息。我尝试了下面这个非常简单的脚本来完成任务:
#!/bin/sh ffmpeg -loglevel 0 -i "$1" -f ffmetadata meta # 从元数据中提取并输出到meta文件 cat meta | grep "END" | awk -F"=" '{print $2}' | awk -F"007000000" '{print $1}' > ends # cat meta | grep "title=" | awk -F"=" '{print $2}' | cut -c4- > titles from="0" count=1 while IFS= read -r to; do title=$(head -$count titles | tail -1) ffmpeg -loglevel 0 -i "$1" -ss $from -to $to -c copy "$title".webm echo $from $to count=$(( $count+1 )) from=$to done < ends
你可以看到,我echo
出$from
和$to
,因为我注意到它们是错误的。为什么会这样?当我在while循环中注释掉ffmpeg
命令时,变量$from
和$to
的结果是正确的,但是当取消注释时,它们就变成了一些奇怪的数字。
注释掉的输出结果:
0 465 465 770 770 890 890 1208 1208 1554 1554 1793 1793 2249 2249 2681 2681 2952 2952 3493 3493 3797 3797 3998 3998 4246 4246 4585 4585 5235 5235 5375 5375 5796 5796 6368 6368 6696 6696 6961
取消注释的输出结果:
0 465 465 70 70 890 890 08 08 1554 1554 3 3 2249 2249 2952 2952 3493 3493 3998 3998 4246 4246 5235 5235 796 796 6368 6368
我尝试了很多其他的方法,以为它们可能是问题所在,但没有改变任何东西。我记得其中一个尝试是将$from
和$to
的格式设置为%H:%M:%S
,结果仍然是一样的。
提前谢谢你的帮助。
ffmpeg混乱了变量
在上述问题中,出现了ffmpeg混乱了变量的问题。具体的原因是:
1. 避免使用临时文件。
2. 避免在循环内部重复读取第二个输入文件。
3. 将复杂的Awk脚本重构为单个脚本。
4. 为了安全起见,添加从/dev/null重定向,以防止ffmpeg吃掉输入数据。
为了解决这个问题,可以尝试以下方法:
#!/bin/sh from=0 ffmpeg -loglevel 0 -i "$1" -f ffmetadata - | awk -F '=' '/END/ { s=$2; sub(/007000000.*/, "", s); end[++i] = s } /title=/ { t=$2; sub(/^([^-]-){3}/, "", t); title[++j] = t } END { for(n=1; n<=i; n++) print end[n]; print title[n] }' | while IFS="" read -r end; do IFS="" read -r title ffmpeg -loglevel 0 -i "$1" -ss "$from" -to "$end" -c copy "$title".webm
Awk脚本将所有数据读入内存,然后打印一个"end"标记,后跟下一行的相应标题;我无法确定您的`ffmpeg -f ffmetadata`命令的输出是什么样的,所以我只是盲目地重构了您的脚本似乎在做什么。如果输出有一定的结构,您可能可以一次读取一条记录。
噢,我真的应该学习如何使用awk。使用`ffmpeg -f metadata`进行管道传输的问题在于它不会输出到命令行,并要求指定一个文件名,也许对ffmpeg有更多了解的人知道如何让它输出到命令行。所以我想在这种情况下必须使用临时文件,但是只需要一个而不是3个,这要归功于你的建议。
尝试将文件名设置为`-`或`/dev/stdout`。
唉,`manpages.org/ffmpeg`似乎在说元数据是某种.ini格式。可以一次解析一个,而不是将其全部加载到内存中。它还似乎验证了`-`应该可以用于写入标准输出。我已更新答案以使用该选项。