Tips in Action‎ > ‎문자열‎ > ‎

유틸리티: 자막 동기화

전종필

간단한 유틸리티 하나 만들어 보았습니다. 동영상을 보다가, 간혹, 영상과 자막이 맞지 않는 경우가 있었습니다.
자막은 HTML 비슷한 모양을 하고 있습니다.(형식이 허술(?)해서 XML이라고는 할 수 없겠군요) 이 안에 보면 <SYNC Start=4629>와 같은 태그가 붙어있음을 볼 수 있습니다. 여기 4629는 밀리 초로, 영화시작한지 4.629초 이후에 이 태그 이후의 문장이 자막으로 출력된다는 뜻입니다. 따라서, 동영상과 자막이 맞지 않으면 이 숫자를 조정해 주면 된다고 할 수 있습니다. 대부분의 경우 한번 맞지 않는 자막은 그 이후로 계속해서 맞지 않습니다. 결국 모든 <SYNC> 태그를 고쳐줘야 하지만, 손으로 이런짓을 할 수는 없겠죠.

아래 스크립트는 모든 <SYNC> 태그에 대해, 선택적으로 몇 초 이후부터의 태그들에 대해서만, 시간을 조정해 주는 스크립트입니다. 직접 분석해 보시고 편한대로 고쳐 쓸 수도 있을 것입니다.



=head1 제목

smictrl.pl - 자막 동기시간 조정 스크립트

=head1 SYNOPSIS

  smictrl FILENAME SECONDS_TO_ADJUST [ ADJUST_FROM_WHERE ]
	
    SECONDS_TO_ADJUST : 조정할 양. 0이 아닌 정수(양수 또는 음수)
    ADJUST_FROM_WHERE : 조정이 시작될 시간(몇 초 후부터 조정).
                        없으면 0(처음)으로 간주

  smictrl mymovie.smi 5
  
    자막파일 mymovie.smi의 모든 자막에 대해 5초씩 늦게 나오게 함.

  smictrl mymovie.smi -3 30
  
    자막파일 mymovie.smi의 30초 이후 부터의 모든 자막에 대해 3초씩 더 빨리 나오게 함.

=head1 설명

자막파일(*.smi)이 동영상과 맞지 않을 경우 이를 조절하여 주는 유틸리티.
간단하게..

=head1 만든 이

=item 전종필(펄아비)

=cut

use strict;
my $file = shift || usage();
my $adjust = shift || usage();
my $from = shift;

$adjust *= 1000;
$from *= 1000;
adjust($file, $adjust, $from);

###
sub adjust {
	my $file = shift;
	my $adjust = shift;
	my $from = shift;
	$adjust += 0;
	$from += 0;
	
	my $txt = readFile($file);
	
	$txt =~ s/<sync\s+([^>]+)>/"<Sync " . &adjustSync($1,$adjust,$from) . ">";/gei;
	rename($file, "$file.bak") or warn "RENAME $file to $file.bak failed: $!";
	open(FILE, ">$file") || die "파일쓰기 실패: $file";
	print FILE $txt;
	close FILE;
}

###
sub readFile {
	my $file = shift;
	if( open(F, $file) ) {
		local $/ = undef;
		my $txt = <F>;
		close F;
		return $txt;
	}
	die "Reading $file failed: $!";
}

###
sub adjustSync {
	my $paramStr = shift;
	my($adjust, $from) = @_;
	my $save = $paramStr;
	$paramStr =~ s/\bstart=(['"]?)(\d+)\1/{ "start=" . ( $2 >= $from ? $2 + $adjust : $2 ) }/gei;
	# 위에는 약간의 문제가 있습니다. 무엇일까요?
	return $paramStr;
}

###
sub usage {
	print <<EOT;
Usage :

$0 FILENAME SECONDS_TO_ADJUST [ ADJUST_FROM_WHERE ]
	
  SECONDS_TO_ADJUST : 조정할 양. 0이 아닌 정수(양수 또는 음수)
  ADJUST_FROM_WHERE : 조정이 시작될 시간(몇 초 후부터 조정).
                      없으면 0(처음)으로 간주

EOT
	exit(0);
}


Comments