Voici le script, annoté à l’arrache :
/**************
This is a Processing parser for .SRT files, a widely used subtitle text file format.
.SRT file information is obtained from: http://en.wikipedia.org/wiki/SubRip
The SubRip file format is "perhaps the most basic of all subtitle formats."
SubRip files are named with the extension .srt,
and contain formatted UTF-8 plain text.
The time format used is hours:minutes:seconds,milliseconds.
The decimal separator used is the comma,
since the program was written in France;
the line break used is the CR+LF pair.
Subtitles are numbered sequentially, starting at 1.
The format for an .SRT subtitle is:
Subtitle number
Start time --> End time
Text of subtitle (one or more lines)
Blank line
These are parsed into a series of SubtitleUnit data structures
and stored in the Java Vector, subtitleVector.
(See class definition for SubtitleUnit below.)
***************/
//-----------------------------------------------------------
// Which .SRT file should we load (from the sketch's "data" folder)?
String srtFilename = "THX_1138.srt";
int compteur=0;
String sub_text="";
int adjuster;
//-----------------------------------------------------------
void setup() {
size(600, 400);
textAlign(CENTER, CENTER);
subtitleVector = new ArrayList();
creervecteur();
// recuperer le passage du dernier sous-titre
SubtitleUnit SU=(SubtitleUnit) subtitleVector.get(subtitleVector.size()-1);
length_srt=SU.endTime+5000;
adjuster=millis(); // commencer le compteur maintenant
}
void draw() {
background (0);
fill(255);
int this_moment=millis()-adjuster;
if (this_moment > sub_end) {
compteur++;
new_subtitle();
if (compteur > subtitleVector.size()-1) { // retourner au début
compteur=0;
}
}
if (this_moment > sub_start && this_moment < sub_end) {
text(sub_text, width/2, height*0.4);
}
text("compteur "+compteur + " - " + sub_text, width/2, height*40);
text(this_moment, width/2, height*0.60);
text(sub_start + " - "+ sub_end, width/2, height*0.66);
// dessiner la barre de défilement
noStroke();
fill(0, 100, 10);
rect(0, height-20, width, 20);
stroke(255);
float p=map(millis()-adjuster, 0, length_srt, 0, width);
line(p, height-20, p, height);
}
void mouseClicked() {
if (mouseY > height-20) {
adjuster=millis()-int(map(mouseX, 0, width, 0, length_srt));
find_subtitle();
}
}
// toutes les fonctions de traitement des sous-titres
//-----------------------------------------------------------
// Important booleans which modify how we will perform the parsing.
boolean bStripItalicChars = true; // Remove <i> and </i>
boolean bStripOtherChars = true; // Remove initial hyphens and ellipses
boolean bStripMusicChars = true; // Remove #, indicating music
boolean bStripStagingChars = false; // Remove brackets [ and ], indicating instructions
boolean bConvertToLowerCase = true; // Convert all subtitles to lowercase
String rawSRTLines[];
int nRawSRTLines;
int nSubtitles;
ArrayList subtitleVector;
int sub_start;
int sub_end;
int length_srt;
//-----------------------------------------------------------
// Different codes for subtitles.
int SUBTITLE_TYPE_SPEECH = 0;
int SUBTITLE_TYPE_MUSIC = 1;
int SUBTITLE_TYPE_STAGING = 2;
int SUBTITLE_TYPE_ITALIC = 3;
String typeStrs[] = {
"SPEECH", "MUSIC", "STAGING", "ITALIC"
};
//-----------------------------------------------------------
// This class contains a single Subtitle: what was said when.
class SubtitleUnit {
int subtitleNumber;
int subtitleType;
int startTime;
int endTime;
String subtitleText;
void print() {
String typeStr = typeStrs[subtitleType];
println(subtitleNumber + "\t" + typeStr + "\t" + startTime + "\t" + endTime + "\t" + subtitleText);
}
}
// ============================================== ici on crée les elements de sous-titre
void creervecteur() {
rawSRTLines = loadStrings(srtFilename);
nRawSRTLines = rawSRTLines.length;
if (nRawSRTLines > 0) {
String prevLine = rawSRTLines[0];
String currLine = "";
for (int i=1; i<nRawSRTLines; i++) {
currLine = rawSRTLines[i];
int indexOfArrowChars = currLine.indexOf("-->");
if (indexOfArrowChars > -1) {
// if we're here, then currLine is a timecode line, and prevline is an ID line
int subtitleType = SUBTITLE_TYPE_SPEECH;
int subtitleID = Integer.parseInt (prevLine.trim());
String startString = currLine.substring (0, indexOfArrowChars);
String endString = currLine.substring (indexOfArrowChars+4, currLine.length());
startString = startString.trim();
endString = endString.trim();
// Extract and compute the start and end timestamps of the subtitle.
int sH = Integer.parseInt( startString.substring(0, 2));
int sM = Integer.parseInt( startString.substring(3, 5));
int sS = Integer.parseInt( startString.substring(6, 8));
int sL = Integer.parseInt( startString.substring(9, 12));
float startTimeInSeconds = 60*60*sH + 60*sM + sS + sL/1000.0;
int eH = Integer.parseInt( endString.substring(0, 2));
int eM = Integer.parseInt( endString.substring(3, 5));
int eS = Integer.parseInt( endString.substring(6, 8));
int eL = Integer.parseInt( endString.substring(9, 12));
float endTimeInSeconds = 60*60*eH + 60*eM + eS + eL/1000.0;
// Subtitles might be on several lines. Search ahead to find the end.
String subtitle = "";
int lineNumberToStartFrom = i;
String futureLine = currLine;
while ( (lineNumberToStartFrom< (nRawSRTLines-1)) && (futureLine.length() != 0)) {
lineNumberToStartFrom++;
futureLine = rawSRTLines[lineNumberToStartFrom];
subtitle += futureLine + " ";
}
// Cleanup phase: clean the text.
subtitle = subtitle.trim();
if (bConvertToLowerCase) {
subtitle = subtitle.toLowerCase();
}
//----------------------------------------
if (subtitle.startsWith("#")) {
subtitleType = SUBTITLE_TYPE_MUSIC;
}
if (subtitle.startsWith("[")) {
subtitleType = SUBTITLE_TYPE_STAGING;
}
if (subtitle.startsWith("<i>")) {
subtitleType = SUBTITLE_TYPE_ITALIC;
}
//----------------------------------------
if (bStripItalicChars) {
if (subtitle.startsWith("<i>")) {
subtitle = subtitle.substring(3, subtitle.length());
}
if (subtitle.endsWith("</i>")) {
subtitle = subtitle.substring(0, subtitle.length()-4);
}
}
if (bStripOtherChars) {
if (subtitle.startsWith("-")) {
subtitle = subtitle.substring(1, subtitle.length());
}
if (subtitle.startsWith("...")) {
subtitle = subtitle.substring(3, subtitle.length());
}
}
if (bStripMusicChars) {
if (subtitle.startsWith("#")) {
subtitle = subtitle.substring(1, subtitle.length());
}
if (subtitle.endsWith("#")) {
subtitle = subtitle.substring(0, subtitle.length()-1);
}
}
if (bStripStagingChars) {
if (subtitle.startsWith("[")) {
subtitle = subtitle.substring(1, subtitle.length());
}
if (subtitle.endsWith("]")) {
subtitle = subtitle.substring(0, subtitle.length()-1);
}
}
// One more trim for good luck.
subtitle = subtitle.trim();
//----------------------------------------
// Create a new Subtitle containing the above data,
// and append it to the Vector of subtitles.
SubtitleUnit SU = new SubtitleUnit();
SU.subtitleNumber = subtitleID;
SU.subtitleType = subtitleType;
SU.startTime = int(startTimeInSeconds*1000);
SU.endTime = int(endTimeInSeconds*1000);
SU.subtitleText = subtitle;
//subtitleVector.addElement(SU);
subtitleVector.add(SU);
nSubtitles++;
}
prevLine = currLine;
}
}
}
void new_subtitle() {
SubtitleUnit SU = (SubtitleUnit) subtitleVector.get(compteur);
sub_text=SU.subtitleText;
sub_start=SU.startTime;
sub_end=SU.endTime;
}
void find_subtitle() {
for (int i=0;i<subtitleVector.size();i++) {
SubtitleUnit SU = (SubtitleUnit) subtitleVector.get(i);
if (SU.endTime > millis()-adjuster) {
compteur=i;
new_subtitle();
break;
}
}
}