Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 05/09/2015, à 10: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 ! smile

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, à 10:32)

Hors ligne

#2 Le 05/09/2015, à 14: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

Hors ligne

#3 Le 05/09/2015, à 14:28

slash-z

Re : [script] recaler les timings dans un fichier de sous-titres

credenhill a écrit :

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 smile 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 wink

Dernière modification par slash-z (Le 05/09/2015, à 14:33)

Hors ligne

#4 Le 05/09/2015, à 14: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, à 14: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, à 16: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

Hors ligne

#6 Le 05/09/2015, à 16: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 smile

Hors ligne