Fixing overlapping subtitles  in srt files

F.P. Laussy - fabrice.laussy@gmail.com
10 July 2023 - see http://laussy.org/wiki/Blog:Hacks/Overlapping_subtitles_in_kdenlive

SetDirectory[NotebookDirectory[]]

Modules

Not all of those modules are needed

trimBefore[srttime_]:=StringPadLeft[ToString[Floor[FractionalPart[DateList[{srttime,{"Hour",":","Minute",":","Second",",","Millisecond"}}] [[-1]]]*((1000+1)/40)]*40],3,"0"]

trimBefore["00:00:02,081"]

trimAfter[srttime_]:=StringPadLeft[ToString[Ceiling[FractionalPart[DateList[{srttime,{"Hour",":","Minute",":","Second",",","Millisecond"}}] [[-1]]]*((1000-1)/40)]*40],3,"0"]

AddSecond[strtime_]:=Module[{datelist},
datelist=DateList[{strtime,{"Hour",":","Minute",":","Second",",","Millisecond"}}];
DateString[DateObject[
If[1000FractionalPart[datelist[[-1]]]>960.1,DatePlus[Flatten@{datelist[[Range[5]]],IntegerPart[datelist[[-1]]]},Quantity[1,"Second"]],datelist]
],{"Hour",":","Minute",":","Second",",","Millisecond"}]
]

AddSecond["00:34:59,782"]

AddSecond["00:34:59,982"]

This is the module actually needed to do the job:

RemoveTime[strtime_,δt_]:=Module[{datelist},
datelist=DateList[{strtime,{"Hour",":","Minute",":","Second",",","Millisecond"}}];
DateString[DateObject[DatePlus[datelist,Quantity[-δt-ϵt,"Second"]]],{"Hour",":","Minute",":","Second",",","Millisecond"}]
]

Data

fn=FileNames["timestamps"]

subt=ToString/@Import[fn[[1]],"List"];

Better with sed as the following can break with quoted text

(*ltimes=Pick[subt,StringContainsQ["-->"]@subt];*)

The following remove the non-numerical stuff that we got cluttered with:

lsplit=StringSplit[#,"-->"]&/@subt;

ltimes=StringReplace[#,"{"->""]&/@lsplit;

ltimes2=StringReplace[#,"}"->""]&/@ltimes;

ltimess is the list of times in string form:

ltimess=StringReplace[#," "->""]&/@ltimes2;

ltimes (single-s) is the list of numerical times:

ltimes=Map[AbsoluteTime[{#,{"Hour",":","Minute",":","Second",",","Millisecond"}}]&,ltimess,{2}];

List of starting and stopping times:

ltimesStart=ltimes[[All,1]];

ltimesStop=ltimes[[All,2]];

Occurences with no delay:

Flatten[Position[ltimesStart-RotateRight[ltimesStop,1],val_/;val==0]]

Occurences with negative delay: (the file was fixed)

loverlap=Drop[Flatten[Position[ltimesStart-RotateRight[ltimesStop,1],val_/;val<0]],1]

Time accuracy of kdenlive (actually 1/25, here we take it slightly larger)

ϵt=(1/24.)

loverlap=Drop[Flatten[Position[ltimesStart-RotateRight[ltimesStop,1],val_/;val<ϵt]],1];

Percentages of cases to fix:

((Length[loverlap])/(Length[ltimesStart]))100.

lδt=-(ltimesStart-RotateRight[ltimesStop,1]);

Export["rules.txt",Table["s/--> "<>ltimess[[All,2]][[i-1]]<>"/--> "<>RemoveTime[ltimess[[All,2]][[i-1]],lδt[[i]]+ϵt]<>"/",{i,loverlap}]]

Now run sed on these rules and your srt file.