Comment convertir le file .txt sous-titré au format .srt?

J'ai un file de sous-titres, ça ressemble à ceci:

00:00:44:" Myślę, więc jestem".|Kartezjusz, 1596-1650 00:01:01:Trzynaste Pietro 00:01:06:Podobno niewiedza uszczęśliwia. 00:01:10:Po raz pierwszy w życiu|zgadzam się z tym. 00:01:13:Wolałbym... 00:01:15:nigdy nie odkryć|tej straszliwej prawdy. 00:01:19:Teraz już wiem... 

Je ne suis pas sûr de ce format, mais je voulais convertir les sous-titres en .srt. Malheureusement, gnome-subtitles et subtitleeditor ne peuvent pas reconnaître ce type de format.

gnome-subtitles dit:

Impossible de détecter le format des sous-titres. Veuillez vérifier que le type de file est pris en charge.

subtitleeditor dit:

Veuillez vérifier que le file contient des sous-titres dans un format pris en charge.

sortie du file :

 UTF-8 Unicode text 

Existe-t-il un moyen de convertir ce file au format .srt?

Ceci est très similaire à l'approche de @ goldilock mais, IMO, plus simple et peut traiter les lignes vides dans le file et remplace | avec un saut de ligne:

 #!/usr/bin/env perl my ($time, $text, $next_time, $next_text); my ($c,$i)=0; while (<>) { ## skip bad lines next unless /^\s*([:\d]+)\s*:(.+)/; ## If this is the first line. I could have used $. but this is ## safer in case the file contains an empty line at the beginning. if ($c == 0) { $time=$1; $text=$2; $c++; } else { ## This is the counter for the subtitle index $i++; ## Save the current values $next_time=$1; $next_text=$2; ## I am assuming that the | should be interpreted ## as a newline, remove this if I'm wrong. $text=~s/\|/\n/g; ## Print the previous subttitle print "$i\n$time,100 --> $next_time,000\n$text\n\n"; ## Save the current one for the next line $time=$next_time; $text=$next_text; } } ## Print the last subtitle. It will be dislayed for a minute ## 'cause I'm lazy. $i++; $time=~/(\d+:)(\d+)(:\d+)/; my $newtime=$1 . (sprintf "%02d", $2+1) . $3; print "$i\n$time,100 --> $newtime,000\n$text\n\n"; 

Enregistrez le script en tant que file et faites-le exécutable, puis exécutez:

 ./script.pl subfile > good_subs.srt 

La sortie que je reçois sur votre échantillon était:

 1 00:00:44,100 --> 00:01:01,000 " Myślę, więc jestem". Kartezjusz, 1596-1650 2 00:01:01,100 --> 00:01:06,000 Trzynaste Pietro 3 00:01:06,100 --> 00:01:10,000 Podobno niewiedza uszczęśliwia. 4 00:01:10,100 --> 00:01:13,000 Po raz pierwszy w życiu zgadzam się z tym. 5 00:01:13,100 --> 00:01:15,000 Wolałbym... 6 00:01:15,100 --> 00:01:19,000 nigdy nie odkryć tej straszliwej prawdy. 7 00:01:19,100 --> 00:02:19,000 Teraz już wiem... 

Ce que Thorsten voulait dire, c'est quelque chose comme ça:

 #!/usr/bin/perl use ssortingct; use warnings FATAL => qw(all); my $END = '!!ZZ_END'; my $LastTitleDuration = 5; my $count = 1; my $line = <STDIN>; chomp $line; my $next = <STDIN>; while ($line) { $next = lastSubtitle($line) if !$next; last if !$next; chomp $next; if (!($next =~ m/^\d\d:\d\d:\d\d:.+/)) { print STDERR 'Skipping bad data at line '.($count+1).":\n$line\n"; $next = <STDIN>; next; } printf STDOUT "%d\r\n%s,100 --> %s,000\r\n%s\r\n\r\n", $count++, substr($line, 0, 8), substr($next, 0, 8), substr($line, 9) ; } continue { $line = $next; $next = <STDIN>; } sub lastSubtitle { my $line = shift; $line =~ /^(\d\d:\d\d:)(\d\d):(.+)/; return 0 if $3 eq $END; return sprintf("$1%2d:$END", $2 + $LastTitleDuration); } 

Quand je nourris vos données d'échantillon dans ceci, j'obtiens:

 1 00:00:44,100 --> 00:01:01,000 " Myślę, więc jestem".|Kartezjusz, 1596-1650 2 00:01:01,100 --> 00:01:06,000 Trzynaste Pietro 3 00:01:06,100 --> 00:01:10,000 Podobno niewiedza uszczęśliwia. 4 00:01:10,100 --> 00:01:13,000 Po raz pierwszy w życiu|zgadzam się z tym. 5 00:01:13,100 --> 00:01:15,000 Wolałbym... 6 00:01:15,100 --> 00:01:19,000 nigdy nie odkryć|tej straszliwej prawdy. 7 00:01:19,100 --> 00:01:24,000 Teraz już wiem... 

Couple de points:

  • Les sous-titres commencent en fait 1 / 10ème de seconde, donc ils ne se chevauchent pas, et parce que j'étais trop paresseux pour append quelques calculs impliquant le deuxième horodatage. Ils restnt ensuite jusqu'à 1 / 10ème de seconde avant le prochain titre.

  • Le dernier titre rest $LastTitleDuration pour $LastTitleDuration (5 secondes).

  • J'ai utilisé les fins de ligne CRLF selon l' article de wikipedia de SupRip bien que cela ne soit pas nécessairement nécessaire.

  • Cela suppose que la première ligne d'input n'est pas mal formée. Au-delà, ils sont vérifiés et les erreurs sont signalées à stdout, donc:

     readAlongToSRT.pl < readAlong.txt > whatever.srt 

    Devrait créer le file mais encore imprimer des erreurs à l'écran.

  • Le traitement s'arrêtera sur une ligne vierge.

  • Voir le commentaire de Terdon ci-dessous concernant la signification possible de | dans le contenu des sous-titres. Vous voudrez peut-être insert $line =~ s/|/\r\n/g; avant la ligne printf STDOUT .

Cela m'a pris 20 minutes et les seudatatables de test que j'ai eues étaient ces 7 lignes, donc ne countz pas sur cela étant parfait. S'il y a des sauts de ligne dans les sous-titres , cela causera un problème. Je présume qu'il n'y en a pas; si c'est le cas, je vous suggère de les supprimer de l'input en premier plutôt que d'essayer de les traiter ici.