Bash script pour resynchroniser les fichiers de sous-titres srt

Terminal logo

Il est fréquent de subir des problèmes de synchronisation avec les fichiers de sous-titre. En effet, il arrive régulièrement que le fichier de sous-titres ne soit pas afapté à notre fichier video source. Cela se caractérise alors par un décalage qui va de quelques millisecondes à plusieurs secondes et qui par conséquent peut vite s'avérer frustrant.

Il est possible avec la plupart des lecteurs vidéos (vlc, mpv ou mplayer); voir ici; d'adjuster ce délais, mais la configuration sera perdue lors du prochain visionnage. Il peut donc être plus interessant d'avoir la possibilité de mofifier le décalage directement dans le fichier de sous-titrage.

Et j'ai justement développé un script en bash pour faire ça.

Utilisation

  • Utilisation :
user@host:~$ ./shebangthe_srt.sh -f [srt file] -t '[+/- time]'
  • Enlever 400 milisecondes au fichier de sous-titres :
user@host:~$ ./shebangthe_srt.sh -f /home/std/Running.on.Empty.1988.1080p.BluRay.x264.AAC.5.1-POOP.srt -t '- 0.400'
  • Ajouter 1.400 secondes au fichier de sous-titres :
user@host:~$ ./shebangthe_srt.sh -f /home/std/Running.on.Empty.1988.1080p.BluRay.x264.AAC.5.1-POOP.srt -t '+ 1.400'

Format du fichier srt

  • Ce script a été créé pour traiter ce type de fichiers srt seulement :
[…]
1126
01:55:12,527 --> 01:55:14,461
I love you.

1127
01:55:20,735 --> 01:55:22,669
I really love you.

Code

#! /bin/bash

IFS=$'\n'
option_F_found=0
option_T_found=0

usage()
{
        echo "usage: ./subtitles.sh -f [srt file] -t '[+/- time]'"
        echo "ex : ./subtitles.sh -f /home/std/lecuisinierlevoleursafemmeetsonamant.srt -t '- 18.100'"
        echo "ex : ./subtitles.sh -f /home/std/lecuisinierlevoleursafemmeetsonamant.srt -t '+ 18.100'"
        echo ""
        exit 3
}

while getopts f:t: OPTNAME; do
        case "$OPTNAME" in
        f)
                FILE="$OPTARG"
                option_F_found=1
                ;;

        t)
                TIME="$OPTARG"
                option_T_found=1
                ;;


        *)
                usage
                ;;
        esac
done

if [ "$option_F_found" -eq "0" ] || [ "$option_T_found" -eq "0" ]; then
        usage
fi

FunctionDuration()
{
        duration_temp=$(date -d "1983-12-12 $1" "+%s.%3N")
        duration_diff=$(echo "scale=3; $duration_temp $TIME" | bc -l)
        duration_dest=$(date -d"@$duration_diff" "+%H:%M:%S,%3N")
        echo "$duration_dest"
}


for i in $(grep -E "[0-9]{2}:[0-9]{2}\,[0-9]{3}" "$FILE");
do
        A=$(echo "$i" | sed 's/\([0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\,[0-9]\{3\}\) --> \([0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\,[0-9]\{3\}\)/\1/')
        B=$(echo "$i" | sed 's/\([0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\,[0-9]\{3\}\) --> \([0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\,[0-9]\{3\}\)/\2/')
        VAL1=$(FunctionDuration "$A")
        VAL2=$(FunctionDuration "$B")
        echo "working on $A --> $B"
        sed -i "s/$i/$VAL1 --> $VAL2/" "$FILE"
done
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :