Architecture et modèle d'exécution
La session persistante et le client CLI, la socket de contrôle, l'adaptateur de backend Whisper et la cascade d'injection de texte.
Une session persistante, un client qui lui parle
whispskrid lancé sans argument de contrôle démarre une session persistante au premier plan : elle charge la configuration, charge le modèle Whisper une seule fois, ouvre le périphérique de capture, démarre l’écouteur de touche et la socket de contrôle, puis attend.
Le modèle CTranslate2 met de l’ordre de la seconde à plusieurs secondes à charger selon sa taille et la machine. Le recharger à chaque dictée rendrait l’appui-pour-parler inutilisable : c’est la raison d’être du processus persistant.
whispskrid lancé avec un argument de contrôle (--dictate, --status, --stop…) agit en client : il se connecte à la socket de la session en cours, envoie une commande d’une ligne, imprime la réponse et sort avec un code de retour reflétant OK ou ERR. S’il n’y a pas de session, il le dit et sort en erreur.
Deux voies pour déclencher une dictée
Le même état interne de la session persistante est piloté par un écouteur de touche local et par la socket de contrôle.
- Écouteur de raccourci local (
pynput) — il observe le serveur X.pynputdistingue l’appui de la relâche : la sémantique « je parle tant que je tiens » est donc native sur cette voie. Sous Wayland il ne capte que les fenêtres passant par XWayland, jamais une fenêtre Wayland native ; c’est un confort best-effort. Touche par défaut : Maj droit (shift_r), surchargeable parhotkeys.push_to_talk. - Sous-commandes CLI via la socket — voie universelle, indépendante du type de session. Un raccourci de bureau ne transmet pas « touche tenue / touche relâchée » : cette voie fonctionne donc en bascule.
--dictatedémarre la capture,--dictate-stopl’arrête et injecte,--togglefait l’un ou l’autre selon l’état,--canceljette la capture en cours sans injecter.
Une capture démarrée par la touche peut être annulée par --cancel, et inversement.
Garde-fou de durée
Seul garde-fou automatique : capture.max_seconds (défaut 300).
Si la touche reste tenue au-delà, la capture s’arrête d’elle-même, ce qui a été enregistré est transcrit et injecté normalement, et un avertissement est journalisé. Ce n’est pas un minuteur de confort — c’est une protection contre une touche bloquée ou un tampon audio qui gonfle sans fin. L’arrêt automatique sur silence (VAD) reste possible plus tard, en option ; la clé vad.enabled est réservée dans le schéma mais n’est pas implémentée en v1.0.1.
L’adaptateur de backend
Un module backend/ expose une interface étroite — load, transcribe(audio, langue), info — pour qu’un second moteur puisse être ajouté plus tard sans toucher au reste.
faster-whisper (CTranslate2) est la seule implémentation livrée en v1.0.1 ; la clé backend.name est réservée mais n’accepte que cette valeur. whisper.cpp est envisagé comme second backend, plus tard.
L’adaptateur instancie WhisperModel avec device (auto : CPU ou CUDA), compute_type (auto : int8 sur CPU, float16 sur CUDA) et download_root pointé sur le dossier de modèles géré. transcribe() est appelé avec beam_size (défaut 5), la langue forcée ou None, et sans filtre VAD ; il concatène les segments rendus et rogne le texte.
Gestion des modèles
Les modèles vivent dans un dossier géré — /usr/share/whispskrid/whisper-models/ et ~/.local/share/whispskrid/whisper-models/ pour une installation par paquet, whisper-models/ à la racine du dépôt pour une installation source.
La résolution d’un nom court (base) parcourt ces emplacements dans l’ordre. Le cache Hugging Face par défaut de faster-whisper n’est qu’un ultime repli : l’outil doit démarrer hors ligne une fois le modèle présent. whispskrid --download-model [NOM] télécharge le modèle demandé dans le dossier utilisateur, vérifie qu’il se charge, et sort ; le postinst du paquet propose ce téléchargement au premier lancement si aucun modèle n’est là.
Injection de texte : un collage par le presse-papiers, avec cascade de moteurs
Une fois le texte transcrit et post-traité, la couche d’injection le place dans le presse-papiers et simule un collage. Le moteur est choisi une seule fois au démarrage.
| Voie | Outils | Condition |
|---|---|---|
| Premier | ydotool + wl-clipboard | Frappe au niveau du pilote (/dev/uinput) via le démon ydotoold ; codes de touches dépendants de la disposition du clavier ; appartenance au groupe input requise. |
| Second | xdotool + xclip | Voie standard. La détection de la fenêtre (combinaison de collage pour terminal) n’existe que sur cette voie — ydotool n’a pas de notion de fenêtre ciblée. |
| Sinon | mode dégradé | Aucune frappe envoyée ; le texte transcrit reste dans le terminal pour le reste de la session. |
Le moteur de frappe a besoin d’un outil de presse-papiers à ses côtés : wl-clipboard sous Wayland — requis même sur le repli ydotool — et xclip sous X11. Le paquet Debian tire wl-clipboard et recommande xclip ; une installation depuis les sources les ajoute elle-même. Sans cela, le texte transcrit n’atteint jamais le presse-papiers et le collage réinsère le dernier contenu copié à la main.
Le contenu précédent du presse-papiers est relu puis restauré après le collage (réglable par clipboard.restore, actif par défaut). Un contenu non textuel — image, fichiers — est laissé intact. Sous Wayland avec une application GTK, la restauration peut devancer la lecture du presse-papiers par la fenêtre ; clipboard.defer_restore diffère la restauration à la fin de la session pour que le collage ne reprenne jamais l’ancien contenu.
Si aucun moteur adapté à la session courante ne fonctionne, l’outil ne plante pas et n’abandonne rien en silence : il passe en mode dégradé. Le texte transcrit continue de s’afficher dans le terminal et la frappe automatique est désactivée pour le reste de la session, plutôt que d’être retentée — sans succès — à chaque dictée. Quelques fenêtres refusent aussi le collage — certaines applications Java, des champs protégés ; à la première de ces situations, l’outil passe de la même façon en mode dégradé.
La socket de contrôle
Une session en cours ouvre une socket Unix privée à $XDG_RUNTIME_DIR/whispskrid.sock (mode 0600). La même commande appelée avec --dictate, --dictate-stop, --toggle, --cancel, --status ou --stop se connecte à cette socket au lieu de démarrer une seconde session.
C’est ce qui fait fonctionner les raccourcis de bureau partout sous Wayland, y compris pour les fenêtres Wayland natives que l’écouteur pynput ne voit jamais. Le protocole est en lignes de texte, une commande par ligne, réponse préfixée OK ou ERR ; une commande inconnue répond ERR unknown-command. Il n’y a pas de sleep / wake : WhispSkrid n’a pas d’état de veille.
Une seule session tourne par utilisateur à la fois ; une socket laissée par un plantage est détectée et remplacée au démarrage suivant.
Langue de l’interface et langue de dictée
Ce sont deux réglages distincts.
Langue de l'interface
Les chaînes de l’outil lui-même passent par la chaîne GNU gettext — catalogues .po compilés en .mo, extraits du source Python. Quatre langues : anglais, français, allemand, espagnol.
Langue de dictée
-l fr force la langue passée à Whisper pour cette session ; sans argument, default_language puis l’autodétection de Whisper. Aucune configuration par langue au-delà de ce choix.
Whisper ponctue et met les majuscules de phrase seul. Le post-traitement de WhispSkrid se limite au rognage des blancs de bord et à une capitale forcée sur la première lettre du texte injecté. Aucune table de substitution, aucune règle par langue.
Voir le dépôt du projet pour le code, et Guides pour démarrer.