summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorache <ache@ache.one>2023-12-19 06:19:30 +0100
committerache <ache@ache.one>2023-12-19 06:19:30 +0100
commit71f6f99b8f61d530134a210ceb9410edb9808602 (patch)
tree937c60d306c5756ab7d943505ae0729fbfd29c93
parentDisalow ressources directory to web crawlers (diff)
Publish article about train
-rw-r--r--articles/les-trains-et-la-publicité.md428
-rw-r--r--articles/rail-and-advertising.md409
-rw-r--r--articles/res/DB-ad-The_client-de.vtt47
-rw-r--r--articles/res/DB-ad-The_client-en.vtt46
-rw-r--r--articles/res/DB-ad-The_client-fr.vtt46
-rw-r--r--articles/res/DB-ad-The_client_poster.pngbin0 -> 1026651 bytes
-rw-r--r--articles/res/JR_West-ads-Summer_Train-ai_en.vtt23
-rw-r--r--articles/res/JR_West-ads-Summer_Train-ai_fr.vtt23
-rw-r--r--articles/res/JR_West-ads-Summer_Train-gt_en.vtt23
-rw-r--r--articles/res/JR_West-ads-Summer_Train-gt_fr.vtt23
-rw-r--r--articles/res/JR_West-ads-Summer_Train-ja.vtt23
-rw-r--r--articles/res/JR_West-ads-Summer_Train_poster.pngbin0 -> 1046048 bytes
-rw-r--r--articles/res/LDz_ads_railway-safety_poster.pngbin0 -> 426527 bytes
-rw-r--r--articles/res/SNCF-ad-Hexagonal-en.vtt118
-rw-r--r--articles/res/SNCF-ad-Hexagonal-fr.vtt121
-rw-r--r--articles/res/SNCF-ad-Hexagonal_poster.pngbin0 -> 702597 bytes
-rw-r--r--articles/res/train-speed-inv.svg83
-rw-r--r--articles/res/train-speed-v1.svg59
-rw-r--r--articles/res/train-speed-v2.svg108
-rw-r--r--src/build/i18n.mjs2
20 files changed, 1582 insertions, 0 deletions
diff --git a/articles/les-trains-et-la-publicité.md b/articles/les-trains-et-la-publicité.md
new file mode 100644
index 0000000..3afa67f
--- /dev/null
+++ b/articles/les-trains-et-la-publicité.md
@@ -0,0 +1,428 @@
+---
+
+pubDate = 2023-11-16 13:34:00Z
+tags = ['train', 'publicité', 'IA']
+
+[author]
+name = "ache"
+email = "ache@ache.one"
+
+[[alt_lang]]
+lang = "en"
+url = "/articles/rail-and-advertising"
+
+---
+
+La publicité pour les trains
+===========================
+
+
+![Illustration d'un train qui roule vite.](res/train-speed-inv.svg)
+Parlons trains. Enfin pub.
+Enfin vous verez bien !
+L'idée est d'analyser quelques publicités pour des trains à travers le monde.
+Mais c'est surtout un prétexte pour vous présenter l'utilisation de technologies d'intelligence artificielle récentes. 🤖
+
+
+Sommaire
+----------
+
+
+:::question
+Pourquoi des pubs pour le train ?
+:::
+
+Déjà pourquoi pas ?
+Ensuite, parce que j'aime analyser la construction et la mise en scène des films.
+Ici on va prendre des publicités, car je ne vais pas analyser un film entier avant de vous parler d'IA.
+
+
+## Une publicité japonaise
+
+Ce petit clip de 15s a été créé par le studio Ponoc.
+Cette publicité est une commande de JR West, l'une des grosses compagnies ferroviaires japonaises.
+
+<video controls class="big" preload=none poster="res/JR_West-ads-Summer_Train_poster.png">
+ <source src="res/JR_West-ads-Summer_Train.webm" type="video/webm" />
+ <track kind="captions" srclang="jp" src="res/JR_West-ads-Summer_Train-ja.vtt" default label="日本語"/>
+ <track kind="subtitles" srclang="fr" src="res/JR_West-ads-Summer_Train-ai_fr.vtt" label="Français (IA)"/>
+ <track kind="subtitles" srclang="en" src="res/JR_West-ads-Summer_Train-ai_en.vtt" label="English (AI)"/>
+ <track kind="subtitles" srclang="fr" src="res/JR_West-ads-Summer_Train-gt_fr.vtt" label="Français"/>
+ <track kind="subtitles" srclang="en" src="res/JR_West-ads-Summer_Train-gt_en.vtt" label="English"/>
+</video>
+
+Dans un style d'animation japonais, l'histoire nous dépeint une famille partant en vacances dans l'ouest du Japon.
+L'accent est mis sur le jeune garçon qui est tout d'abord réticent puis qui progressivement s'épanouit avec sa famille.
+
+Sa réticence est en contraste avec l'excitation ambiante de la famille.
+Il est silencieux et peu mobile alors que le reste de la famille bouge beaucoup et tout le monde parle en même temps.
+Son changement d'avis sur ce voyage est traduit par son sourire qui passe d'une moue intense à des éclats de joie lorsqu'il découvre la mer.
+
+Le public visé est la famille en général, pas spécialement les enfants.
+Ici la publicité est une mise en scène très habile des souvenirs de vacances et de la nostalgie.
+On y voit de très nombreuses références à la réalité comme le Shinkansen série N700 ou la gare Shin-Ōsaka qui est tout à fait reconnaissable.
+En particulier, on voit et entend une cigale japonaise, véritable symbole de l'été au japon.
+
+Bref, publicité qui réussi à faire passer un message et parle à son public.
+
+En parlant de publicité qui parle à son public ...
+Voyons une publicité d'outre-Rhin.
+
+
+## Der Volksgeist (L'esprit du peuple)
+
+Cette publicité, mini-film, a été commandée par la Deutsch Bahn[^db] et réalisée par [Pantera](https://bwgtbld.tv/pantera/).
+Elle décrit de manière humoristique une jeune femme partant en voyage d'affaires et qui se fait _harceler_ par sa cliente.
+
+<video controls class="big" preload=none poster="res/DB-ad-The_client_poster.png">
+ <source src="res/DB-ad-The_client.webm" type="video/webm"/>
+ <track kind="captions" srclang="de" src="res/DB-ad-The_client-de.vtt" default label="Deutsch"/>
+ <track kind="subtitles" srclang="fr" src="res/DB-ad-The_client-fr.vtt" label="Français"/>
+ <track kind="subtitles" srclang="en" src="res/DB-ad-The_client-en.vtt" label="English"/>
+</video>
+
+[^db]: Que l'on pourrait traduit par « Réseau ferré allemand ».
+
+La publicité insiste sur **la tranquillité et le confort du voyage en train** en la mettant en contraste avec la vigilance et le stress inhérent à la conduite d'une voiture.
+
+L'humour est typiquement allemand et se base sur le comique de répétition du client insistant.
+Les éléments clés de cet humour sont la répétition de la phrase « Frau Fischer » et la mise en scène du client qui essaye de joindre cette M<sup>me</sup> Fischer par des moyens toujours plus improbables les uns que les autres.
+
+Dans cette mise en scène absurde, le son joue un rôle aussi important que l'image.
+Les effets sonores sont très bien sélectionnés et sont mis en exergue par l'utilisation d'une musique de fond style symphonie classique, tout en appuyant l'histoire.
+
+Dans une interprétation plus réaliste de l'histoire, M<sup>me</sup> Mueller (la cliente) n'apparait pas par magie dans la voiture de M<sup>me</sup> Fischer.
+C'est en fait une personnification du stress de M<sup>me</sup> Fischer tout droit sortie de son imagination.
+La disparition de ces hallucinations traduit ainsi la disparition du stress de M<sup>me</sup> Fischer, sereine, car elle a pris le train.
+
+Je vous épargne une description précise de chaque plan, mais chaque élément est sélectionné et peu de choses sont laissés au hasard.
+
+Sont visés par cette publicité les personnes effectuant des déplacements professionnels.
+Une classe de personne assez réduite donc.
+Il n'est pas question ici de faire l'ombre de manière générale à la voiture, cœur de l'industrie allemande. 🙄
+Le ou la réalisateur⋅trice Pantera a d'ailleurs ensuite réalisé plusieurs publicités pour la marque de voiture Mercedez Benz.
+
+Ses autres talentueuses réalisations sont disponibles sur le site [BWGTBLD](https://bwgtbld.tv/).
+
+
+## À la française
+
+Ce mini-film réalisé pour le groupe français SNCF n'est pas vraiment une pub.
+Le but n'est pas de vous vendre quelque chose mais de travailler l'image de la marque et de promouvoir le nouveau slogan de la SNCF « Pour nous tous ».
+
+<video controls class="big" preload=none poster="res/SNCF-ad-Hexagonal_poster.png">
+ <source src="res/SNCF-ad-Hexagonal.webm"/>
+ <track kind="captions" srclang="fr" src="res/SNCF-ad-Hexagonal-fr.vtt" default label="Français"/>
+ <track kind="subtitles" srclang="en" src="res/SNCF-ad-Hexagonal-en.vtt" label="English"/>
+</video>
+
+La vidéo s'articule autour d'un texte en **slam**, chanté par [Gaël Faye](https://fr.wikipedia.org/wiki/Ga%C3%ABl_Faye), et illustrés par de nombreux extraits vidéos très courts et de provenances variées.
+
+Ce clip fait appel à de nombreux références culturelles françaises et a de nombreuses séquences promotionnelles précédentes, parfois très anciennes, de la SNCF.
+Ces séquences, bien que faisant appel à la mémoire du public sont suffisamment peu marquantes pour qu'il soit difficile de se souvenir d'où elles proviennent précisément.
+Le but étant de s'effacer fasse à l'élément clé de ce spot, la chanson.
+
+Rythmée par une quelques notes de piano[^claque], elle décrit la SNCF et ses valeurs.
+On y trouve de nombreux jeux de mots et des figures de styles subtiles.
+Notamment, la SNCF y décrit ses engagements et son caractère humaniste.
+
+[^claque]: Bien que simple, la musique n'est ici pas delessée pour autant.
+Le rythme est calqué et introduit par le bruit ferroviaire.
+Chaque moment qui détonne est accentué par [le sonal signature de la SNCF](https://youtu.be/NA5MwhuHWLo?t=2) qui s'y prête étonnament bien !
+
+Tous les Français sont invités à aimer la SNCF dans cette vidéo fédératrice. 💕
+Paradoxalement, elle rassemble en insistant sur la diversité de la France et renoue ainsi avec un de ses engagements, **supporter la diversité**.
+
+Au fur et à mesure, la vidéo qui décrivait la SNCF décrit de plus en plus les Français même, notamment par l'utilisation du pronom impersonnel « on », ambïgue depuis le début de la vidéo, qui peut désigner autant la SNCF que les Français.
+Par cet amalgame, elle fait appel à la fierté patriotique des citoyens français.
+
+Le lien étant crée, c'est le moment idéal pour la SNCF d'aborder le sujet de ses défauts et de les partager avec son public, puisque ses défauts sont les défauts clichés des Français.
+Ainsi par une certaine empathie on est invité à les excuser, mais pas seulement elle renforce surtout l'idée d'une entreprise française pour les Français, pour la France, « pour nous tous ».
+
+Cette dernière idée est particulièrement mise en avant avec la phrase choc finale « On est pas carré, on est hexagonal ».
+Qui présente ainsi définitivement les faiblesses en qualités à travers un jeu de mot très français.
+
+:::attention
+La SNCF insiste beaucoup sur son caractère humain[^handy] dans cette vidéo. Notamment en présentant dans personnes handicapées dans sont clip.
+
+Je note cependant que malgrès ses efforts et tout comme la DB, la SNCF a du chemin à parcourir au niveau de l'accessibilité.[^handy]
+:::
+
+[^handy]: Par exemple, [le service Accès Plus](https://emeraude.my.site.com/aplus/s/demande-prestation?origin=PKhzh3NUh8) destiné a acompagné les voyageurs, bien que gratuit n'est disponible qu'en français.
+ Aussi, les OuiGo offrent, de manière générale, [un mauvais niveau d'accessibilité](https://www.sncf-voyageurs.com/fr/voyagez-avec-nous/preparez-votre-voyage/accessibilite/equipement-a-bord/).
+
+  
+
+ La volonté de la SNCF de s'améliorer semble lente mais réelle, ainsi le prochain [TGV M](https://fr.wikipedia.org/wiki/TGV_M) annonce être accessibile en complète autonomie. 👍 🚄
+ Si le sujet vous intéresse, ARTE a réalisé un très bon documentaire sur [le militentisme et l'accessibilité](https://www.arte.tv/fr/videos/110252-001-A/arte-regards/) qui parle suscintement de l'accessibilité des trains.
+
+
+## Résumé
+
+Cette étude des publicités montrent que ces clips sont culturellement très riches.
+On remarque que ces groupes n'hésitent pas à investir de l'argent pour se promouvoir, ou qu'en tout cas qu'ils ont de l'expérience dans leur communication.
+Les références sont ancrées dans la culture du pays et je remarque que cela entre en contradiction avec les politiques modernes d'ouverture du marché ferroviaire à la concurrence, notamment étrangère.
+On s'attendrait plus à une communication en anglais par exemple avec des références basées sur [la pop culture](https://fr.wikipedia.org/wiki/Culture_populaire).
+
+Pour finir, sur une note drôle, je vous présente cet ensemble de vidéos de prévention des accidents de la compagnie lettonne LDz.
+
+<video controls class="big"
+ preload=none
+ poster="res/LDz_ads_railway-safety_poster.png">
+ <source src="res/LDz_ads_railway-safety.mp4" type="video/webm; codecs=av01.0.05M.08" />
+ <p>Ensemble de vidéos de la LDz métant en scène les personnages d'Avārijas Brigāde dans de le but de sensibilisé la population à la sureté ferroviaire.</p>
+</video>
+
+
+## Parlons tech
+
+Les sous-titres des vidéos ont été créer à partir d'outils basés sur [de grands modèles de langage](https://fr.wikipedia.org/wiki/Grand_mod%C3%A8le_de_langage) (LLM).
+La vidéo de LDz a été agrandie et est bien plus agréable à regardée que [la version originale](https://youtu.be/f4HtbPt1DCk).
+
+Pour créer cet article, j'ai ainsi utilisé:
+
+ - [yt-dlp](https://github.com/yt-dlp/yt-dlp), un logiciel libre permettant de télécharger des vidéos depuis de nombreux sites, pas seulement youtube.
+ - [Whisper](https://en.wikipedia.org/wiki/Whisper_(speech_recognition_system)): Un modèle d'apprentissage automatisé cette fois-ci dédié à la reconnaissance vocale (S2P pour _Speech to Text_) issue d'OpenAI.
+ - [Seamless](https://github.com/facebookresearch/seamless_communication): Un modèle d'apprentissage automatisé créer par Meta et dédié à la traduction multimodale (Text <=> Text / Audio <=> Text / Audio <=> Audio).
+ - [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN): Un modèle dédié à l'amélioration des images.
+ - [ffmpeg](https://fr.wikipedia.org/wiki/FFmpeg): Le logiciel référence de manipulation des codecs audio.
+
+Je vais passer sur `yt-dlp` et sur `ffmpeg` et me concentrer sur les technologies d'intelligence artificielle.
+
+
+### Whisper
+
+Ok, donc puisque les vidéos ne sont pas forcément dans une langue des lecteurs de ce blog, j'aurais aimé avoir des sous-titres aux vidéos.
+
+J'ai donc cherché à utiliser Whisper qui permet de faire de la reconnaissance vocale.
+J'ai déjà les sous-titres de la vidéo en français, ça tombe bien, c'est une langue que je maîtrise, je vais pouvoir m'en servir pour vérifier la sortie de Whisper.
+
+J'ai créé un container et installer Whisper d'OpenAI directement.
+La qualité des résultats est différente en fonction de la langue.
+
+
+#### Japonais
+
+En japonais, je peux difficilement évaluer le résultat.
+Il me semble cependant que celui-ci est difficilement compréhensible, les phrases sont peu liées entre elles, le sens général n'est pas claire.
+
+:::note
+J'ai également utilisé [insanely-fast-whisper](https://github.com/Vaibhavs10/insanely-fast-whisper) pour retranscrire le japonais.
+
+Je dois admettre que les résultats sont meilleurs et bien plus rapides qu'avec la version de Meta même si ceci ne sont pas au niveau du traitement des langues latines.
+:::
+
+
+#### L'allemand et le français
+
+Pour l'allemand c'est globalement correct[^v3].
+La vidéo comporte cependant des phrases coupées qui sont mal retranscrites, aussi deux courtes phrases à la fin sont mal retranscrites.
+En utilisant le modèle de taille moyen, les résultats sont meilleurs.
+
+[^v3]: Attention à bien utiliser la dernière version. Auquel cas, le support du français et de l'allemand est médiocre.
+En effet, avant la version 3, « Apollinaire » devenait systématiquement « Napoléon », ce qui est tout de suite, beaucoup plus Rome antique que romantique.
+
+Pour le français, il n'y a qu'une erreur de transcription mais l'orthographe est parfois à désirer, le lyrisme de la chanson y est certainement pour quelque-chose.
+
+
+J'ai également essayé whispercpp sur l'audio français et allemand.
+Les résultats sont très bons et à peu près identique aux versions originales.
+Légèrement moins bon dans l'ensemble.
+J'ai même essayé [un modèle fine-tuné pour le français](https://huggingface.co/bofenghuang/whisper-large-v3-french/tree/main).
+Celui-ci corrige en effet, l'erreur de transcription que Whisper avait mais en crée une autre !
+
+Ainsi, après quelques retouches, j'ai donc les sous-titres originaux des vidéos ! 🥳
+Il me suffit maintenant seulement de les traduire. 🎉
+
+Il se trouve que whisper et whispercpp proposent de traduire directement vers l'anglais (uniquement l'anglais).
+Cependant, je voudrais avoir également la version française.
+
+:::question
+Pourquoi ne pas avoir utilisé d'autres méthodes de transcription ?
+:::
+
+C'est une question intéressant.
+En effet, il existe de nombreuses méthodes de transcriptions.
+Il existe même un [classement de ces méthodes sur paperswithcode.com](https://paperswithcode.com/sota/speech-recognition-on-common-voice-french).
+
+Il est difficile de savoir à quel point ces méthodes sont utilisables dans un contexte réel, avec du bruit pas exemple.
+Aussi, les performances ne sont pas indiquées, et certaine méthodes sont très gourmandes en ressources.
+J'ai essayé d'utiliser par exemple [tevr-asr-tool](https://github.com/DeutscheKI/tevr-asr-tool) mais celui-ci était très consomateur de ressources (⚠️) et n'était pas adapté à un environment bruillant.
+
+
+### Seamless
+
+L'idée ici c'est de traduire les sous-titres de whispercpp vers 3 langues, la langue originale, le français et l'anglais.
+
+:::information
+En première version de cet article, j'ai utilisé [NLLB](https://github.com/facebookresearch/fairseq/tree/nllb) qui est un modèle d'apprentissage automatisé créer par Meta et dédié à la traduction textuelle.
+
+Malgrès une traduction rapide, les résultats étaient décevants.
+Aussi, l'utilisation même du modèle était, je trouve, trop complèxe.
+:::
+
+
+Il n'existe pas d'outil CLI disponible avec Seamless.
+On doit automatiquement passer par du code Python.
+Heureusement, HuggingFace propose tout ce dont on a besoin.
+
+```python
+import srt
+from pathlib import Path
+from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, pipeline, SeamlessM4TModel, AutoProcessor, SeamlessM4TForTextToText
+
+def translate(text, processor, model):
+ text_inputs = processor(text = text, src_lang=langSrc, return_tensors="pt")
+ output_tokens = model.generate(**text_inputs, tgt_lang=langTrg)
+
+ return processor.decode(output_tokens[0].tolist(), skip_special_tokens=True)
+
+fileToTranslate = "JR-West-ads-Summer_Train-ja.srt"
+langSrc, langTrg = "jpn", "fra"
+
+
+# Must clone the Hugging Face repo with git lfs https://huggingface.co/facebook/hf-seamless-m4t-large
+print("Loading processor")
+processor = AutoProcessor.from_pretrained("hf-seamless-m4t-large")
+print("Loading model")
+model = SeamlessM4TForTextToText.from_pretrained("hf-seamless-m4t-large")
+
+
+with open(fileToTranslate) as f:
+ subs = list(filter(lambda x: x is not None, srt.parse(f.read())))
+
+if subs == None or subs == []:
+ print("No subs available")
+ exit(0)
+
+toTranslate = [x.content for x in subs]
+
+for i in range(len(subs)):
+ print(f"> {toTranslate[i]}")
+ subs[i].content = translate(toTranslate[i], processor, model)
+ print(f">> {subs[i].content}")
+
+with open(f'{Path(fileToTranslate).stem}_{langTrg}.srt', 'w') as f:
+ f.write(srt.compose(subs))
+
+```
+
+Le résultat est globalement bluffant ! 🤯
+
+Encore une fois pour le japonais, c'est très difficile d'évaluer la pertinance de la traduction.
+Surtout quand on se base sur un texte qui est certainement mal retranscrit.
+Par-contre, pour l'allemand et le français, c'est un sans-faute ! 💯
+
+
+### Real-ESRGAN
+
+Ici, ça va être très simple, j'ai suivi les instructions du README.
+D'abord, je me suis assuré d'avoir Pytorch d'installer et que Python est en version au moins 3.7.
+Ensuite, j'ai téléchargé le modèle pré-entrainé conseillé `RealESRGAN_x4plus.pth`.
+Je suis d'ailleurs assez étonné de ne pas trouver plus de variantes disponibles sur HuggingFace.
+
+Ensuite, j'ai agrandi chacune des images de la vidéo initial avec ce petit script:
+
+```sh
+for i in $(seq 1 14706); do
+ file=$(printf "png/%04d.png" $i)
+ python3 inference_realesrgan.py -n RealESRGAN_x4plus -i $file -o train --fp32
+ echo $file $(($i * 100 / 14706))
+done
+```
+
+Le reste est une histoire de ffmpeg, le bon encodeur et les bons paramètres.
+
+:::note
+Il semble qu'il existe un modèle de Real-ESRGAN défié à la vidéo.
+Cependant, je n'ai découvert son existance qu'après avoir commencé l'amélioration basée sur les images individuelles.
+
+Je vous invite à essayer par vous même le modèle dédié à l'amélioration vidéo et à m'en faire part par e-mail. ;)
+:::
+
+
+## Conclusion
+
+
+La conclusion va être rapide, les technologies à base de LLM sont globalement performantes et vont s'améliorer rapidement. 👌
+Ce sont désormais des outils utilisables quotidiennement pour produire des documents de qualités.
+Elles sont désormais disponibles en local et à partir de logiciels librérateurs.
+
+Ce dernier point est important, car on remarque que ces technologies tournent autour des États-Unis et de l'anglais.
+L'existance de logiciels libérateurs dans ce domaine nous garanti que d'autres pays puissent se munir de ces technologies sans dépendre de grosses sociétés comme Meta, Microsoft ou Google ([GAFAM](https://fr.wikipedia.org/wiki/GAFAM)).
+
+L'égémonie étasunienne sur les outils d'IA n'est concurencée que par les [BATX](https://fr.wikipedia.org/wiki/BATX) (Baïdu, Alibaba, Tencent et Xiamoi).
+Dans un tel contexte, il n'est pas étonnant que ces outils soit américano centrés.
+Outre le fait que la langue par défaut de ces outils soit l'anglais (voir la seule langue disponible !), il est notable que ces modèles sont plus performants en anglais que dans le reste des langues européennes. Ce qui pose bien évidement un problème d'équïté entre les peuples et qui est de fait un avantage concurrenciel pour les entreprises étasuniennes.
+
+
+-----------------------
+
+Pour finir, je vais vous narrer comment en 5min, j'ai animé l'illustration de cet article.
+
+J'avais déjà une petite idée de ce que je voulais comme animation, un train qui avance, l'idée de vitesse, etc.
+Souvent dans mes animations, ce qui me limite est l'illustration SVG de base.[^talent]
+Je peux ainsi passer beaucoup de temps à trouver le bon SVG à animer.
+
+[^talent]: Et bien sur, mon manque de talent pour réaliser ce type d'illustration moi-même.
+
+Ici, ça a été au contraire très rapide.
+Sur iconbuddy, un site d'icônes vectoriels libres d'utilisation, en cherchant « train » je tombe sur cette illustration crée par IBM.
+
+Dans Inkscape, je sépare l'image en plusieurs composants que je vais animer indépendamment.
+Mon but est de rapidement vérifier que l'effet de rail infini que je souhaite créer est possible.
+Pour cela, j'agrandis les rails et je rajoute de l'animation avec un élément `animateTransform`
+
+```xml
+ <animateTransform
+ attributeName="transform"
+ attributeType="XML"
+ type="translate"
+ from="0"
+ to="-12"
+ dur="0.15s"
+ repeatCount="indefinite" />
+```
+
+![Animation du train avec seulement les rails qui bougent](res/train-speed-v1.svg)
+
+C'est parfait ! Dans la foulée, j'anime alors le train.
+Cette fois-ci, pour une question d'esthétique, je voudrais une animation plus complexe où le train avance, ralentis puis accélère.
+Je me tourne donc vers les animations CSS par `keyframe` avec une animation « ease-in-out ».
+On peut rajouter du CSS directement dans le SVG, c'est pratique.
+
+```css
+#path1 {
+ animation: train 4s infinite;
+ animation-timing-function: ease-in-out;
+}
+
+@keyframes train {
+ 0% {
+ transform: translate(-40px);
+ }
+ 30% {
+ transform: translate(-5px);
+ }
+ 53% {
+ transform: translate(-15px);
+ }
+ 100% {
+ transform: translate(220px);
+ }
+}
+```
+
+Très rapidement j'ai un résultat convainquant que je présente à ma copine.
+
+Qui me rétorque sur un ton un peu moqueur:
+« C'est pas mal ! Ton train est un peu court par contre. »
+😿
+
+
+![« train » un peu court](res/train-speed-v2.svg)
+
+Je m'empresse de l'agrandir, je rajoute au passage deux petites bandes pour traduire la vitesse et le tour est joué !
+
+![Logo de l'article: Un train qui avance rapidement sur des rails, style simplifié vue de profil.](res/train-speed-inv.svg)
+
diff --git a/articles/rail-and-advertising.md b/articles/rail-and-advertising.md
new file mode 100644
index 0000000..883c4da
--- /dev/null
+++ b/articles/rail-and-advertising.md
@@ -0,0 +1,409 @@
+---
+
+pubDate = 2023-11-16 13:34:00Z
+tags = ['train', 'adverts', 'AI']
+
+[author]
+name = "ache"
+email = "ache@ache.one"
+
+[[alt_lang]]
+lang = "fr"
+url = "/articles/les-trains-et-la-publicité"
+
+---
+
+Rail and advertising
+===========================
+
+![Illustration of a fast-moving train](res/train-speed-inv.svg)
+Let's talk trains and advertising !
+The idea is to analyse a few advertisements for trains around the world.
+But it's mainly a pretext for showing you how recent artificial intelligence technologies can be used to improve an article. 🤖
+
+
+Table of contents
+----------
+
+
+:::question
+Why rail ads ?
+:::
+
+Because I like to analyse the construction and staging of films.
+Here we're going to take ads, because I'm not going to analyse an entire film before talking to you about AI.
+
+
+## A Japanese advert
+
+<video controls class="big" preload=none poster="res/JR_West-ads-Summer_Train_poster.png">
+ <source src="res/JR_West-ads-Summer_Train.webm" type="video/webm" />
+ <track kind="captions" srclang="jp" src="res/JR_West-ads-Summer_Train-ja.vtt" default label="日本語"/>
+ <track kind="subtitles" srclang="fr" src="res/JR_West-ads-Summer_Train-ai_fr.vtt" label="Français (IA)"/>
+ <track kind="subtitles" srclang="en" src="res/JR_West-ads-Summer_Train-ai_en.vtt" label="English (AI)"/>
+ <track kind="subtitles" srclang="fr" src="res/JR_West-ads-Summer_Train-gt_fr.vtt" label="Français"/>
+ <track kind="subtitles" srclang="en" src="res/JR_West-ads-Summer_Train-gt_en.vtt" label="English"/>
+</video>
+
+This short 15s clip was created by the Ponoc studio.
+The advert was commissioned by JR West, one of Japan's major railway companies.
+
+In Japanese animation style, the story depicts a family going on holiday in western Japan.
+The focus is on the young boy, who is reluctant at first but gradually blossoms with his family.
+
+His reticence contrasts with the family's excitement.
+He is quiet and not very mobile, whereas the rest of the family is moving around a lot and everyone is talking at the same time.
+His change of heart on this trip is reflected in his smile, which goes from an intense pout to bursts of joy when he discovers the sea.
+
+The target audience is families in general, not children in particular.
+Here the advert is a very clever staging of holiday memories and nostalgia.
+There are many references to reality, such as the Shinkansen N700 series and the recognisable Shin-Ōsaka station.
+In particular, we see and hear a Japanese cicada, a true symbol of summer in Japan.
+
+
+In short, this is an advert that gets a message across and speaks to its audience. 👏
+
+Speaking of advertising that speaks to its audience ...
+Let's take a look at an advert from Germany.
+
+
+## Der Volksgeist (The people's spirit)
+
+This mini-film advert was commissioned by Deutsch Bahn[^db] and produced by [Pantera](https://bwgtbld.tv/pantera/).
+It humorously depicts a young woman going on a business trip who is _harass_ by her client.
+
+[^db]: Which could be translated as “German rail network”.
+
+<video controls class="big" preload=none poster="res/DB-ad-The_client_poster.png">
+ <source src="res/DB-ad-The_client.webm" type="video/webm"/>
+ <track kind="captions" srclang="de" src="res/DB-ad-The_client-de.vtt" default label="Deutsch"/>
+ <track kind="subtitles" srclang="fr" src="res/DB-ad-The_client-fr.vtt" label="Français"/>
+ <track kind="subtitles" srclang="en" src="res/DB-ad-The_client-en.vtt" label="English"/>
+</video>
+
+The advert emphasises **the tranquillity and comfort of travelling by train** by contrasting it with the vigilance and stress inherent in driving a car.
+
+The humour is typically German, based on the repetitive comedy of the insistent customer.
+The key elements of this humour are the repetition of the phrase "Frau Fischer" and the staging of the customer trying to reach Mrs Fischer in increasingly **improbable ways**.
+
+In this absurd production, sound plays as important a role as image.
+The sound effects are very well chosen and are enhanced by the use of classical symphony-style background music, while supporting the story.
+In a more realistic interpretation of the story, Mrs Mueller (the customer) does not magically appear in Mrs Fischer's car.
+She is, in fact, a personification of Mrs Fischer's stress, a figment of her imagination.
+The disappearance of these hallucinations reflects the disappearance of Mrs Fischer's stress, as she is serene because she has taken the train.
+
+I'll spare you a precise description of each shot, but every element is selected and few things are left to chance.
+
+The advertisement is aimed at people travelling on business.
+A fairly small group of people.
+There's no question here of generally overshadowing the car, the heart of German industry. 🙄
+The director⋅trice Pantera went on to make several ads for the Mercedez Benz car brand.
+
+I invite you to have a look at the other creations of the [BWGTBLD company](https://bwgtbld.tv/).
+
+
+## The French touch
+
+This mini-film made for the French SNCF group isn't really an advert.
+The aim is not to sell you something, but to work on the brand's image and promote the SNCF's new slogan "For all of us".
+
+
+<video controls class="big" preload=none poster="res/SNCF-ad-Hexagonal_poster.png">
+ <source src="res/SNCF-ad-Hexagonal.webm"/>
+ <track kind="captions" srclang="fr" src="res/SNCF-ad-Hexagonal-fr.vtt" default label="Français"/>
+ <track kind="subtitles" srclang="en" src="res/SNCF-ad-Hexagonal-en.vtt" label="English"/>
+</video>
+
+The video is based around a **slam** text, sung by [Gaël Faye](https://en.wikipedia.org/wiki/Ga%C3%ABl_Faye), and illustrated by a number of very short video extracts from a variety of sources.
+
+The clip draws on a wide range of French cultural references and a number of previous SNCF promotional sequences, some of them are very old.
+These sequences, while appealing to the public's memory, are sufficiently unremarkable to make it difficult to remember exactly where they come from.
+The aim is to give way to the key element of this spot, the song.
+
+Punctuated by a few piano notes [^claque], it describes the SNCF and its values.
+There are many puns and subtle figures of speech.
+In particular, the SNCF describes its commitments and its humanist nature.
+
+
+[^claque]: Although the music is simple, it is not outdone.
+The rhythm is modelled on and introduced by railway noise.
+Every snappy moment is accentuated by [the SNCF's signature sonal](https://youtu.be/NA5MwhuHWLo?t=2) which lends itself surprisingly well!
+
+All French people are invited to love the SNCF in this unifying video. 💕
+Paradoxically, it brings people together by emphasising France's diversity, thus reviving one of its commitments, **supporter la diversité**.
+
+As the video progresses, the description of the SNCF becomes more and more descriptive of the French people themselves, in particular through the use of the impersonal pronoun "on", which has been ambiguous since the beginning of the video, and which can refer to both the SNCF and the French people.
+This amalgam appeals to the patriotic pride of French citizens.
+
+Now that the link has been created, it's the ideal time for SNCF to broach the subject of its faults and share them with its public, since its faults are the clichéd faults of the French.
+This empathy not only invites us to forgive them, but also reinforces the idea of a French company for the French, for France, "for all of us".
+
+This last idea is particularly highlighted by the final shock line “On est pas carré, on est hexagonal” (“We're not square, we're hexagonal”).
+In a very French play on words, it turns the weaknesses of not been very rigorous (“To not be square”) into a quality of been french. 🇫🇷
+
+## To sum up
+
+This study of the advertisements shows that these clips are culturally very rich.
+We can see that these groups do not hesitate to invest money to promote themselves, or at least that they have a lot of experience in their communications.
+The references are anchored in the culture of the country and I note that this contradicts the modern policies of opening up the rail market to competition, particularly from abroad.
+One could expect communication in English, with references based on [pop culture] (https://fr.wikipedia.org/wiki/Culture_populaire).
+
+To finish on a funny note, here's a set of accident prevention videos from the Latvian company LDz.
+
+<video controls class="big"
+ preload=none
+ poster="res/LDz_ads_railway-safety_poster.png">
+ <source src="res/LDz_ads_railway-safety.mp4" type="video/webm; codecs=av01.0.05M.08" />
+ <p>Set of LDz video staging the characters of Avārijas Brigāde about rail safety.</p>
+</video>
+
+
+## Let's get technical
+
+The video subtitles were created using tools based on [LLM](https://en.wikipedia.org/wiki/Large_language_model).
+The LDz video has been enlarged and is much more pleasant to watch than [the original version](https://youtu.be/f4HtbPt1DCk).
+
+To create this article, I used:
+
+ - [yt-dlp](https://github.com/yt-dlp/yt-dlp), a free software that can download videos from many website, not only youtube.
+ - [Whisper](https://en.wikipedia.org/wiki/Whisper_(speech_recognition_system)): A machine learning model for _Speech to Text_ (S2P) made by OpenAI.
+ - [Seamless](https://github.com/facebookresearch/seamless_communication): A machine learning model made by Meta and made to be a multimodal translation (Text <=> Text / Audio <=> Text / Audio <=> Audio).
+ - [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN): A model dedicated to image enhancement.
+ - [ffmpeg](https://fr.wikipedia.org/wiki/FFmpeg): The reference software for handling audio codecs.
+
+I will not write about yt-dlp and ffmpeg and concentrate myself on machine learning tools.
+
+
+### Whisper
+
+Ok, so since the videos aren't necessarily in a language that readers of this blog speak, I would have liked to have subtitles for the videos.
+
+I used Whisper to transcribe every video.
+I already have the subtitles of the SNCF ad, I will use that to verify the quality of Whisper, since french is my mother tongue.
+
+I setup a container and install Whisper.
+The quality of the transcriptions vary wildly based on the language.
+
+
+#### Japanese
+
+In Japanese, I can hardly evaluate the result.
+However, it seems to me that it is difficult to understand, the sentences are not very well linked and the general meaning is not clear.
+
+:::note
+I also used [insanely-fast-whisper](https://github.com/Vaibhavs10/insanely-fast-whisper) to transcribe Japanese.
+
+I have to admit that the results are better and much faster than with the Meta version, even if they are not at the level of Latin language processing.
+:::
+
+
+#### German and French
+To transcribe German it's ok[^v3].
+However, the video contains cuted sentences that are poorly transcribed, and two short sentences at the end are also poorly transcribed.
+Using the medium-sized model, the results are better.
+
+In French, there is only one transcription error[^v3], but the spelling sometimes leaves something to be desired, the lyricism of the song certainly having something to do with it.
+
+
+[^v3]: Make sure you are using the latest version. Otherwise, support for French and German is mediocre.
+In fact, before version 3, "Apollinaire" systematically became "Napoléon", which is a lot less romantic.
+
+I've also tried whispercpp on the French and German audio.
+The results are very good and more or less identical to the OpenAI versions.
+Slightly less good overall.
+I even tried [a fine-tuned model for French](https://huggingface.co/bofenghuang/whisper-large-v3-french/tree/main).
+This corrects the transcription error that Whisper had, but creates another one!
+
+So, after a few tweaks, I have the original subtitles for the videos! 🥳
+Now I just need to translate them. 🎉
+
+As it happens, whisper and whispercpp offer to translate directly into English (English only).
+However, I would also like to have the French version.
+
+
+:::question
+Why didn't you use other transcription methods?
+:::
+
+That's an interesting question.
+There are many different methods of transcription.
+There is even a [leadboard of these methods on paperswithcode.com](https://paperswithcode.com/sota/speech-recognition-on-common-voice-french).
+
+It is difficult to know how usable these methods are in a real context, with noise and background.
+Also, some of theses methods are very resource-intensive.
+I tried using [tevr-asr-tool](https://github.com/DeutscheKI/tevr-asr-tool) for example, but it was very resource-hungry (⚠️) and not suitable for a noisy environment.
+
+### Seamless
+
+The idea here is to translate the Whisper subtitles into 3 languages: the original language, French and English.
+
+:::information
+In the first version of this article, I used [NLLB](https://github.com/facebookresearch/fairseq/tree/nllb) which is an automated learning model created by Meta and dedicated to textual translation.
+
+Despite a quick translation, the results were disappointing.
+Also, the use of the model itself was, in my opinion, too complex.
+:::
+
+There is no CLI tool available with Seamless.
+You automatically have to use Python code.
+Fortunately, HuggingFace has everything you need.
+
+```python
+import srt
+from pathlib import Path
+from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, pipeline, SeamlessM4TModel, AutoProcessor, SeamlessM4TForTextToText
+
+def translate(text, processor, model):
+ text_inputs = processor(text = text, src_lang=langSrc, return_tensors="pt")
+ output_tokens = model.generate(**text_inputs, tgt_lang=langTrg)
+
+ return processor.decode(output_tokens[0].tolist(), skip_special_tokens=True)
+
+fileToTranslate = "JR-West-ads-Summer_Train-ja.srt"
+langSrc, langTrg = "jpn", "fra"
+
+
+# Must clone the Hugging Face repo with git lfs https://huggingface.co/facebook/hf-seamless-m4t-large
+print("Loading processor")
+processor = AutoProcessor.from_pretrained("hf-seamless-m4t-large")
+print("Loading model")
+model = SeamlessM4TForTextToText.from_pretrained("hf-seamless-m4t-large")
+
+
+with open(fileToTranslate) as f:
+ subs = list(filter(lambda x: x is not None, srt.parse(f.read())))
+
+if subs == None or subs == []:
+ print("No subs available")
+ exit(0)
+
+toTranslate = [x.content for x in subs]
+
+for i in range(len(subs)):
+ print(f"> {toTranslate[i]}")
+ subs[i].content = translate(toTranslate[i], processor, model)
+ print(f">> {subs[i].content}")
+
+with open(f'{Path(fileToTranslate).stem}_{langTrg}.srt', 'w') as f:
+ f.write(srt.compose(subs))
+
+```
+
+The overall result is stunning! 🤯
+
+Once again for Japanese, it's very difficult to assess the relevance of the translation.
+Especially when you're basing it on a text that's certainly badly transcribed.
+On the other hand, for German and French, it's flawless! 💯
+
+
+### Real-ESRGAN
+
+Here, it's going to be very simple, I followed the instructions in the README.
+First, I made sure I had Pytorch installed and that Python was at least version 3.7.
+Then I downloaded the recommended pre-trained model `RealESRGAN_x4plus.pth`.
+I'm actually rather surprised not to find more variants available on HuggingFace.
+
+Then I enlarged each of the images in the initial video with this little script:
+
+```sh
+for i in $(seq 1 14706); do
+ file=$(printf "png/%04d.png" $i)
+ python3 inference_realesrgan.py -n RealESRGAN_x4plus -i $file -o train --fp32
+ echo $file $(($i * 100 / 14706))
+done
+```
+
+And them I encode the video with ffmpeg in AV1.
+
+:::note
+It seems that there is a model for video enhancement.
+However, I only found out about it after I'd started enhancing based on individual images.
+
+I invite you to try out the video enhancement model for yourself and let me know how good is it by e-mail ;)
+:::
+
+
+## Conclusion
+
+I will be quick, LLM-based technologies are performing well and are going to improve rapidly. 👌
+They are now tools that can be used on a daily basis to produce quality documents.
+They are now available locally and from liberating software.
+
+This last point is important, as we can see that these technologies revolve around the United States and the English language.
+The existence of open-source software in this field guarantees that other countries will be able to acquire these technologies without depending on large companies such as Meta, Microsoft or Google ([Big Tech](https://en.wikipedia.org/wiki/Big_Tech)).
+
+The American aegemony over AI tools is rivalled only by the [BATX](https://en.wikipedia.org/wiki/BATX) (Baidu, Alibaba, Tencent and Xiamoi).
+In such a context, it is not surprising that these tools are American-centric.
+While the default language of these tools is English (sometimes the only language available!), these models perform better in English than in the rest of the European languages. This is obviously a problem of fairness between peoples, and is in fact a competitive advantage for US companies.
+
+
+-----------------------
+
+
+To conclude, I'm going to describe how in 5 minutes, I animated the illustration for this article.
+
+I already had a rough idea of what I wanted the animation to look like, a moving train, the idea of speed, etc. But I didn't really know what I wanted.
+Often in my animations, what limits me is the basic SVG illustration[^talent].
+So I can spend a lot of time finding the right SVG to animate.
+Pour finir, je vais vous narrer comment en 5min, j'ai animé l'illustration de cet article.
+
+[^talent]: Of course, my lack of talent to do this type of illustration myself is also a problem.
+
+Here, on the contrary, it was very quick.
+On iconbuddy, a free vector icon site, I searched for 'train' and came across this illustration created by IBM.
+
+Using Inkscape, I separate the image into several components that I'm going to animate independently.
+My aim is to quickly check that the infinite rail effect I want to create is possible.
+To do this, I enlarge the rails and add animation using an `animateTransform` element.
+
+```xml
+ <animateTransform
+ attributeName="transform"
+ attributeType="XML"
+ type="translate"
+ from="0"
+ to="-12"
+ dur="0.15s"
+ repeatCount="indefinite" />
+```
+
+![Train animation with only the rails moving](res/train-speed-v1.svg)
+
+It's perfect! I then animated the train.
+This time, for aesthetic reasons, I wanted a more complex animation where the train moves forward, slows down and then speeds up.
+So I turned to CSS keyframe animations with an 'ease-in-out' animation.
+You can add CSS directly to the SVG, which is very practical.
+
+```css
+#path1 {
+ animation: train 4s infinite;
+ animation-timing-function: ease-in-out;
+}
+
+@keyframes train {
+ 0% {
+ transform: translate(-40px);
+ }
+ 30% {
+ transform: translate(-5px);
+ }
+ 53% {
+ transform: translate(-15px);
+ }
+ 100% {
+ transform: translate(220px);
+ }
+}
+```
+
+Very quickly I have a convincing result which I present to my girlfriend.
+
+She retorts in a slightly mocking tone:
+“It's not bad! Your train's a bit short though.”
+
+![Too short train](res/train-speed-v2.svg)
+
+I quickly enlarged it, added two small strips to reflect the speed and that was it!
+
+![The article's logo: A train moving fast on rails, simplified style, side view.](res/train-speed-inv.svg)
+
diff --git a/articles/res/DB-ad-The_client-de.vtt b/articles/res/DB-ad-The_client-de.vtt
new file mode 100644
index 0000000..f281065
--- /dev/null
+++ b/articles/res/DB-ad-The_client-de.vtt
@@ -0,0 +1,47 @@
+WEBVTT
+
+00:00.000 --> 00:02.000
+Ja, ich weiß. Okay, perfekt.
+
+00:02.000 --> 00:04.000
+So, ich muss jetzt los.
+
+00:04.000 --> 00:06.000
+Ich bin dann unterwegs, ja?
+
+00:06.000 --> 00:08.000
+Okay, ja, danke.
+
+00:24.780 --> 00:27.920
+Hallo Frau Fischer, ich brauche eine Änderung in der Präsentation.
+
+00:30.000 --> 00:31.200
+Und zwar sofort.
+
+00:36.560 --> 00:38.060
+Wir haben nicht viel Zeit, Frau Fischer. Haben Sie [...]
+
+00:43.220 --> 00:44.580
+Was ist los, Frau Fischer?
+
+00:55.380 --> 00:56.780
+Hallo, hallo, Frau Fischer?
+
+00:58.980 --> 01:00.360
+Wir haben keine Zeit.
+
+01:00.840 --> 01:01.200
+[...]
+
+01:02.000 --> 01:04.000
+Hallo, Frau Fischer?
+
+01:04.920 --> 01:06.000
+Warum antworten Sie nicht?
+
+01:06.280 --> 01:07.340
+Es bleibt keine Zeit.
+
+01:07.360 --> 01:07.840
+Frau Fischer!!
+
diff --git a/articles/res/DB-ad-The_client-en.vtt b/articles/res/DB-ad-The_client-en.vtt
new file mode 100644
index 0000000..769f972
--- /dev/null
+++ b/articles/res/DB-ad-The_client-en.vtt
@@ -0,0 +1,46 @@
+WEBVTT
+
+00:00.000 --> 00:02.000
+Yeah, I know. Okay, perfect.
+
+00:02.000 --> 00:04.000
+So, I have to go now.
+
+00:04.000 --> 00:06.000
+I'll be on my way, okay?
+
+00:06.000 --> 00:08.000
+Okay, yeah, thank you.
+
+00:24.780 --> 00:27.920
+Hello, Mrs. Fischer, I need a change in the presentation.
+
+00:30.000 --> 00:31.200
+And I want to do it now.
+
+00:36.560 --> 00:38.060
+We don't have much time, Mrs. Fischer.
+
+00:43.220 --> 00:44.580
+What's the matter, Mrs. Fischer?
+
+00:55.380 --> 00:56.780
+Hello, hello, Mrs. Fischer? How are you?
+
+00:58.980 --> 01:00.360
+We don't have time.
+
+01:00.840 --> 01:01.200
+The [...]
+
+01:02.000 --> 01:04.000
+Hello, Mrs. Fischer? How are you?
+
+01:04.920 --> 01:06.000
+Why don't you answer?
+
+01:06.280 --> 01:07.340
+There is no time left.
+
+01:07.360 --> 01:07.840
+Mrs Fischer!!
diff --git a/articles/res/DB-ad-The_client-fr.vtt b/articles/res/DB-ad-The_client-fr.vtt
new file mode 100644
index 0000000..2c33d82
--- /dev/null
+++ b/articles/res/DB-ad-The_client-fr.vtt
@@ -0,0 +1,46 @@
+WEBVTT
+
+00:00.000 --> 00:02.000
+Oui, je sais. Okay, parfait.
+
+00:02.000 --> 00:04.000
+Alors, je dois partir maintenant.
+
+00:04.000 --> 00:06.000
+Je suis alors en route, oui?
+
+00:06.000 --> 00:08.000
+Okay, oui, merci.
+
+00:24.780 --> 00:27.920
+Hello Mme Fischer, j'ai besoin d'un changement dans la présentation.
+
+00:30.000 --> 00:31.200
+Et ce immédiatement.
+
+00:36.560 --> 00:38.060
+Nous n'avons pas beaucoup de temps, Mme Fischer. Avez-vous [...]
+
+00:43.220 --> 00:44.580
+Qu'est le problème, Mme Fischer?
+
+00:55.380 --> 00:56.780
+Hello, hello, Mme Fischer?
+
+00:58.980 --> 01:00.360
+Nous n'avons pas de temps.
+
+01:00.840 --> 01:01.200
+[...]
+
+01:02.000 --> 01:04.000
+Hello, Mme Fischer?
+
+01:04.920 --> 01:06.000
+Pourquoi ne répondez-vous pas?
+
+01:06.280 --> 01:07.340
+Il ne reste pas de temps.
+
+01:07.360 --> 01:07.840
+Madame Fischer!!
diff --git a/articles/res/DB-ad-The_client_poster.png b/articles/res/DB-ad-The_client_poster.png
new file mode 100644
index 0000000..7d6d341
--- /dev/null
+++ b/articles/res/DB-ad-The_client_poster.png
Binary files differ
diff --git a/articles/res/JR_West-ads-Summer_Train-ai_en.vtt b/articles/res/JR_West-ads-Summer_Train-ai_en.vtt
new file mode 100644
index 0000000..f5dbbca
--- /dev/null
+++ b/articles/res/JR_West-ads-Summer_Train-ai_en.vtt
@@ -0,0 +1,23 @@
+WEBVTT
+
+00:00.000 --> 00:01.000
+<c.back>I'll be right there.</c>
+
+00:00.000 --> 00:02.000
+I'm going to put a little bit of this in here.
+
+00:02.000 --> 00:03.000
+I'm going to take a look at the weather map.
+
+00:03.000 --> 00:04.000
+I'm going to do it.
+
+00:04.000 --> 00:05.000
+Is there anyone?
+
+00:10.000 --> 00:12.000
+The summer family!
+
+00:12.000 --> 00:14.000
+The summer train!
+
diff --git a/articles/res/JR_West-ads-Summer_Train-ai_fr.vtt b/articles/res/JR_West-ads-Summer_Train-ai_fr.vtt
new file mode 100644
index 0000000..40a4a2b
--- /dev/null
+++ b/articles/res/JR_West-ads-Summer_Train-ai_fr.vtt
@@ -0,0 +1,23 @@
+WEBVTT
+
+00:00.000 --> 00:01.000
+<c.back>On viendra.</c>
+
+00:00.000 --> 00:02.000
+Ha oui qu'est?
+
+00:02.000 --> 00:03.000
+On porte peut-être la baleine?
+
+00:03.000 --> 00:04.000
+C'est?
+
+00:04.000 --> 00:05.000
+Il y a?
+
+00:10.000 --> 00:12.000
+Famille été!
+
+00:12.000 --> 00:14.000
+Summer train!
+
diff --git a/articles/res/JR_West-ads-Summer_Train-gt_en.vtt b/articles/res/JR_West-ads-Summer_Train-gt_en.vtt
new file mode 100644
index 0000000..707c21c
--- /dev/null
+++ b/articles/res/JR_West-ads-Summer_Train-gt_en.vtt
@@ -0,0 +1,23 @@
+WEBVTT
+
+00:00.000 --> 00:01.000
+<c.back>I'm coming</c>
+
+00:00.000 --> 00:02.000
+yes, what up?
+
+00:02.000 --> 00:03.000
+I wonder if there will be whales
+
+00:03.000 --> 00:04.000
+I do not think so.
+
+00:04.000 --> 00:05.000
+Will there be any?
+
+00:10.000 --> 00:12.000
+Summer family!
+
+00:12.000 --> 00:14.000
+Summer train!
+
diff --git a/articles/res/JR_West-ads-Summer_Train-gt_fr.vtt b/articles/res/JR_West-ads-Summer_Train-gt_fr.vtt
new file mode 100644
index 0000000..fbd52af
--- /dev/null
+++ b/articles/res/JR_West-ads-Summer_Train-gt_fr.vtt
@@ -0,0 +1,23 @@
+WEBVTT
+
+00:00.000 --> 00:01.000
+<c.back>Je viens</c>
+
+00:00.000 --> 00:02.000
+Oui, qu'est-ce qu'il y a ?
+
+00:02.000 --> 00:03.000
+Je me demande s'il y aura des baleines.
+
+00:03.000 --> 00:04.000
+Je ne pense pas.
+
+00:04.000 --> 00:05.000
+Est-ce qu'il y aura ?
+
+00:10.000 --> 00:12.000
+Famille d'été !
+
+00:12.000 --> 00:14.000
+Summer train !
+
diff --git a/articles/res/JR_West-ads-Summer_Train-ja.vtt b/articles/res/JR_West-ads-Summer_Train-ja.vtt
new file mode 100644
index 0000000..39e0a2d
--- /dev/null
+++ b/articles/res/JR_West-ads-Summer_Train-ja.vtt
@@ -0,0 +1,23 @@
+WEBVTT
+
+00:00.000 --> 00:01.000
+<c.back>来ちゃうよ</c>
+
+00:00.000 --> 00:02.000
+はい、どうした?
+
+00:02.000 --> 00:03.000
+クジラをよいてるかな?
+
+00:03.000 --> 00:04.000
+そうかな?
+
+00:04.000 --> 00:05.000
+いるかは?
+
+00:10.000 --> 00:12.000
+夏家族!
+
+00:12.000 --> 00:14.000
+レアルターブレイン!
+
diff --git a/articles/res/JR_West-ads-Summer_Train_poster.png b/articles/res/JR_West-ads-Summer_Train_poster.png
new file mode 100644
index 0000000..b544e36
--- /dev/null
+++ b/articles/res/JR_West-ads-Summer_Train_poster.png
Binary files differ
diff --git a/articles/res/LDz_ads_railway-safety_poster.png b/articles/res/LDz_ads_railway-safety_poster.png
new file mode 100644
index 0000000..5277c5a
--- /dev/null
+++ b/articles/res/LDz_ads_railway-safety_poster.png
Binary files differ
diff --git a/articles/res/SNCF-ad-Hexagonal-en.vtt b/articles/res/SNCF-ad-Hexagonal-en.vtt
new file mode 100644
index 0000000..88cff5c
--- /dev/null
+++ b/articles/res/SNCF-ad-Hexagonal-en.vtt
@@ -0,0 +1,118 @@
+WEBVTT
+
+00:04.344 --> 00:05.490
+Creatives and inventors,
+
+00:05.490 --> 00:06.925
+Great artists,
+
+00:06.925 --> 00:08.491
+Great feminists,
+
+00:08.491 --> 00:09.603
+Big mouths
+
+00:09.603 --> 00:10.734
+Great in heart,
+
+00:10.734 --> 00:12.152
+But mostly big grumblers.
+
+00:13.386 --> 00:14.500
+Sometimes grandiloquent,
+
+00:14.500 --> 00:15.700
+The flower with the rifle,
+
+00:15.700 --> 00:16.992
+And the bite to the teeth,
+
+00:16.992 --> 00:19.564
+But romantic like a 20-year-old Apollinaire
+
+00:20.735 --> 00:22.207
+Elegant like no other
+
+00:22.274 --> 00:23.797
+Dressed in the most beautiful apparel
+
+00:23.797 --> 00:26.153
+Sapés too stylish and parade at the Grand Palais
+
+00:27.084 --> 00:29.307
+But above all ready to march for equality
+
+00:29.307 --> 00:31.415
+To declare rights for all men
+
+00:31.415 --> 00:33.848
+For all the women, and for our owls
+
+00:34.527 --> 00:36.531
+Humanists to the nail,
+
+00:36.643 --> 00:38.150
+Human to the core,
+
+00:38.150 --> 00:39.276
+Cicadas on the tongue,
+
+00:39.276 --> 00:40.480
+The ocean on the lips,
+
+00:40.480 --> 00:41.807
+Maroilles in the mouth,
+
+00:41.807 --> 00:43.372
+Or sauerkraut under the tooth,
+
+00:43.372 --> 00:45.970
+We vibrate, we cry, we laugh
+
+00:46.000 --> 00:46.937
+From the six corners of the country
+
+00:46.937 --> 00:48.057
+We breathe the same wind
+
+00:49.229 --> 00:50.596
+Pessimists often,
+
+00:50.596 --> 00:52.640
+Facing adversity as well as the opponent
+
+00:52.640 --> 00:55.219
+Wrong though, just look back
+
+00:55.219 --> 00:56.684
+Supporters of the Earth
+
+00:56.878 --> 00:58.302
+Lovers of the environment
+
+00:58.302 --> 01:00.554
+From our forests, our plains, our seas,
+
+01:00.659 --> 01:04.937
+Blue, white, red, but every day greener
+
+01:04.937 --> 01:07.831
+We are not static, we are progressive,
+
+01:07.831 --> 01:10.422
+We won't be late again, we're late sometimes
+
+01:10.684 --> 01:13.468
+But we're not late, we're ahead.
+
+01:13.565 --> 01:15.712
+We are not stuck, we have an unparalleled sense of humor
+
+01:15.712 --> 01:19.020
+We are not in bad faith, we are just a little paradoxical
+
+01:23.681 --> 01:24.641
+We are not square...
+
+01:25.761 --> 01:27.521
+One is hexagonal.
diff --git a/articles/res/SNCF-ad-Hexagonal-fr.vtt b/articles/res/SNCF-ad-Hexagonal-fr.vtt
new file mode 100644
index 0000000..0ee2f55
--- /dev/null
+++ b/articles/res/SNCF-ad-Hexagonal-fr.vtt
@@ -0,0 +1,121 @@
+WEBVTT
+Kind: captions
+Language: fr
+
+00:00:04.344 --> 00:00:05.490
+Créatifs et inventeurs,
+
+00:00:05.490 --> 00:00:06.925
+Grands artistes,
+
+00:00:06.925 --> 00:00:08.491
+Grands féministes,
+
+00:00:08.491 --> 00:00:09.603
+Grands de gueule
+
+00:00:09.603 --> 00:00:10.734
+Grands de cœur,
+
+00:00:10.734 --> 00:00:12.152
+Mais surtout grands râleurs
+
+00:00:13.386 --> 00:00:14.500
+Grandiloquents parfois,
+
+00:00:14.500 --> 00:00:15.700
+La fleur au fusil,
+
+00:00:15.700 --> 00:00:16.992
+Et le mors aux dents,
+
+00:00:16.992 --> 00:00:19.564
+Mais romantiques comme un Apollinaire de 20 ans
+
+00:00:20.735 --> 00:00:22.207
+Élégants comme aucun autre
+
+00:00:22.274 --> 00:00:23.797
+Parés du plus bel apparat
+
+00:00:23.797 --> 00:00:26.153
+Sapés trop stylé et défilé au Grand Palais
+
+00:00:27.084 --> 00:00:29.307
+Mais surtout prêts à défiler pour l’égalité
+
+00:00:29.307 --> 00:00:31.415
+À déclarer des droits pour tous les hommes
+
+00:00:31.415 --> 00:00:33.848
+Pour toutes les femmes, et pour nos mouflets
+
+00:00:34.527 --> 00:00:36.531
+Humanistes jusqu’au bout des ongles,
+
+00:00:36.643 --> 00:00:38.150
+Humains jusqu’au fond des tripes,
+
+00:00:38.150 --> 00:00:39.276
+Des cigales sur la langue,
+
+00:00:39.276 --> 00:00:40.480
+De l’océan sur les lèvres,
+
+00:00:40.480 --> 00:00:41.807
+Du maroilles dans la bouche,
+
+00:00:41.807 --> 00:00:43.372
+Ou de la choucroute sous la dent,
+
+00:00:43.372 --> 00:00:45.970
+On vibre, on pleure, on rit
+
+00:00:46.000 --> 00:00:46.937
+Des six coins du pays
+
+00:00:46.937 --> 00:00:48.057
+On respire le même vent
+
+00:00:49.229 --> 00:00:50.596
+Pessimistes souvent,
+
+00:00:50.596 --> 00:00:52.640
+Face à l’adversité comme face à l’adversaire
+
+00:00:52.640 --> 00:00:55.219
+À tort pourtant, suffit de regarder en arrière
+
+00:00:55.219 --> 00:00:56.684
+Supporters de la Terre
+
+00:00:56.878 --> 00:00:58.302
+Amoureux de l’environnement
+
+00:00:58.302 --> 00:01:00.554
+De nos forêts, de nos plaines, de nos mers,
+
+00:01:00.659 --> 00:01:04.937
+Bleu, blanc, rouge, mais chaque jour plus vert
+
+00:01:04.937 --> 00:01:07.831
+On n’est pas statique, on est progressiste,
+
+00:01:07.831 --> 00:01:10.422
+On va pas se refaire, on est parfois en retard
+
+00:01:10.684 --> 00:01:13.468
+Mais on n’est pas retardataire, on est avant-gardiste,
+
+00:01:13.565 --> 00:01:15.712
+On n’est pas coincé, on a un humour hors-pair
+
+00:01:15.712 --> 00:01:19.020
+On n’est pas de mauvaise foi, on est juste un peu paradoxal
+
+00:01:23.681 --> 00:01:24.641
+On n’est pas carré...
+
+00:01:25.761 --> 00:01:27.521
+on est hexagonal
+
diff --git a/articles/res/SNCF-ad-Hexagonal_poster.png b/articles/res/SNCF-ad-Hexagonal_poster.png
new file mode 100644
index 0000000..86bca0d
--- /dev/null
+++ b/articles/res/SNCF-ad-Hexagonal_poster.png
Binary files differ
diff --git a/articles/res/train-speed-inv.svg b/articles/res/train-speed-inv.svg
new file mode 100644
index 0000000..4334c33
--- /dev/null
+++ b/articles/res/train-speed-inv.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="200"
+ height="200"
+ viewBox="0 0 32 32"
+ version="1.1"
+ id="svg1"
+ sodipodi:docname="train-speed.svg"
+ inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1" />
+ <sodipodi:namedview
+ id="namedview1"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:zoom="4.6312032"
+ inkscape:cx="55.169249"
+ inkscape:cy="71.903561"
+ inkscape:window-width="2248"
+ inkscape:window-height="1470"
+ inkscape:window-x="0"
+ inkscape:window-y="26"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg1" />
+
+ <style>
+#path1 {
+ animation: train 4s infinite;
+ animation-timing-function: ease-in-out;
+}
+
+@keyframes train {
+ 0% {
+ transform: translate(-40px);
+ }
+ 30% {
+ transform: translate(-5px);
+ }
+ 53% {
+ transform: translate(-15px);
+ }
+ 100% {
+ transform: translate(220px);
+ }
+}
+
+ </style>
+
+
+ <path
+ fill="#000000"
+ d="M 29.714,16.59 18.15,8.64 C 15.651447,6.9168384 12.687134,5.9959408 9.652,6 H -20.530925 V 8 H 9.652 c 2.630327,-0.00357 5.199339,0.7941693 7.365,2.287 L 18.053,11 H 9 v 2 h 11.962 l 7.62,5.238 c 0.782412,0.537956 0.400506,1.763671 -0.549,1.762 H -7.4160686 v 2 H 28.034 c 2.912396,-4.73e-4 4.07983,-3.759889 1.68,-5.41 z m -54.952082,-4.630537 h -13.418725 v 2 h 13.418725 m 7.098392,1.844855 h -13.418724 v 2 h 13.418724"
+ id="path1"
+ sodipodi:nodetypes="ccccccccccccccccccccccccc" />
+ <path
+ fill="#000000"
+ d="M 52.076009,25 H 2 v 2 h 3.5768578 v 2 H 9.1537156 V 27 H 18.09586 v 2 h 3.576858 v -2 h 8.942145 v 2 h 3.576857 v -2 h 8.942145 v 2 h 3.576858 v -2 h 5.365286 z"
+ id="path2"
+ sodipodi:nodetypes="ccccccccccccccccccccc"
+ style="stroke-width:1.33732">
+
+ <animateTransform
+ attributeName="transform"
+ attributeType="XML"
+ type="translate"
+ from="0"
+ to="-12"
+ dur="0.15s"
+ repeatCount="indefinite" />
+
+
+
+ </path>
+</svg>
diff --git a/articles/res/train-speed-v1.svg b/articles/res/train-speed-v1.svg
new file mode 100644
index 0000000..92ae92e
--- /dev/null
+++ b/articles/res/train-speed-v1.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="200"
+ height="200"
+ viewBox="0 0 32 32"
+ version="1.1"
+ id="svg1"
+ sodipodi:docname="train-speed.svg"
+ inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1" />
+ <sodipodi:namedview
+ id="namedview1"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:zoom="4.6312032"
+ inkscape:cx="55.169249"
+ inkscape:cy="71.903561"
+ inkscape:window-width="2248"
+ inkscape:window-height="1470"
+ inkscape:window-x="0"
+ inkscape:window-y="26"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg1" />
+
+ <path
+ fill="#000000"
+ d="M 29.714,16.59 18.15,8.64 C 15.651447,6.9168384 12.687134,5.9959408 9.652,6 H -20.530925 V 8 H 9.652 c 2.630327,-0.00357 5.199339,0.7941693 7.365,2.287 L 18.053,11 H 9 v 2 h 11.962 l 7.62,5.238 c 0.782412,0.537956 0.400506,1.763671 -0.549,1.762 H -7.4160686 v 2 H 28.034 c 2.912396,-4.73e-4 4.07983,-3.759889 1.68,-5.41 z m -54.952082,-4.630537 h -13.418725 v 2 h 13.418725 m 7.098392,1.844855 h -13.418724 v 2 h 13.418724"
+ id="path1"
+ sodipodi:nodetypes="ccccccccccccccccccccccccc" />
+ <path
+ fill="#000000"
+ d="M 52.076009,25 H 2 v 2 h 3.5768578 v 2 H 9.1537156 V 27 H 18.09586 v 2 h 3.576858 v -2 h 8.942145 v 2 h 3.576857 v -2 h 8.942145 v 2 h 3.576858 v -2 h 5.365286 z"
+ id="path2"
+ sodipodi:nodetypes="ccccccccccccccccccccc"
+ style="stroke-width:1.33732">
+
+ <animateTransform
+ attributeName="transform"
+ attributeType="XML"
+ type="translate"
+ from="0"
+ to="-12"
+ dur="0.15s"
+ repeatCount="indefinite" />
+
+
+
+ </path>
+</svg>
diff --git a/articles/res/train-speed-v2.svg b/articles/res/train-speed-v2.svg
new file mode 100644
index 0000000..ce16e8d
--- /dev/null
+++ b/articles/res/train-speed-v2.svg
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="200"
+ height="200"
+ viewBox="0 0 32 32"
+ version="1.1"
+ id="svg1"
+ sodipodi:docname="train-speed.svg"
+ inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1" />
+ <sodipodi:namedview
+ id="namedview1"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:zoom="3.5898048"
+ inkscape:cx="20.753218"
+ inkscape:cy="-4.7356336"
+ inkscape:window-width="2248"
+ inkscape:window-height="1470"
+ inkscape:window-x="0"
+ inkscape:window-y="26"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg1" />
+ <style>
+#path1 {
+ animation: train 4s infinite;
+ animation-timing-function: ease-in-out;
+}
+
+@keyframes train {
+ 0% {
+ transform: translate(-30px);
+ }
+ 30% {
+ transform: translate(-5px);
+ }
+ 53% {
+ transform: translate(-15px);
+ }
+ 100% {
+ transform: translate(140px);
+ }
+}
+
+
+#path1 {
+ animation: train 4s infinite;
+}
+
+@keyframes train {
+ 0% {
+ transform: translate(-30px);
+ }
+ 35% {
+ transform: translate(-5px);
+ }
+ 60% {
+ transform: translate(-15px);
+ }
+ 100% {
+ transform: translate(80px);
+ }
+}
+ </style>
+ <path
+ fill="#000000"
+ d="M 29.714,16.59 18.15,8.64 C 15.651447,6.9168384 12.687134,5.9959408 9.652,6 H 2 v 2 h 7.652 c 2.630327,-0.00357 5.199339,0.7941693 7.365,2.287 L 18.053,11 H 9 v 2 h 11.962 l 7.62,5.238 c 0.782412,0.537956 0.400506,1.763671 -0.549,1.762 H 2 v 2 h 26.034 c 2.912396,-4.73e-4 4.07983,-3.759889 1.68,-5.41 z"
+ id="path1"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+ <path
+ fill="#000000"
+ d="M 52.076009,25 H 2 v 2 h 3.5768578 v 2 H 9.1537156 V 27 H 18.09586 v 2 h 3.576858 v -2 h 8.942145 v 2 h 3.576857 v -2 h 8.942145 v 2 h 3.576858 v -2 h 5.365286 z"
+ id="path2"
+ sodipodi:nodetypes="ccccccccccccccccccccc"
+ style="stroke-width:1.33732">
+ <animateTransform
+ attributeName="transform"
+ attributeType="XML"
+ type="translate"
+ from="0"
+ to="-26"
+ dur="0.25s"
+ repeatCount="indefinite" />
+
+
+ <animateTransform
+ attributeName="transform"
+ attributeType="XML"
+ type="translate"
+ from="0"
+ to="-12"
+ dur="0.15s"
+ repeatCount="indefinite" />
+
+
+
+ </path>
+</svg>
diff --git a/src/build/i18n.mjs b/src/build/i18n.mjs
index ebebfd9..2b74b64 100644
--- a/src/build/i18n.mjs
+++ b/src/build/i18n.mjs
@@ -13,6 +13,7 @@ const i18n = {
'mastodon': 'Mon mastodon',
},
articles: [
+ 'les-trains-et-la-publicité.md',
'formats-images-web.md',
'bizarreries-du-langage-c.md',
'retour-sur-laoc-2021-semaine-1.md',
@@ -44,6 +45,7 @@ const i18n = {
'mastodon': 'Mastodon account',
},
articles: [
+ 'rail-and-advertising.md',
'web-image-formats.md',
'c-language-quirks.md',
],