我有一堆视频剪辑,我想为每个剪辑选择一组音乐。
我编写了一个脚本,该脚本会遍历每个剪辑,并根据其长度随机选择mp3。
例如。如果片段持续10:30,则它会累加几个mp3,长度总和等于片段的长度。
#!/bin/bash
for v in clips/*; do
videolength=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $v | awk '{print int($0)}');
mp3s=0
names=""
for m in music/*; do
audiolength=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $m | awk '{print int($0)}');
while [[ $videolength -ge $mp3s ]]; do
(( mp3s+=audiolength ))
names+=$v" "
mv "$m" "used/$m"
break
done
continue
done
echo "music for this clip: "${names[*]}
# ffmpeg things here
done
此脚本可以正常工作,只是它会从我的100多个mp3列表中迭代相同的第一个mp3。
如何标记为已使用并跳过已使用的mp3 ,然后在下一个剪辑中仅选择新鲜的mp3?
当前该脚本将mp3移至另一个文件夹,但这似乎并不明智。
有什么聪明的方法可以仅在嵌套循环内遍历新文件吗?
答案 0 :(得分:1)
尝试一下:
#!/bin/bash
used=""
for v in clips/*; do
videolength=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$v" | awk '{print int($0)}');
mp3s=0
names=""
for m in music/*; do
# check if the file "$m" was already used
# "$used" is a newline separated file with names in it
# we filter out "$m" from it. If it exists, that means that it was used.
if <<<"$used" grep -q -x "$m"; then
echo "File $m was already used"
continue;
fi
audiolength=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$m" | awk '{print int($0)}');
if (( videolength >= mp3s )); then # I guess you meant if not while, cause it has break on the end, so it acts as if
(( mp3s += audiolength ))
names+=$v" " # didn't you mean "$m" here?
# save "$m" to the list of used files.
used+="$m"$'\n'
fi
done
echo "music for this clip: "${names[*]}
# ffmpeg things here
done
您可以将使用的名称保存在以换行符分隔的变量内。然后在列表上使用grep来检查名称是否已被使用。