mercredi 11 juin 2008

Décalage temporel des fichiers .srt

Les fichiers à extension .srt sont des fichiers textes utilisés pour sous-titrer des vidéos, typiquement des divx. Il arrive que les sous-titres contenus dans ces fichiers soient décalés globalement(1 seconde d'avance ou 2 secondes de retard).
Voici l'exemple d'un fichier .srt:
1
00:01:14,601 --> 00:01:16,410
Il fait beau aujourd'hui

Le but de l'application d'aujourd'hui est d'écrire une commande Ruby, utilisant les expressions régulières:
-prenant en paramètre le nom d'un fichier.srt,un décalage temporel exprimé en millième de seconde et un nom de fichier de sortie.
-vérifiant que le fichier passé en paramètre existe et est exploitable.
-appliquant le décalage temporel au fichier initial pour pouvoir générer le fichier de sortie.
exemples de fichiers.srt:

Le code correspondant à l'application est le suivant:
fichier=ARGV[0]
decalage=ARGV[1]
nvofichier=ARGV[2]
Comme cité ci-dessus, ces trois lignes nous montrent les arguments que l'utilisateur devra passer en paramètre qui sont le fichier, le décalage et le nouveau fichier.

On commence tout d'abord par ouvrir le nouveau fichier en mode écriture.
nomfichier = File.open(nvofichier,'w')
Puis on vérifie que le fichier existe et est bien exploitable.

if File.file?(fichier)&&File.writable?(fichier)

Ensuite on fait appel à la méthode open de la classe File qui ouvre et ferme un fichier à la fois et peut être aussi associée à un bloc.
File.open(fichier,'r') do |file|

Après, on a recours à un itérateur qui parcourt les lignes du fichier et teste la concordance(=~) de ces dernières avec le format d'un fichier .srt, comme vous pouvez le remarquer l'expression suivante : (\d{2}:\d{2}:)(\d{2}),(\d{3})(-->\\d{2}:\d{2}:)(\d{2}),(\d{3})/correspond au format de l'heure dans un fichier .srt, en effet on utilise à nouveau des expressions régulières qui utilisent à leur tour des patterns(dont l'intérêt est de filtrer une chaîne de caractères selon cette même expression régulière), le \d{2} fait deux fois référence à un chiffre et les parenthèses sont utilisées pour regrouper les termes d'expressions régulières à l'intérieur.

file.each_line do |line|

if line =~ /(\d{2}:\d{2}:)(\d{2}),(\d{3})( --> \d{2}:\d{2}:)(\d{2}),(\d{3})/

Si la concordance est vérifiée ,les variables $1,$2,..contiendront respectivement la première, la seconde,....sous-expression régulière.
nvsec1="#{$2}#{$3}".to_i+decalage.to_i
nvsec2="#{$5}#{$6}".to_i+decalage.to_i
Enfin,on crée deux variables nvsec1 et nvsec2 qui contiendront respectivement les variables ($2,$3)et ($5,$6) décalés du décalage que la fonction prend en paramètre.

nvsec2=nvsec2.to_s.insert(-4, ',')
nvsec1=nvsec1.to_s.insert(-4, ',')
line = "#{$1}"+nvsec1.to_s+"#{$4}"+nvsec2.to_s
nomfichier.puts line
else
nomfichier.puts line
end
end
end
else

Si le fichier passé n'existe pas ou est inexploitable on retourne le message d'erreur suivant :
puts "Fichier qui n'existe pas ou qui n'est pas exploitable"
end

Après s'être attardées sur l'explication du code, finissons alors avec une petite application.
Comme convenu on rentre en paramètre un nom de fichier, un décalage qui est de 1 pour cet exemple et un autre fichier de sortie.
Le résultat obtenu est le suivant.
1
00:01:14,601 --> 00:01:16,410
Il fait beau aujourd'hui
après l'application du programme ruby:
1
00:01:14,600 --> 00:01:16,409
Précédemment dans 24


Aucun commentaire: