最近得了「弹幕依赖症」,看视频时没有弹幕总觉得哪里不对劲,之前写过拿弹幕文件的东西,再配合转换XML弹幕为ASS,本来基本就完事的,不过这一次,因为分Part了,两个XML都是从Part的00:00.00开始计时的,而在网上下载的原始视频是完整的,于是就需要调整第二个ASS文件的时间。
这里每个弹幕文件里面都有8000条,人工调整当然是想都没想过,想的是用什么语言来写个快速调整ASS字幕时间的,C/C++虽然处理很快,但是,果然呢,说到文字处理,那为何不用Perl呢。
于是说做就做,这里就仅仅是针对使用了转换XML弹幕为ASS的ASS文件,不过其实要改成通用的,也只需要改一小部分即可。直接贴代码啦。
Code
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use 5.010;
use Getopt::Long;
sub colon_time_to_second {
my \$time = shift || return 0;
my @component = split':',\$time;
return 0 if (\$#component != 2);
\$component[0] * 3600 + \$component[1] * 60 + \$component[2];
}
sub second_to_colon_time {
my \$seconds = shift;
my \$component1 = int(\$seconds / 3600);
my \$component2 = sprintf"%02d", (int((\$seconds - \$component1 * 3600) / 60));
my \$component3 = sprintf"%05.2f",(\$seconds - \$component1 * 3600 - \$component2 * 60);
"\$component1:\$component2:\$component3";
}
sub shift_timeline {
my \$orig = colon_time_to_second shift;
my \$shift = shift || 0;
second_to_colon_time \$orig + \$shift;
}
sub shift_file_name {
my \$filename = shift;
my @paths = split'/',\$filename;
my \$filepath = \$paths[\$#paths];
my @dots = split /./,\$filepath;
if (\$#dots > 0) {
my \$shift_name = "";
for(my \$i = 0; \$i < \$#paths; \$i++){
\$shift_name .= \$paths[\$i];
\$shift_name .= "/";
}
for (my \$i = 0; \$i < \$#dots; \$i++) {
\$shift_name .= \$dots[\$i];
\$shift_name .= ".";
}
\$shift_name .= "shift.".\$dots[\$#dots];
} else {
my\$shift_name = "";
for(my\$i = 0; \$i < \$#paths - 1; \$i++){
\$shift_name .= \$paths[\$i];
\$shift_name .= "/";
}
\$shift_name .= "_shift";
}
}
my@all_file = ();
my\$shift_time;
GetOptions(
'file|f=s{,}'=> @all_file,
't=s' => \$shift_time
);
foreach my \$file (@all_file) {
next if (!-f -e \$file);
open (my\$ASSFILE ,\$file);
my \$shift_file_name = shift_file_name \$file;
open my \$CONVERT, ">\$shift_file_name"ordie"cannot open \$shift_file_namen";
while (<\$ASSFILE>) {
if (/Dialogue: 2,(.*),Danmaku2ASS(.*)/) {
my @time = split ',',\$1;
print \$CONVERT"Dialogue: 2,";
print \$CONVERT shift_timeline \$time[0], \$shift_time;
print \$CONVERT",";
print \$CONVERT shift_timeline \$time[1], \$shift_time;
print \$CONVERT",Danmaku2ASS";
print \$CONVERT\$2;
}else {
print \$CONVERT\$_;
}
}
say"OK! Saved at \$shift_file_name";
}
say"[All Done]";