#1 Le 05/09/2015, à 09:28
- slash-z
[script] recaler les timings dans un fichier de sous-titres
Je ne sais pas si ce genre de scripts a déjà été fourni.
Mais voici ma version qui fonctionne quelle que soit la forme du décalage puisque j'utilise une équation affine type y = a x + B
Attention, les paramètres doivent être modifiés à chaque fois au début du script puisqu'ils sont inscrits en dur.
pour les deux lignes ancien_titre et nouveau_titre, je pense que c'est clair en soi.
Pour first_line, new_first, last_line et new_last quelques explications:
On recopie dans first_line n'importe quelle ligne de timing piochée au début du film.
Dans new_first, on met le nouveau timing souhaité (seulement la première partie de la ligne)
On renouvelle l'opération sur last_line et new_last pour n'importe quel sous-titre pioché en fin de film.
On lance le script (ne pas oublier le chmod +x) et normalement c'est magique mais assez lent (bicoz bourré de grep et de sed).
Je ne dis pas que c'est super bien écrit (un peu à la va-comme-j'te-pousse) mais normalement c'est efficace !
NB: On peut voir le nouveau fichier se former fur et à mesure dans une autre console en faisant un simple tail - f
Ici: tail - f './Anges Et Démons (2009).srt'
#!/bin/bash
ancien_titre='./Anges Et Démons (2009).fr.srt'
nouveau_titre='./Anges Et Démons (2009).srt'
first_line='00:02:13,710 --> 00:02:18,589'
new_first='00:02:08,500'
last_line='02:15:51,240 --> 02:15:54,529'
new_last='02:10:16,600'
# N1 = A1 * X + ERREUR
# N2 = A2 * X + ERREUR
mille1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],\([0-9][0-9][0-9]\).*/\1/')
seconde1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:\([0-9][0-9]\).*/\1/')
minute1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:\([0-9][0-9]\):[0-9][0-9].*/\1/')
heure1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^\([0-9][0-9]\):[0-9][0-9]:[0-9][0-9].*/\1/')
A1=`expr $heure1 \* 3600000 + $minute1 \* 60000 + $seconde1 \* 1000 + $mille1`
mille1=$(echo $last_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],\([0-9][0-9][0-9]\).*/\1/')
seconde1=$(echo $last_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:\([0-9][0-9]\).*/\1/')
minute1=$(echo $last_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:\([0-9][0-9]\):[0-9][0-9].*/\1/')
heure1=$(echo $last_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^\([0-9][0-9]\):[0-9][0-9]:[0-9][0-9].*/\1/')
A2=`expr $heure1 \* 3600000 + $minute1 \* 60000 + $seconde1 \* 1000 + $mille1`
mille1=$(echo $new_first | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],\([0-9][0-9][0-9]\).*/\1/')
seconde1=$(echo $new_first | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:\([0-9][0-9]\).*/\1/')
minute1=$(echo $new_first | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:\([0-9][0-9]\):[0-9][0-9].*/\1/')
heure1=$(echo $new_first | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^\([0-9][0-9]\):[0-9][0-9]:[0-9][0-9].*/\1/')
N1=`expr $heure1 \* 3600000 + $minute1 \* 60000 + $seconde1 \* 1000 + $mille1`
mille1=$(echo $new_last | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],\([0-9][0-9][0-9]\).*/\1/')
seconde1=$(echo $new_last | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:\([0-9][0-9]\).*/\1/')
minute1=$(echo $new_last | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:\([0-9][0-9]\):[0-9][0-9].*/\1/')
heure1=$(echo $new_last | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^\([0-9][0-9]\):[0-9][0-9]:[0-9][0-9].*/\1/')
N2=`expr $heure1 \* 3600000 + $minute1 \* 60000 + $seconde1 \* 1000 + $mille1`
# N2 - N1
# X = -------
# A2 - A1
NUMERATEUR=`expr $N2 - $N1`
NUMERATEUR=`expr $NUMERATEUR \* 1000000000000`
DENOMINATEUR=`expr $A2 - $A1`
X=`expr $NUMERATEUR / $DENOMINATEUR`
# ERREUR = N2 - A2 * X
ERREUR=`expr $N2 \* 1000000000000 - $A2 \* $X`
X=`expr $X / 1000`
ERREUR=`expr $ERREUR / 1000`
echo $X
echo $ERREUR
while read line
do
mille1=$(echo $line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],\([0-9][0-9][0-9]\).*/\1/')
seconde1=$(echo $line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:\([0-9][0-9]\).*/\1/')
minute1=$(echo $line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:\([0-9][0-9]\):[0-9][0-9].*/\1/')
heure1=$(echo $line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^\([0-9][0-9]\):[0-9][0-9]:[0-9][0-9].*/\1/')
mille2=$(echo $line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] | sed 's/.*\ [0-9][0-9]:[0-9][0-9]:[0-9][0-9],\([0-9][0-9][0-9]\).*/\1/')
seconde2=$(echo $line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/.*\ [0-9][0-9]:[0-9][0-9]:\([0-9][0-9]\).*/\1/')
minute2=$(echo $line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/.*\ [0-9][0-9]:\([0-9][0-9]\):[0-9][0-9].*/\1/')
heure2=$(echo $line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/.*\ \([0-9][0-9]\):[0-9][0-9]:[0-9][0-9].*/\1/')
if [ "$seconde1" != '' ]
then
temps1=`expr $heure1 \* 3600000 + $minute1 \* 60000 + $seconde1 \* 1000 + $mille1`
temps2=`expr $heure2 \* 3600000 + $minute2 \* 60000 + $seconde2 \* 1000 + $mille2`
temps1=`expr $temps1 \* $X + $ERREUR`
temps1=`expr $temps1 / 1000000000`
temps2=`expr $temps2 \* $X + $ERREUR`
temps2=`expr $temps2 / 1000000000`
heure1=`expr $temps1 / 3600000`
minute1=`expr $temps1 % 3600000 / 60000`
seconde1=`expr $temps1 % 3600000 % 60000 / 1000`
mille1=`expr $temps1 % 3600000 % 60000 % 1000`
heure2=`expr $temps2 / 3600000`
minute2=`expr $temps2 % 3600000 / 60000`
seconde2=`expr $temps2 % 3600000 % 60000 / 1000`
mille2=`expr $temps2 % 3600000 % 60000 % 1000`
if [ $heure1 -lt 10 ]
then
heure1="0$heure1"
fi
if [ $minute1 -lt 10 ]
then
minute1="0$minute1"
fi
if [ $seconde1 -lt 10 ]
then
seconde1="0$seconde1"
fi
if [ $mille1 -lt 100 ]
then
if [ $mille1 -lt 10 ]
then
mille1="0$mille1"
fi
mille1="0$mille1"
fi
if [ $heure2 -lt 10 ]
then
heure2="0$heure2"
fi
if [ $minute2 -lt 10 ]
then
minute2="0$minute2"
fi
if [ $seconde2 -lt 10 ]
then
seconde2="0$seconde2"
fi
if [ $mille2 -lt 100 ]
then
if [ $mille2 -lt 10 ]
then
mille2="0$mille2"
fi
mille2="0$mille2"
fi
line=$(echo "$line" | sed "s/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]\(.*\)[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]\(.*\)/$heure1:$minute1:$seconde1,$mille1\1$heure2:$minute2:$seconde2,$mille2\2/")
fi
echo $line >> "$nouveau_titre"
done < "$ancien_titre"
exit
Dernière modification par slash-z (Le 05/09/2015, à 09:32)
Hors ligne
#2 Le 05/09/2015, à 13:06
- credenhill
Re : [script] recaler les timings dans un fichier de sous-titres
hello
first_line='00:02:13,710 --> 00:02:18,589'
...
mille1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],\([0-9][0-9][0-9]\).*/\1/')
seconde1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:\([0-9][0-9]\).*/\1/')
minute1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:\([0-9][0-9]\):[0-9][0-9].*/\1/')
heure1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^\([0-9][0-9]\):[0-9][0-9]:[0-9][0-9].*/\1/')
peut être simplifié par
IFS=':, ' read h1 m1 s1 ml1 reste <<<"$first_line" ; echo $h1 $m1 $s1 $ml1
00 02 13 710
En ligne
#3 Le 05/09/2015, à 13:28
- slash-z
Re : [script] recaler les timings dans un fichier de sous-titres
hello
first_line='00:02:13,710 --> 00:02:18,589' ... mille1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],\([0-9][0-9][0-9]\).*/\1/') seconde1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:[0-9][0-9]:\([0-9][0-9]\).*/\1/') minute1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^[0-9][0-9]:\([0-9][0-9]\):[0-9][0-9].*/\1/') heure1=$(echo $first_line | grep ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9] | sed 's/^\([0-9][0-9]\):[0-9][0-9]:[0-9][0-9].*/\1/')
peut être simplifié par
IFS=':, ' read h1 m1 s1 ml1 reste <<<"$first_line" ; echo $h1 $m1 $s1 $ml1 00 02 13 710
Oui ça fait longtemps que j'ai pondu ce truc et j'étais pressé de voir le film.
En me relisant je pense que beaucoup, voire tous les grep sont inutiles déjà. Je pense que c'était pour faire du débogage et je les ai laissés ensuite.
Pour ce qui est de ce que tu proposes, la syntaxe <<<"$first_line" ne fonctionne si je ne m'abuse qu'avec bash dans ses nouvelles versions, c'est pas POSIX La mienne fonctionne même avec un bash du siècle précédent, en ksh ou zsh à priori.
Mais merci, effectivement je ne me sers jamais de IFS et c'est un tort
Dernière modification par slash-z (Le 05/09/2015, à 13:33)
Hors ligne
#4 Le 05/09/2015, à 13:51
- Rufus T. Firefly
Re : [script] recaler les timings dans un fichier de sous-titres
Salut,
Il existe un (au moins) truc sur le net pour faire ça. Il a surtout l'avantage de permettre aussi de la synchro non-linéaire.
Quand le film a été encodé pour dieu sait quelle raison en 23.8 images par secondes par exemple et que le sous-titre correspond au film en 24 images par secondes, ça se décale de plus en plus à mesure de l'avancement.
Il y a évidemment 2 solutions, celle qui peut être assez compliquée, de remettre le film en 24 images par secondes, et l'autre qui consiste à augmenter la durée globale de la piste de sous-titre.
Ce qu'on peut faire très facilement ici : http://olivier.jeulin.free.fr/divers/synchro/index.php
Mais c'est sans doute un truc du même genre que le script proposé.
Dernière modification par Rufus T. Firefly (Le 05/09/2015, à 13:57)
La provocation est une façon de remettre la réalité sur ses pieds. (Bertolt Brecht)
Il n'y a pas de route royale pour la science et ceux-là seulement ont chance d'arriver à ses sommets lumineux qui ne craignent pas de se fatiguer à gravir ses sentiers escarpés. (Karl Marx)
Il est devenu plus facile de penser la fin du monde que la fin du capitalisme
Hors ligne
#5 Le 05/09/2015, à 15:21
- credenhill
Re : [script] recaler les timings dans un fichier de sous-titres
ceci doit fonctionner avec un vieux sh
$ IFS=':, '; set -- $first_line; h1=$1; m1=$2; s1=$3; ml1=$4; echo $h1 $m1 $s1 $ml1
00 02 13 710
En ligne
#6 Le 05/09/2015, à 15:43
- slash-z
Re : [script] recaler les timings dans un fichier de sous-titres
Excellent là aussi. Je n'aurais jamais pensé à me servir de set dans ce cas.
Du coup je vais peut-être prendre le temps de le réécrire, ça devrait sérieusement le booster. Et puis tu me files la honte avec de telles ingénieuses astuces
Hors ligne