Mes notes concernant l’extraction et la conversion des sous-titre d’un DVD en VOBSUB et ASS.
Sources :
- format ASS sur wikipedia
- spécification du format ASS en ligne
- page du wiki ubuntu que j’ai écrite il y a quelques années
- mail décrivant les étapes de la procédure
Pour plus de simplicité je fais une copie iso du DVD sur mon disque dure.
Cette étape n’est pas nécessaire, on peut trés bien travailler directement sur /dev/sr0
.
Sélection de la piste
Un DVD contient plusieurs titres, nous devons choisir le bon (le film).
Pour lire le titre n°1 d’un DVD
max@laptop % mpv dvd://1 --dvd-device DVD.iso
max@laptop % mpv dvdread://1 --dvd-device DVD.iso
dvd
(anciennement appelé dvdnav
) et dvdread
sont deux implémentations différentes.
dvd
peut passer automatiquement d’un titre à l’autre.
Le support de dvd://menu
a été supprimé des version récente de mpv.
Il est possible de connaitre le titre actuellement joué via dvd
en observant la sortie standard.
DVDNAV, switched to title: 23
indique que je suis en train de lire le titre 23.
Pour lister les titres d’un DVD on peut utiliser lsdvd
:
max@laptop % lsdvd DVD.iso
libdvdread: Encrypted DVD support unavailable.
Disc Title: …
Title: 01, Length: 00:00:37.080 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 00
Title: 02, Length: 00:24:34.760 Chapters: 06, Cells: 06, Audio streams: 05, Subpictures: 02
…
Longest track: 09
max@laptop % lsdvd -t 02 -x DVD.iso
libdvdread: Encrypted DVD support unavailable.
Disc Title: …
Title: 02, Length: 00:24:34.760 Chapters: 06, Cells: 06, Audio streams: 05, Subpictures: 02
VTS: 02, TTN: 01, FPS: 25.00, Format: PAL, Aspect ratio: 16/9, Width: 720, Height: 576, DF: Letterbox
Palette: 108080 2b8080 eb8080 51ef5a 7d8080 b48080 a910a5 6addca d29210 1c76b8 50505a 30b86d 5d4792 3dafa5 718947 eb8080
Number of Angles: 1
Audio: 1, Language: fr - Francais, Format: ac3, Frequency: 48000, Quantization: drc, Channels: 6,AP: 0, Content: Undefined, Stream id: 0x80
…
Audio: 5, Language: en - English, Format: ac3, Frequency: 48000, Quantization: drc, Channels: 2, AP: 0, Content: Undefined, Stream id: 0x84
Chapter: 01, Length: 00:01:40.320, Start Cell: 01
…
Chapter: 06, Length: 00:00:00.480, Start Cell: 06
Cell: 01, Length: 00:01:40.320
…
Cell: 06, Length: 00:00:00.480
Subtitle: 01, Language: fr - Francais, Content: Undefined, Stream id: 0x20,
Subtitle: 02, Language: xx - Unknown, Content: Undefined, Stream id: 0x21,
Attention : j’ai eu des surprise avec certains DVD, j’indiquais à mpv
de lire un certain titre et il en prenait un autre.
Dans ce cas j’y vais à taton, je testes les titres jusqu’à trouver le bon.
ISO → VOB
Une fois qu’on déterminé le bon titre (ici 02) on l’extrait sous forme de VOB.
max@laptop % mpv dvdread://02 --dvd-device DVD.iso --stream-dump=titre01.vob
Playing: dvdread://02
libdvdread: Encrypted DVD support unavailable.
[dvd] There are 20 titles on this DVD.
[dvd] There are 1 angles in this DVD title.
[dvd] audio stream: 0 format: ac3 (5.1) language: fr aid: 128.
[dvd] audio stream: 1 format: ac3 (5.1) language: ja aid: 129.
[dvd] audio stream: 2 format: ac3 (stereo) language: fr aid: 130.
[dvd] audio stream: 3 format: ac3 (stereo) language: ja aid: 131.
[dvd] audio stream: 4 format: ac3 (stereo) language: en aid: 132.
[dvd] number of audio channels on disk: 5.
[dvd] subtitle ( sid ): 0 language: fr
[dvd] subtitle ( sid ): 1 language: unknown
[dvd] number of subtitles on disk: 2
[dvd] CHAPTERS: 00:00:00.000,00:01:40.320,00:09:55.040,00:22:17.360,00:23:44.120,
…
Les méta données seront perdues c’est pourquoi je les affiches ici (il faut les conserver).
On peut aussi utiliser dvd
mais je le déconseille car plusieurs titres peuvent s’enchainer.
max@laptop % mpv dvd://02 --dvd-device DVD.iso --stream-dump titre01.vob
…
libdvdnav: DVD disk reports itself with Region mask 0x00000000. Regions: 1 2 3 4 5 6 7 8
[dvdnav] DVDNAV, switched to title: 23
Dumping 1409284096/0...
[dvdnav] DVDNAV, switched to title: 1
Dumping 1465001984/0...
…
IFO
Il peut être interessant de sauvegarder le fichier ifo correspondant à votre titre/piste. Celui-ci contient notamment la couleur des sous-titres.
Pour déterminer le bon VTS j’utilise lsdvd :
max@laptop % lsdvd -t 02 -v DVD.iso
libdvdread: Encrypted DVD support unavailable.
Disc Title: …
Title: 02, Length: 00:24:34.760 Chapters: 06, Cells: 06, Audio streams: 05, Subpictures: 02
VTS: 02, TTN: 01, FPS: 25.00, Format: PAL, Aspect ratio: 16/9, Width: 720, Height: 576, DF: Letterbox
Ici « VTS: 02 » donc le fichier IFO est VIDEO_TS/VTS_02_0.IFO
.
max@laptop % mkdir /tmp/dvd
max@laptop % sudo mount -o loop DVD.iso /tmp/dvd
mount: /dev/loop0 est protégé en écriture, sera monté en lecture seule
max@laptop % cp /tmp/dvd/VIDEO_TS/VTS_02_0.IFO titre01.ifo
Sources :
VOB → PS1
Je veux extraire les sous-titres français, je sais qu’il s’agit du premier flux de sous-titre du VOB.
[dvd] number of audio channels on disk: 6.
[dvd] subtitle ( sid ): 0 language: fr
[dvd] subtitle ( sid ): 1 language: unknown
[dvd] number of subtitles on disk: 2
J’utilise ffmpeg
pour déterminer sa référence.
max@laptop % ffprobe titre01.vob
…
Input #0, mpeg, from 'titre01.vob':
Duration: 00:26:00.52, start: 0.280000, bitrate: 7229 kb/s
Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv), 720x576 [SAR 16:15 DAR 4:3], max. 8199 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
Stream #0:1[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream #0:2[0x82]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream #0:3[0x84]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream #0:4[0x81]: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
Stream #0:5[0x83]: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
Stream #0:6[0x85]: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
Stream #0:7[0x20]: Subtitle: dvd_subtitle
Stream #0:8[0x21]: Subtitle: dvd_subtitle
At least one output file must be specified
Ici sa référence est « 0x20 » (premier flux de sous-titre).
Je l’extrais via tcextract
(paquet « transcode » sous Archlinux).
max@laptop % tcextract -i titre01.vob -t vob -x ps1 -a 0x20 > titre01_subtitle_fr.ps1
PS1 → VOBSUB
Dans le format VOBSUB les sous-titre sont stoqué sous forme d’image. Cette technique est donc beaucoup plus simple est rapide que la création de fichier ASS.
Avec le fichier ifo :
max@laptop % subtitle2vobsub -p titre01_subtitle_fr.ps1 -i titre01.ifo -o titre01_subtitle_fr
Sans fichier ifo, subtitle2vobsub utilise des paramètre par défaut (qu’il est possible de surcharger, je n’ai pas réussi à faire fonctionner -c correctement) :
max@laptop % subtitle2vobsub -p titre01_subtitle_fr.ps1 -o titre01_subtitle_fr -s 720x576 -a 0,fr
Je change la palette par défaut (immonde) par celle donnée en exemple par matroska :
max@laptop % sed -i 's/^palette: .*/palette: 000000, 7e7e7e, fbff8b, cb86f1, 7f74b8, e23f06, 0a48ea, b3d65a, 6b92f1, 87f087, c02081, f8d0f4, e3c411, 382201, e8840b, fdfdfd/' titre01_subtitle_fr.idx
PS1 → ASS
Les sous-titre sont stoqué en temps qu’image dans le fichier PS1. Pour créé notre fichier ASS nous allons devoir passer toutes ces images dans un OCR.
PS1 → PGM
J’extrais ensuite les sous-titres sous forme d’images.
max@laptop % subtitle2pgm -i titre01_subtitle_fr.ps1 -C 0 -c 255,0,255,255
-C 0
permet de détourer les images-c x,y,z,t
niveau de gris à appliquer à chaque partie des images- 255 = blanc
- 0 = noir
- x : contour des caractères
- y : caractères
- z : fond
- t : je ne sais pas, peut-être le canal alpha…
subtitle2pgm
créé aussi un fichier d’index movie_subtitle.srtx
qui servira de base à la création du srt.
Si les images vous paraisse moches (difficilement exploitable par un OCR) vous pouvez faire plusieurs tests en faisant varier les niveaux de gris :
max@laptop % subtitle2pgm -e 00:00:00,5 -i titre01_subtitle_fr.ps1 -C 0 -c 255,0,0,0
PGM → TXT
Nous transformons ensuite chaque images en texte via l’OCR tesseract.
max@laptop % for i in *.pgm
do
tesseract $i $i -l fra -psm 6
done
-l fra
considère que le texte est en français-psm 6
considère que le texte est sous forme d’un bloque uniforme
Il est aussi possible d’utiliser pgm2txt
qui utilise gocr mais je trouve que les résultats sont beaucoup moins bon.
TXT → SRT
On fusionne tous le fichier srtx
et txt
pour créer un srt.
max@laptop % srttool -s -w -i movie_subtitle.srtx -o titre01_subtitle_fr.srt
-s
dans le fichier source, remplace toutes les références à des fichiers par leur contenu (indique que le fichier source est un fichier d’index)-w
supprime les espaces blancs-i
fichier source-o
fichier de sortie
Corrections
On corrige les fautes les plus importante avec vim
.
Voici les commande vim
que je lance habituellement :
:%s/\.7/?/gc
:%s/\/\//Il/gc
:%s/\//l/gc
:%s/\//I/gc
:%s/||/Il/gc
:%s/|/l/gc
:%s/|/I/gc
:%s/a‘/à/gc
:%s/— /-/gc
:%s/—/-/g
:%s/\(.\)- /\1-/gc
:%s/’/'/g
:%s/”/"/g
:%s/0\([a-zA-Z]\)/O\1/gc
:%s/ 7/ ?/gc
En touche final on passe un correcteur orthographique.
max@laptop % aspell check -l fr --home-dir=. titre01_subtitle_fr.srt
check
correction orthographique-l fr
utilise le dictionnaire français--home-dir=.
sauvegarde le dictionnaire personnel (.aspell.fr.pws
) et les remplacement (.aspell.fr.prepl
) dans le répertoire courant plutôt que dans le$HOME
de l’utilisateur
Les différentes commande lors de la correction :
- « Ignorer » ignorer une fois
- « Ignorer tout » ignorer toutes les occurrences
- « Remplacer » remplace l’occurrence par un texte donné par l’utilisateur
- « Remplacer tout » remplace toutes les occurrences par un texte donné par l’utilisateur
- « Ajouter » ajouter le mot dans le dictionnaire personnel
- « Ajouter minus. » ajouter le mot en minuscule dans le dictionnaire personnel.
Le fait d’ajouter le mot en minuscule permet de considérer le mot comme correcte lorsque
- il est en minuscule
- le première caractère est en majuscule
- tous les caractères sont en majuscule
- « Abandon » arrête la correction et abandonne toutes les modifications faites précédemment
- « Sortir » arrête la correction en conservant toutes les modifications faites précédemment
SRT → ASS
On converti ensuite le srt
en ASS.
max@laptop % ffmpeg -i titre01_subtitle_fr.{srt,ass}
Personnellement je remplace le style utilisé par ffmpeg
par mon propre style.
max@laptop % sed -i 's/Style: Default.*/Style: Default,DejaVu Sans,24,\&H0000FFFF,\&H00FFFFFF,\&H00000000,\&H00FFFFFF,0,0,0,0,100,100,0,0,1,2,0,2,20,20,20,0/' titre01_subtitle_fr.ass
Le format de style utilisé dans les fichiers ASS est, dans l’ordre d’apparition :
- nom du style (Default)
- police de caractère à utiliser (DejaVu Sans)
- taille de la police (24)
- couleur du texte (&H0000FFFF → jaune)
- je ne sais pas (&H00FFFFFF → blanc)
- couleur du contour des caractères ou de la boite de fond (&H00000000 → noir)
- couleur de l’ombre des caractères (&H00FFFFFF → blanc)
- caractères gras (0 → non)
- caractères italic (0 → non)
- texte souligné (0 → non)
- texte barré (0 → non)
- modifie la taille horizontal de la police en % (100 → taille normal)
- modifie la taille vertical de la police en % (100 → taille normal)
- ajout de pixels supplémentaires entre les caractères (0 pixels)
- angle de rotation du texte par rapport à l’horizontal (0 degrés d’angle)
- « BorderStyle » (1)
- 1 = contour + ombre
- 3 = boite
- taille du contour entre 0 et 4 pixels (2 pixels)
- taille de l’ombre entre 0 et 4 pixels (0 pixels)
- placement du texte (2)
- 1 = gauche
- 2 = centré
- 3 = droite
- +4 = haut (par exemple, 5 = 1 + 4 = en haut à gauche)
- +8 = centre vertical
- marge de gauche en pixels (20)
- marge de droite en pixels (20)
- marge horizontale, haut ou bas, en pixels (20)
- encodage du texte (0 pour de l’ASCII)… je met de l’UTF8 et ça passe très bien.
On peut rendre plus ou moin transparente une couleur en modifiant son premier octet, c’est à dire les deux premier caractères qui suivent le « &H ». Ici aucune des couleurs n’a de transparence, elles sont complètement opaques ; leur premier octet est « 00 » (e.g. &H00FFFFFF, &H0000FFFF…). Pour rendre une couleur complètement transparente (je vois pas trop l’intérêt… mais bon) indiquez « FF » (e.g. &HFFFFFFFF, &HFF00FFFF…). Personnellement je me sers parfois de cette fonctionnalité pour mettre mes sous-titres dans des boites (paramètre n°16 à 3) noire légèrement transparentes (paramètre n°6 à &H50000000).
max@laptop % sed -i 's/Style: Default.*/Style: Default,DejaVu Sans,24,\&H0000FFFF,\&H00FFFFFF,\&H50000000,\&H00FFFFFF,0,0,0,0,100,100,0,0,3,2,0,2,20,20,20,0/' titre01_subtitle_fr.ass
Les paramètres ASS « PlayResX » et « PlayResY » sont important pour le rendu des sous-titre, ils définissent la taille/résolution de la fenêtre d’affichage de la vidéo de celui qui à écrit le sous-titre. La taille des caractères affichés et tous les autres paramètre de style correspondant à des pixels, sont calculer en fonction de la taille de la fenêtre d’affichage de la vidéo et de ces paramètres, pas de la résolution de la vidéo ou de l’écran. Par exemple, si on fixe PlaxResY à 100 et une taille de police de 50, un caractère recouvrira en hauteur la moitié de la vidéo. Par défaut lors de la conversion d’un SRT en ASS, ffmpeg fixe PlayRedX et PlayResY à 384x288.
Lors de la conversion de sous-titre SRT en ASS vous pourrez tomber sur l’erreur suivante :
Invalid UTF-8 in decoded subtitles text; maybe missing -sub_charenc option
Pour résoudre se problème il suffit d’indiqué à ffmpeg l’encodage du fichier SRT, pour le français il s’agit généralement de CP1252.
max@laptop % ffmpeg -sub_charenc cp1252 -i French.srt French.ass
HS sub_charenc
Une petite note hors sujet concernant -sub_charenc
.
mpv peut aussi indiquer l’erreur suivante :
[ffmpeg] mov_text: Invalid UTF-8 in decoded subtitles text; maybe missing -sub_charenc option
[sub/ass] Error decoding subtitle
-sub_charenc
n’est pas une option reconnue par mpv.
À la place vous pouvez essayer --sub-codepage
(eg. --sub-codepage=+cp1252
), mais personnellement ça n’a pas fonctionné.
Décallage sous-titre ↔ son
Si le sous-titre ne colle pas parfaitement à l’image vous pouvez les décaller facilement avec ffmpeg
.
Dans la commande suivante j’opère un décalage de 500 millisecondes (les sous-titres étaient en retard).
max@laptop % ffmpeg -itsoffset '-0.5' -y -i titre01_subtitle_fr.ass titre01_subtitle_fr.ass