đ Je construis un moteur de dictĂ©e en PHP (Flow + Symfony + Whisper.cpp)
le 22 février 2026
Construire un moteur de dictée en 2026 est trivial.
Construire une architecture propre autour dâun moteur de dictĂ©e est plus intĂ©ressant.
Cet article prĂ©sente Flowvox, un MVP de moteur de transcription audio dĂ©veloppĂ© en PHP, en sâappuyant sur :
- Symfony
- Symfony Messenger
- Flow : orchestrateur maison
- ffmpeg
- whisper.cpp
Le code source est disponible en open source : đ https://github.com/darkwood-com/flowvox
Lâobjectif nâĂ©tait pas simplement dâutiliser Whisper. Lâobjectif Ă©tait de structurer correctement le pipeline.
Le problĂšme : la transcription nâest quâune Ă©tape
Un moteur vocal minimal peut se résumer à :
Audio â Texte
Mais dans un systÚme réel, plusieurs contraintes apparaissent :
- Déclenchement start / stop
- Finalisation propre du fichier audio
- Gestion dâĂ©tat du recorder
- Orchestration des étapes
- Extension vers post-traitement (résumé, LLM, analyse)
La question devient alors :
Comment modéliser un pipeline audio propre, extensible et maßtrisé ?
Stack technique
Le MVP repose sur :
- PHP 8+
- Symfony
- Symfony Messenger
- Flow (orchestrateur)
- ffmpeg (captation audio locale)
- whisper.cpp (transcription open source locale)
Aucune API distante. Aucun service cloud. Transcription 100% locale.
Architecture générale
Lâarchitecture est organisĂ©e en trois flows :
InputProvider â Recorder â Transcribe
Chaque Ă©tape est isolĂ©e et responsable dâun rĂŽle prĂ©cis.
InputProviderFlow
Responsabilité :
- Ăcouter les commandes
voice:startetvoice:stop - Ămettre un
VoiceControlEvent
Les commandes CLI déclenchent des messages via Symfony Messenger.
Le worker, en arriÚre-plan, reçoit ces événements et les injecte dans Flow.
Ce découplage permet :
- Un contrĂŽle granulaire
- Une gestion multi-session
- Une séparation claire des responsabilités
RecorderFlow
Responsabilité :
- Piloter une instance de
VoiceRecorder - GĂ©rer le cycle de vie dâun processus
ffmpeg
Le VoiceRecorder encapsule un processus systÚme lancé via :
Symfony\Component\Process\Process
ProblĂšme central :
Comment gérer proprement start / stop sans corrompre le fichier audio ?
Trois états sont explicitement modélisés :
idlerecordingstopping
Lors dâun stop, un SIGINT est envoyĂ© Ă ffmpeg afin de finaliser correctement le header WAV.
LâĂ©tat stopping Ă©vite :
- Les double-start
- Les conflits concurrents
- Les fichiers incomplets
Le processus est maßtrisé, pas subi.
TranscribeFlow
Responsabilité :
- Recevoir un fichier WAV finalisé
- Lancer whisper.cpp
- Produire un texte transcrit
Whisper est exécuté localement via CLI.
Le MVP reste volontairement simple :
- Pas de streaming
- Pas de chunking temps réel
- Une transcription synchrone
Lâobjectif est de valider lâintĂ©gration et lâorchestration.
Worker et orchestration
Le moteur fonctionne via un worker Symfony :
php bin/console voice:worker
Ce worker :
- Instancie Flow
- Enregistre les flows
- Ăcoute Symfony Messenger
- Ordonne lâexĂ©cution des Ă©tapes
Commandes disponibles :
voice:start
voice:stop
voice:worker-list
Le flux complet devient :
voice:start
â Recorder dĂ©marre
â voice:stop
â Recorder finalise
â TranscribeFlow sâexĂ©cute
â Texte produit
Sans état global externe.
Pourquoi Flow ?
Flow permet :
- Une architecture orientée pipeline
- Des stratĂ©gies dâInput Processing (IP Strategy)
- Une gestion explicite des événements
- Une séparation nette entre orchestration et logique métier
Le systĂšme nâest pas couplĂ© Ă Whisper.
Whisper est une implémentation. Flow est la structure.
Ce que valide le MVP
- Gestion propre dâun processus systĂšme
- Modélisation explicite des états
- Orchestration événementielle
- Extensibilité du pipeline
Ce nâest pas un produit.
Câest une base architecturale.
Ăvolutions possibles
Les prochaines itérations naturelles :
- Streaming par chunk audio
- Transcription parallĂšle
- Post-traitement LLM
- Intégration desktop
- Support mobile
- Batching multi-modĂšles
Mais ces Ă©volutions ne changent pas le cĆur :
Une architecture claire. Une orchestration maßtrisée. Un pipeline extensible.
Code source
Le dépÎt open source est disponible ici :
đ https://github.com/darkwood-com/flowvox
Contributions, suggestions et retours sont les bienvenus.
Sources
Cet article est basé sur un article de blog de guillaume.id.
Conclusion
Construire un moteur vocal en PHP est simple.
Construire une architecture propre autour dâun moteur vocal est plus intĂ©ressant.
Flowvox valide un principe :
La transcription nâest quâun composant. Lâorchestration est la vĂ©ritable structure.