我一直想要一个覆盖视频的计时计时器,但我在网上找到的所有内容都是使用Adobe After Effects,这不是我真的可以选择的选项。 Linux并且我不愿意付钱。
因此,如果我可以获得一系列图像或视频,那么可以将其导入到Openshot中以非常好地覆盖视频,但是获取所述一系列图像或视频却很困难。
我已经开始编写脚本来制作一系列图像,但不知道如何将变量放入命令中。这是目前形式的脚本:
#!/bin/bash
for i in {0..18000000}
do
echo "$i"
convert -size 780x100 xc:#d3fff5ff -font Courier-New -pointsize 100 -fill black -draw "text 20,80 '000:00:00.00'" 0.png
done
我想要的是0.png基本上是$ i.png,所以它增加到18,000,000。时间(显示为000:00:00.00)在知道如何将变量插入命令后,我可能会自己解决。时间格式为小时,分钟,秒和帧。
以下是一个例子,如果我解释得很糟糕(对不起间距 - 由于某些原因,只有两条新线才能在这里工作):
0.png = 000:00:00.00
1.png = 000:00:00.01
49.png = 000:00:00.49
50.png = 000:00:01.00
51.png = 000:00:01.01
18000000.png = 100:00:00.00
答案 0 :(得分:2)
计算小时,分钟,秒和帧的数学计算非常简单:
f=$(( i % 50 ))
s=$(( (i/50) % 60 ))
m=$(( (i/(50*60)) % 60 ))
h=$(( (i/(50*60*60)) ))
然后你可以简单地将值嵌入字符串中,如下所示:
... -draw "text 20,80 '$(printf "%03d:%02d:%02d.%02d" $h $m $s $f)'" "$i.png"
更大的问题是运行convert
1800万次需要多长时间。
答案 1 :(得分:1)
如果Bash不是单引号,则Bash会扩展命令中的变量。在这里,它们是双引号:
convert -size 780x100 xc:#d3fff5ff -font Courier-New -pointsize 100 -fill black -draw "text 20,80 '$hours:$minutes:$seconds.$frames'" $i.png
请注意,{0..18000000}
首先会扩展为18M字符串列表。使用C风格的循环可能更好:
for (( i=0 ; i<=18000000 ; i++ )) ; do
另一个问题可能是拥有一个包含18M文件的目录。也许将它们存储在像小时/分钟/秒的文件夹中?
答案 2 :(得分:1)
这种建立在chepner和choroba的答案之上,但也解决了如何使用所有CPU核心生成18,000,000个图像。我在一个不错的规格iMac上对3种不同的方法进行了基准测试,并取得了以下结果 - 从最简单,最慢,从那里开始到更快的方法......
方法1 - 普通顺序bash脚本
#!/bin/bash
for ((i=0; i<18000000; i++ )); do
f=$(( i % 50 ))
s=$(( (i/50) % 60 ))
m=$(( (i/(50*60)) % 60 ))
h=$(( (i/(50*60*60)) ))
convert -size 780x100 xc:#d3fff5ff -font Courier -pointsize 100 -fill black -draw "text 20,80 '$(printf "%03d:%02d:%02d.%02d" $h $m $s $f)'" $i.png
done
生成1800万张图片大约需要4.6天。
方法2 - GNU并行脚本
#!/bin/bash
# Define a function for GNU Parallel to run
doit() {
i=$1
f=$(( i % 50 ))
s=$(( (i/50) % 60 ))
m=$(( (i/(50*60)) % 60 ))
h=$(( (i/(50*60*60)) ))
convert -size 780x100 xc:#d3fff5ff -font Courier -pointsize 100 -fill black -draw "text 20,80 '$(printf "%03d:%02d:%02d.%02d" $h $m $s $f)'" $i.png
}
# Export doit() function so GNU Parallel knows about it
export -f doit
ulimit -S -n 2048
for ((i=0;i<=18000000;i++)); do
echo $i
done | parallel -k doit {1}
这使您的所有CPU内核保持忙碌,大约需要32小时才能生成1800万个文件。我认为与必须编写代码并在下一个答案中编译和构建代码相比,这是一个非常好的折衷方案。
方法3 - Magick ++程序并行运行8个副本
#include <Magick++.h>
using namespace std;
using namespace Magick;
int main(int argc, char* argv[]){
// Pick up parameters
if(argc!=3){
printf("ERROR: Please supply 2 arguments - start and end number\n");
exit(EXIT_FAILURE);
}
int start=atoi(argv[1]);
int end =atoi(argv[2]);
InitializeMagick(*argv);
// Create a basic template
Image img(Geometry(780,100),Color("#d3fff5ff"));
img.font("Courier");
img.fillColor(Color("black"));
img.fontPointsize(100);
// Get cycling through the images
for(int i=start;i<=end;i++){
// Work out timestamp for this frame
int f=i % 50;
int s=(i/50) % 60;
int m=(i/(50*60)) % 60;
int h=(i/(50*60*60));
char timestamp[100];
sprintf(timestamp,"%03d:%02d:%02d.%02d",h,m,s,f);
// Copy the basic template image
Image thisframe=img;
thisframe.draw(Magick::DrawableText(20,80,timestamp));
char filename[100];
sprintf(filename,"%d.gif",i);
thisframe.write(filename);
}
}
以下是并行运行8个副本的方法:
#!/bin/bash
./main 1 2250000 &
./main 2250001 4500000 &
./main 4500001 6750000 &
./main 6750001 9000000 &
./main 9000001 11250000 &
./main 11250001 13500000 &
./main 13500001 15750000 &
./main 15750001 18000000 &
wait
生成1800万个文件需要不到9个小时。