Skip to content

Comment annoter des sous-titres YouTube

Comment télécharger des sous-titres avec yt-dlp et les annoter dans Potato, ce que permettent ou non les sous-titres automatiques, comment gérer la vidéo et ce qu'il faut vérifier avant de rediffuser des médias.

Téléchargez les sous-titres avec yt-dlp et pointez Potato vers les fichiers. À savoir d'abord : les sous-titres générés automatiquement n'ont ni ponctuation ni étiquettes de locuteur, et leurs retours à la ligne ne veulent rien dire, ce qui limite ce que vous pouvez annoter de façon sensée. Potato lit tous les formats de sous-titres produits par yt-dlp. Voir Formats de transcription pour la liste complète.

Les plateformes vidéo sont une source vaste et commode de parole naturelle. Le sous-titrage transforme cette parole en texte, et le texte est léger, facile à déplacer et facile à annoter. Le hic, c'est que tous les sous-titres ne sont pas le même type d'objet, et les traiter comme s'ils l'étaient est ce qui fait dérailler la plupart des projets d'annotation sur sous-titres.

Comment télécharger les sous-titres ?

yt-dlp récupère les sous-titres avec ou sans le média :

bash
# Human-written subtitles, if the uploader provided any
yt-dlp --write-subs --sub-langs en --skip-download <URL>
 
# Auto-generated captions
yt-dlp --write-auto-subs --sub-langs en --sub-format vtt --skip-download <URL>

Potato lit vtt, srt, json3, ttml ainsi que les variantes srv1, srv2 et srv3, donc le --sub-format que vous choisirez sera analysé correctement. Choisissez selon ce que vous voulez conserver : json3 garde les temps par mot, tandis que WebVTT et SubRip sont plus faciles à lire et à modifier à la main.

Quelle différence entre sous-titres humains et sous-titres automatiques ?

Dans un éditeur de texte ils se ressemblent, et comme matière à annoter ils se comportent très différemment :

Sous-titres humainsSous-titres automatiques
PonctuationOuiNon, ou peu fiable
Frontières de phraseSignificativesArbitraires
LocuteursParfois, via des balises <v Name>Jamais
Temps par motNonOui, dans json3
Fidélité littéraleSouvent condensés pour la lecturePlus proches de ce qui a été dit

Aucun des deux n'est meilleur dans l'absolu. Les sous-titres humains se lisent bien mais sont retouchés pour la lisibilité : ils suppriment les hésitations, compriment les répétitions et réécrivent parfois une phrase entière. Les sous-titres automatiques sont plus proches du littéral, ce que vous voulez pour tout ce qui touche à la façon dont les gens parlent vraiment, mais ils arrivent sous forme de flux non ponctué.

Que puis-je annoter sur des sous-titres automatiques ?

Ne concevez pas un schéma d'annotation au niveau de la phrase sur des sous-titres automatiques. Leurs frontières de bloc tombent là où la fenêtre de sous-titre s'est remplie, pas là où une phrase s'est terminée. Un bloc dans un fichier de sous-titres automatiques est un artefact d'affichage, pas une unité linguistique. Demandez à des annotateurs de juger des phrases et chacun choisira en silence des frontières différentes, et vos chiffres d'accord finiront par mesurer cela plutôt que ce qui vous intéressait.

Deux options praticables :

  • Annotez les blocs de sous-titre tels quels. Étiquetez chaque bloc avec ce qui s'y applique, en acceptant que l'unité soit arbitraire mais constante. Cela convient pour le thème, la présence d'un phénomène, ou tout ce qui se juge sur un fragment.
  • Resegmentez en amont. Passez un modèle de restauration de ponctuation ou un système de reconnaissance vocale qui ponctue, puis réalignez. Plus de travail, mais vous obtenez de vraies unités.

Avec des sous-titres humains, le problème disparaît en grande partie. Les frontières ont été posées par quelqu'un qui lisait, donc elles respectent en général les propositions.

Et la vidéo ?

Les sous-titres sont légers et faciles à rediffuser. La vidéo, en général, non. Trois options :

bash
# Media hosted somewhere your annotators can reach
potato transcripts ./captions --media-url-prefix https://cdn.example.org/video -o data/talks.json
 
# Media downloaded locally as audio only
yt-dlp -f 'ba' -x --audio-format mp3 -o './audio/%(id)s.%(ext)s' <URL>
potato transcripts ./captions --media-dir ./audio -o data/talks.json

La troisième option consiste à n'avoir aucun média. Les transcriptions sans média s'annotent très bien ; les annotateurs lisent au lieu d'écouter. Si c'est votre plan, dites-le dans les consignes, sinon les annotateurs supposeront que l'absence de lecteur est un bug et le signaleront comme tel.

Warning: Vérifiez vos droits avant de rediffuser quoi que ce soit que vous n'avez pas créé. Télécharger des sous-titres ou des médias pour votre propre recherche est une question différente de servir ces médias à un groupe d'annotateurs, et les conditions de la plateforme, le droit d'auteur et les règles de votre institution entrent tous en jeu. Réglez cela avant de construire le pipeline, pas après.

Comment monter la tâche ?

Le convertisseur écrit un fichier de données avec la transcription déjà normalisée :

bash
potato transcripts ./captions --media-dir ./audio -o data/talks.json
json
{
  "id": "talk_01",
  "conversation": {
    "audio": "audio/talk_01.mp3",
    "turns": [
      {"turn_id": "t0", "speaker": null, "start": 0.0, "end": 4.2,
       "text": "so the thing about caption windows is"}
    ]
  }
}

speaker: null est ce que donne un sous-titre automatique. Ces tours apparaissent comme Unassigned avec un sélecteur, pour que les annotateurs les attribuent pendant qu'ils écoutent.

Trois tours de sous-titres automatiques sur fond gris hachuré, étiquetés Unassigned avec une flèche de menu déroulant et une question rattachée à chaque tour.Les sous-titres automatiques ne portent aucun locuteur, donc chaque bloc reste Unassigned jusqu'à ce qu'un annotateur en choisisse un

yaml
annotation_task_name: "Talk Annotation"
task_dir: .
data_files:
  - data/talks.json
 
item_properties:
  id_key: id
  text_key: conversation
 
instance_display:
  fields:
    - key: conversation
      type: audio_dialogue
      label: "Captions"
      span_target: true
      display_options:
        show_timestamps: true
        allow_speaker_assignment: auto
 
annotation_schemes:
  - annotation_type: radio
    name: cue_topic
    description: "What is this caption window about?"
    labels: [setup, argument, example, aside]
    turn_level: true
    turn_binding:
      field: conversation

turn_level: true rattache la question à chaque bloc plutôt qu'à la vidéo entière, ce qui est la bonne unité quand les blocs sont tout ce dont vous disposez. Lancez-la :

bash
python potato/flask_server.py start config.yaml -p 8000

Vous pouvez aussi vous passer entièrement du convertisseur et faire pointer un fichier de données vers les fichiers de sous-titres sur le disque. Voir Comment annoter des transcriptions Whisper, où le reste du flux est identique.

Pour aller plus loin