ASS字幕时间调整

最近得了「弹幕依赖症」,看视频时没有弹幕总觉得哪里不对劲,之前写过拿弹幕文件的东西,再配合转换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 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]";

声明: 本文为0xBBC原创, 转载注明出处喵~

发表评论

电子邮件地址不会被公开。 必填项已用*标注