post_date=2010-01-22
post_user=YJR
Hey everyone. I just wrote up a script that solved a problem I had with the inability of the WDTV to support SSA/ASS fonts and I just wanted to share that with everyone.
Basically the WDTV displays only one line of subs at a time so often when there is karaoke or multiple conversations, the subs cut each other out and makes it incomprehensible. This is because it seems to convert to SRT on the fly but it doesn't solve the timing overlap problem. This semi-automatically fixes the problem by combining separate subs when their times overlap.
It works satisfactorily for the files that I've tried it on. I'm a medical student and I have no time to optimize it more or debug it more (although it seems relatively free of bugs) so I'm just throwing this out there in case it is useful to anyone else. This was also my first time doing anything in Pascal so forgive me for any oddities in the code.
The first script is KaraokeTag:
// Based on AddDottedLine. Add dotted line. Made by Bedazzle.
program KarokeTag;
// ---------------------------------------------
const
symboltoadd = '*';
var
n: Integer;
i: Integer;
txt: String;
begin
n := GetSubtitleCount;
for i := 0 to n-1 do
begin
if IsSubtitleSelected(i) then
begin
txt := symboltoadd + GetSubtitleText(i);
SetSubtitleText(i, txt);
end;
end;
end.
This is totally copied from the script by Bedazzle. I just changed it to add a star and also to only add it to selected subs. The purpose of this is for you to tag your problem subs for later processing by other scripts.
After taging the problem subs. Use sort to get everything ranked by time. Then run the next script.
The second script is SRTfix:
// Fix subtitle time overlap in SRT. Made by YJR
// Written for SubtitleWorkshop by YJR
// To be used with KarokeTag and KaraokeFix
program SRTfix;
// -------------------------------------
var
i: Integer;
n_max: Integer;
start1: Integer;
end1: Integer;
start2: Integer;
end2: Integer;
Edited: Boolean;
txt1: String;
txt2: String;
txtout: String;
begin
Edited := true;
while Edited do
begin
Edited := false;
n_max := GetSubtitleCount;
for i := 0 to n_max-2 do
begin
start1 := GetSubtitleInitialTime(i);
end1 := GetSubtitleFinalTime(i);
txt1 := GetSubtitleText(i);
start2 := GetSubtitleInitialTime(i+1);
end2 := GetSubtitleFinalTime(i+1);
txt2 := GetSubtitleText(i+1);
if ((end1 > start2) and (end2 > start1)) then
begin //make sure that they're overlaping
if (start1 = start2) then
begin
if (end1 = end2) then
begin //Simply combine them
DeleteSubtitle(i);
DeleteSubtitle(i); //Deleting changes numbering so this is actually i+1
txtout := txt1 + '|' + txt2;
InsertSubtitle(i,start1,end1,txtout,'');
Edited := true;
end;
if (end1 < end2) then
begin //Fragment off the trailing portion that is not overlapping
DeleteSubtitle(i);
DeleteSubtitle(i);
InsertSubtitle(i,end1+1,end2,txt2,'');
InsertSubtitle(i,start2,end1,txt2,'');
InsertSubtitle(i,start1,end1,txt1,'');
Edited := true;
end;
if (end1 > end2) then
begin //Fragment off the trailing portion that is not overlapping
DeleteSubtitle(i);
DeleteSubtitle(i);
InsertSubtitle(i,end2+1,end1,txt1,'');
InsertSubtitle(i,start2,end2,txt2,'');
InsertSubtitle(i,start1,end2,txt1,'');
Edited := true;
end;
end;
if (start1 < start2) then
begin //Fragment off the leading portion
DeleteSubtitle(i);
DeleteSubtitle(i);
InsertSubtitle(i,start2,end2,txt2,'')
InsertSubtitle(i,start2,end1,txt1,'')
InsertSubtitle(i,start1,start2-1,txt1,'')
Edited := true;
end;
if (start1 > start2) then
begin //Fragment off the leading portion
DeleteSubtitle(i);
DeleteSubtitle(i);
InsertSubtitle(i,start1,end1,txt1,'')
InsertSubtitle(i,start1,end2,txt2,'')
InsertSubtitle(i,start2,start1-1,txt2,'')
Edited := true;
end;
end;
end;
end;
end.
What this does is it combines subtitles whenever they overlap. So for instance if the SSA specify that X is displayed from 2 to 5, and Y is displayed from 3 to 6, it'll display X from 2 to 3, XY from 3 to 5, and Y from 5 to 6. It treats the marked subs by karaoke tags normally.
By now it should be clear that even if the conversations are displayed in this way and everything can be seen, the background text might bounce around as the foreground text is turned on and off. Additionally, the background and foreground texts might randomly be switched in some instances. This is why we previously labeled our problem subs with an asterisk and the next script solves these problems.
The last script is KaraokeFix:
program KaraokeFix;
// Fix Karaoke using the tags generated by KaraokeTag
// Written for SubtitleWorkshop by YJR
const
symboltoadd = '*';
var
i: Integer;
n_max: Integer;
start1: Integer;
end1: Integer;
splitlocation: Integer;
strlength: Integer;
txtin: String;
txt1: String;
txt2: String;
input: String;
output: String;
ni: Integer;
begin
n_max := GetSubtitleCount;
for i := 0 to n_max-1 do
begin
txtin := GetSubtitleText(i);
strlength := length(txtin);
splitlocation := Pos('|',txtin);
if splitlocation <> 0 then
begin
txt1 := Copy(txtin,1,splitlocation-1);
txt2 := Copy(txtin,splitlocation+1,strlength-splitlocation);
if txt1[1] = '*' then
begin
txt1 := Copy(txt1,2,length(txt1)-1);
SetSubtitleText(i,txt1 + '|' + txt2);
end;
if txt2[1] = '*' then
begin
txt2 := Copy(txt2,2,length(txt2)-1);
SetSubtitleText(i,txt2 + '|' + txt1);
end;
end;
if ((splitlocation = 0) and (txtin[1] = '*')) then
begin
SetSubtitleText(i,Copy(txtin,2,length(txtin)-1)+ '|*');
end;
end;
end.
What this does is if it finds a line with an asterisk, it'll bring it to the top of the line for the subs. This ensures that karoke stays on top. It also places a spaceholding asterisk below marked lines that are sitting by themselves so that the position of the text is maintained as foreground speech continues so its not bouncing around all the time.
So far i've tried this with a few anime and they all seem to work fine. I hope this helps someone enjoy their WDTV a lot more like it helped me.