#!/usr/bin/perl # # cc_parse.pl 0.2 # Copyright (c) 2007 nhjm449 # # Creates ASS subtitle files from timestamped zvbi-ntsc-cc output. # # You may do whatever you want to with this script as long as copyright # information is retained. # use strict; my ($cctext, %cclines, $linecount, @guesstitles, $guesstitlecount); if ($ARGV[0]) { print STDERR "Opening file '".$ARGV[0]."'...\n"; } else { print STDERR "Usage: $0 filename\n"; exit(1); } open(my $ccfile, $ARGV[0]) or do { print STDERR "Error: Failed to open file!"; exit(1); }; foreach (<$ccfile>) { $cctext .= $_; } close($ccfile); print STDERR "Parsing captions...\n"; foreach my $line ( split(/\n/, $cctext) ) { if ($line =~ s/^\[TIME ([\d\.]+?)\] //) { $linecount++; $cclines{$linecount}{"time"} = $1; } if ($line =~ s/^>> //) { $cclines{$linecount}{"newspeaker"} = 1; if ($line =~ s/^([^\n]+): //) { $cclines{$linecount}{"speaker"} = $1; } } else { if ($linecount > 0 and $cclines{$linecount-1}{"speaker"}) { $cclines{$linecount}{"speaker"} = $cclines{$linecount-1}{"speaker"}; } else { $cclines{$linecount}{"newspeaker"} = 1; $cclines{$linecount}{"speaker"} = ""; } } if ($line =~ /^\%/ or $line =~ /^\[[^\n]*?\]$/) { $cclines{$linecount}{"comment"} = 1; } $cclines{$linecount}{"text"} .= $line . "\n"; if ($line =~ /^%\s+TITLE: (.+?)$/) { $guesstitles[$guesstitlecount++] = $1; } } my $guesstitle = ( @guesstitles ? join("/", @guesstitles) : "Untitled" ); print STDERR "Creating ASS subtitles for $guesstitle...\n"; print <<"EOF"; [Script Info] ; Script generated by cc_parse.pl v0.2 by nhjm449 Title: $guesstitle Closed Captions ScriptType: v4.00+ [V4+ Styles] Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding Style: Default,Arial,24,&H00FFFFFF,&H0000FFFF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,1,10,10,10,0 [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text EOF foreach my $line ( sort { $a <=> $b } keys %cclines ) { next if ($line <= 0); #print "line:$line "; $cclines{$line}{"text"} =~ s/\n$//; $cclines{$line}{"text"} =~ s/\n/\\N/g; my $cctype = $cclines{$line}{"comment"} ? "Comment" : "Dialogue"; my $speaker = $cclines{$line}{"speaker"}; my $style = $speaker ? $speaker : "Default"; my $starttime = &seconds_to_timestamp( $cclines{$line}{"time"} - $cclines{1}{"time"} ); my $endtime = &seconds_to_timestamp( $cclines{$line+1} ? $cclines{$line+1}{"time"} - $cclines{1}{"time"} - (30/1001) : $cclines{$line}{"time"} - $cclines{1}{"time"} ); #print "speaker:$speaker newspeaker:$newspeaker \n"; print "$cctype: 0,$starttime,$endtime,$style,$speaker,0000,0000,0000,," . $cclines{$line}{"text"} . "\n"; } print STDERR "Finished... Enjoy! :)\n"; sub seconds_to_timestamp { my $seconds = shift; my $o_csec = ($seconds * 100) % 100; my $o_seconds = $seconds % 60; my $o_minutes = ($seconds / 60) % 60; my $o_hours = ($seconds / 3600) % 24; return sprintf("%d:%02d:%02d.%02d", $o_hours, $o_minutes, $o_seconds, $o_csec); }