1. Vue d'ensemble
RECscript est une application Flutter pour Android.
Il n'y a aucune base de données, ni locale ni distante, pour les contenus. Toute la persistance se fait en fichiers plats — système de fichiers et JSON — dans le répertoire Documents de l'application. Les transcriptions, synthèses et enregistrements ne quittent jamais l'appareil.
Sans compte et sans base utilisateur, il n'existe aucun jeu de données à exfiltrer côté serveur. C'est la contrepartie d'une autre réalité : une perte d'appareil efface l'historique, d'où l'importance de la sauvegarde chiffrée décrite plus bas.
2. Les trois chemins d'appel
Le mode se choisit dans les paramètres, et c'est lui qui décide qui voit passer le contenu de vos réunions. Un seul mode est actif à la fois.
Clé incluse (offre gratuite)
L'audio est déposé dans un espace de stockage privé (URL signée) hébergé
à Paris, région AWS eu-west-3, puis supprimé dès la fin du
traitement. Un fichier resté orphelin après une coupure réseau est purgé
automatiquement sous 60 minutes au maximum.
Clé personnelle
shared_preferencesAucun contenu ne passe par la fonction Edge : ni audio, ni transcript, ni synthèse. Aucun compteur d'usage n'est tenu. Aucune limite de durée ni de taille d'import ne s'applique, et les partages sortants ne portent aucune signature.
Seule exception, sans rapport avec le contenu : la vérification de
l'abonnement. L'application envoie son identifiant d'appareil anonyme
et le jeton d'achat Google Play à l'action verify_purchase.
Passerelle d'entreprise (offre Enterprise)
Même principe que la clé personnelle — rien ne transite par nos serveurs — mais l'adresse appelée est celle de la passerelle du client au lieu de l'API Mistral. L'application parle le schéma OpenAI, que toutes les passerelles du marché exposent.
Deux écarts de protocole, mesurés contre LiteLLM le 22 septembre 2026, sont traités par l'application et méritent d'être connus de qui administre la passerelle :
-
response_format=verbose_jsondevient obligatoire. Sans lui, la passerelle applique le formatjsond'OpenAI et ne renvoie que le texte : les segments existent côté serveur mais ne sont pas sérialisés, et la diarisation disparaît sans message d'erreur. L'application l'envoie donc systématiquement dans ce mode. - Le streaming est désactivé. LiteLLM ne sait pas relayer le flux SSE de Voxtral : il l'emballe dans un objet d'erreur… renvoyé avec un code HTTP 200. L'application ne le demande donc jamais en mode passerelle. Conséquence visible : la transcription s'affiche d'un bloc au lieu de défiler au fil de l'eau.
Le modèle est un champ libre, et non une liste : une passerelle
expose des alias choisis par son administrateur
(voxtral-mini-latest, mais aussi bien
transcription-interne). Un bouton Tester la connexion
vérifie l'adresse, la clé, la présence du modèle et le format de
réponse avant le premier enregistrement.
Marche à suivre côté administrateur —
config.yaml, clé virtuelle, dépannage :
guide de configuration de la passerelle.
L'APK ne contient aucune clé Mistral. En offre gratuite, la clé n'est détenue que par la fonction Edge, et le décompte du quota y est tenu côté serveur — il n'est donc pas contournable depuis un appareil rooté.
En mode passerelle, la clé saisie est celle du client, pas la nôtre : elle n'ouvre l'accès qu'à sa propre passerelle, et sa révocation est immédiate côté client, sans passer par nous. Elle est exclue de la sauvegarde chiffrée, comme la clé personnelle — seuls l'adresse et le nom du modèle s'y trouvent.
Une passerelle route des appels : elle ne crée aucune garantie juridique par elle-même, et ajoute même un intermédiaire à auditer. Ce qui détermine la souveraineté des données reste le fournisseur placé derrière, sa nationalité et le droit auquel il répond — un hébergement « région européenne » chez une société américaine n'y suffit pas.
Ce mode ne vend donc pas de la souveraineté : il rend au client le choix du fournisseur, qui lui appartenait déjà. À défaut de passerelle, l'appel direct à Mistral — société française soumise au droit européen, sans intermédiaire — reste le chemin le plus court.
3. Pipeline de transcription
L'extraction passe par l'endpoint
POST /v1/audio/transcriptions de l'API Mistral, avec le modèle
Voxtral choisi dans les paramètres.
| Paramètre | Effet |
|---|---|
model |
voxtral-mini-latest, voxtral-mini-2602 ou voxtral-small-latest, au choix. |
diarize=true |
Chaque segment est attribué à un intervenant, renuméroté 1..N dans l'ordre d'apparition. |
stream=true |
Flux SSE : le texte s'affiche au fil de l'eau. Repli automatique en mode non-stream si l'API refuse la combinaison stream + diarize. |
L'exception : l'offre Essentiel
Cette offre n'emprunte pas ce pipeline. Son ASR est
Groq whisper-large-v3-turbo (API compatible
OpenAI), appelé par la même fonction Edge mais avec une clé distincte, qui
ne quitte pas plus le serveur que celle de Mistral. L'audio
transite donc aux États-Unis, là où toutes les autres offres
restent chez Mistral, dans l'Union européenne. C'est la contrepartie
assumée de son prix, et elle est annoncée avant l'achat.
Whisper ne sait pas diariser : la réponse de Groq est du texte horodaté, sans intervenants. La séparation des voix est donc calculée sur le téléphone, hors ligne, par sherpa-onnx — pyannote segmentation-3.0 pour les frontières de parole, empreintes vocales CAM++, puis clustering.
Chaque segment de texte est ensuite rattaché au tour de parole qui le recouvre le plus longtemps : l'ASR découpe par phrase et la diarisation par tour de parole, sur deux grilles de temps qui ne coïncident pas. Cette étape a lieu avant l'affichage — le transcript n'apparaît qu'une fois les voix attribuées, jamais réécrit après coup.
Sources audio
-
Micro — M4A/AAC à 32 kbps sur mobile, soit environ 4 Mo par
heure ; repli en WAV 16 kHz mono si l'appareil ne sait pas encoder en AAC.
Sur Android, un service de premier plan
(
foregroundServiceType="microphone") maintient la capture même écran verrouillé. - Import de fichier — MP3, M4A, WAV, OGG, FLAC, AAC, WebM. Plafonné à 50 Mo en offre gratuite (limite du bucket de transit) ; aucun plafond avec une clé personnelle.
-
Import d'une conversation écrite — export WhatsApp ou format
Prénom: texte, une ligne par tour de parole, jusqu'à 2 Mo. Les horodatages WhatsApp sont retirés. Un fichier de prose sans préfixe de nom est refusé plutôt que découpé au hasard : aucun appel audio n'est fait, la session est archivée directement avec ses intervenants déjà nommés.
Reprise après coupure réseau
Si la connexion tombe en cours d'extraction, la transcription reprend à l'instant de la coupure plutôt que de tout renvoyer. Le fichier est redécoupé à cet instant — en pur Dart pour WAV et M4A/AAC sur toutes les plateformes, via ffmpeg pour les autres formats sur poste de bureau. Si la reprise reste incomplète, la partie déjà transcrite est conservée et l'utilisateur en est informé, plutôt que de perdre le travail en silence.
Suivi pendant l'extraction
La forme d'onde se remplit en orange jusqu'à la portion déjà transcrite,
d'après le champ end des segments SSE. L'amplitude réelle est
extraite en tâche de fond : pur Dart pour le WAV, décodage natif MediaCodec
sur Android, ffmpeg sur poste de bureau. Quand elle n'est pas disponible, un
aperçu stylisé est affiché — et signalé comme tel, pour ne pas
faire passer une décoration pour une mesure.
Le retour audio optionnel lit le fichier en parallèle, avec réglage de vitesse. Deux indicateurs distincts sont affichés et jamais confondus : « Transcrit » (avancement de l'extraction) et « Écoute » (position de lecture).
4. Découpe audio
L'éditeur propose la lecture, la forme d'onde, une paire de ciseaux pour poser une coupe, puis la sélection et la suppression d'une portion. Il s'ouvre depuis deux endroits, et les conséquences ne sont pas les mêmes.
- Avant transcription — seule la portion conservée est envoyée au modèle. Ce qui est retiré n'est jamais transcrit : ni facturé, ni décompté du quota.
- Sur une session archivée — l'opération est irréversible. L'audio est réécrit ; les prises de parole tombant dans les portions supprimées disparaissent, et les autres sont réhorodatées sur la timeline recollée. Une prise de parole à cheval sur une coupe est rognée sur ses vrais mots quand les horodatages par mot existent, sinon elle est conservée entière et signalée comme approximative. Le texte complet est recomposé — sans quoi les questions continueraient à répondre depuis du texte effacé.
Dans les deux cas, un avertissement chiffré — durée d'audio et nombre de prises de parole perdues — s'affiche avant toute écriture. Le découpage est en pur Dart pour WAV et M4A/AAC, donc disponible sur mobile ; ffmpeg n'est requis que pour les autres formats, sur poste de bureau.
5. Génération de texte
Les appels texte sont distincts des appels audio, et disposent de leur propre enveloppe de quota.
- Récap structuré — titre, résumé et actions à mener cochables, généré automatiquement à l'archivage et affiché en tête de session.
-
Synthèse Markdown — générée en streaming par
ministral-8b-latestdans la langue de la conversation. Elle est mise en cache, et le cache est invalidé si les intervenants sont renommés : une synthèse qui cite des noms périmés vaut moins que pas de synthèse du tout. - 22 formats répartis en 9 secteurs — général, tech, produit, business, RH, juridique, santé, éducation, média. Le type est imposé au clic via une feuille secteur puis métier : la synthèse ne repart jamais avec le type de la fois précédente. Les types inutilisés se masquent dans les paramètres.
- Modèles personnalisés — un nom, un prompt, et le modèle devient réutilisable comme les formats intégrés.
Croisement de deux réunions
Le modèle reçoit les deux transcriptions étiquetées par leur titre, ainsi que le recoupement réel des intervenants nommés, calculé côté application. Deux garde-fous encadrent le raisonnement :
- Le sujet décide du lien, pas la liste des participants : une réunion de suivi réunissant de nouvelles personnes sur le même dossier est pleinement exploitée.
- Les noms servent à attribuer, jamais à conclure : un prénom commun ne prouve pas qu'il s'agit de la même personne, et l'absence de nom partagé n'empêche pas le rapprochement. Si les sujets sont réellement étrangers, le modèle le dit d'emblée au lieu de fabriquer une continuité.
6. Persistance locale
Chaque extraction est archivée automatiquement. Aucune base de données : un répertoire par session, un JSON de métadonnées, un fichier audio.
Documents/vox_extract/
├── sessions/
│ └── <id>/
│ ├── session.json métadonnées, transcription, noms,
│ │ synthèse, récap, note
│ └── audio.<ext> l'enregistrement d'origine
├── people.json répertoire des prénoms déjà attribués
└── qa_history.json questions et réponses (300 entrées max)
Les fichiers texte (session.json, people.json,
qa_history.json) sont chiffrés sur disque en
AES-256-GCM, avec une clé générée sur l'appareil et conservée dans le
Keystore Android — jamais dans un fichier posé à côté des données qu'elle
protège. Cela protège contre une sauvegarde ADB, une extraction hors ligne
de la partition, ou un appareil perdu dont on lit la mémoire ; cela ne
protège pas un appareil déverrouillé entre d'autres mains, ni un Android
rooté. L'audio archivé, lui, reste en clair : il est lu en streaming par le
lecteur, et le chiffrer imposerait de le déchiffrer en entier vers un
fichier temporaire avant chaque écoute.
Rétention
- Suppression automatique des sessions — jamais, 7, 30 ou 90 jours. La purge s'exécute au lancement.
- Purge de l'audio seul — désactivée par défaut ; 7, 30, 60 ou 90 jours. Elle supprime le fichier audio et conserve transcription, synthèse, récap et note. Jamais sans préavis : l'avertissement tombe la veille, et la purge n'agit qu'au lancement suivant. Un utilisateur absent six mois retrouve donc son audio intact et l'avertissement à son retour. Le détail de la session indique ensuite explicitement que l'audio a été purgé.
Répertoire de personnes
Voxtral fait de la diarisation par fichier : il distingue les voix d'un enregistrement mais ne fournit aucune empreinte vocale stable d'une session à l'autre. Il ne peut donc pas reconnaître une voix déjà entendue. Le répertoire contourne cette limite sans prétendre la résoudre : il mémorise les prénoms déjà attribués et les propose en autocomplétion, classés par usage récent, ce qui ramène l'attribution à un seul tap.
7. Sauvegarde chiffrée
L'historique ne vit que sur l'appareil : perte, vol ou réinstallation
l'effacent. L'application écrit donc un fichier .recbak chiffré,
confié au partage système Android — Drive, OneDrive, Dropbox, carte SD — sans
SDK tiers à maintenir.
| Élément | Choix |
|---|---|
| Chiffrement | AES-GCM 256 bits |
| Dérivation de clé | Argon2id — 19 Mio de mémoire, 2 itérations |
| Paramètres | Écrits dans l'en-tête, pour qu'un durcissement futur ne rende pas les anciennes sauvegardes illisibles |
| Phrase de passe | 8 caractères minimum |
| Code de récupération | 16 caractères, 80 bits d'entropie, alphabet sans I/O/0/1, affiché une seule fois |
La clé maîtresse est chiffrée à la fois par la phrase de passe et par le code de récupération : une phrase oubliée ne condamne donc pas la sauvegarde. Nous ne connaissons ni l'une ni l'autre, et nous ne pouvons pas déchiffrer le fichier.
Sauvegardé
- Sessions : transcriptions, synthèses, récaps, notes
- Répertoire de personnes
- Historique des questions et réponses
- Une liste blanche de réglages
Jamais sauvegardé
- L'audio — le texte porte la valeur
- La clé Mistral personnelle — un secret n'a rien à faire dans un fichier qui part chez un tiers
- Le compteur de quota et sa signature — les restaurer offrirait le contournement de l'offre gratuite
La restauration est non destructive : les sessions déjà présentes ne sont jamais écrasées, l'historique des questions est fusionné par identifiant, et l'application annonce combien d'éléments ont été ajoutés.
8. Décompte du quota
Sur la clé incluse, deux enveloppes mensuelles distinctes s'appliquent, remises à zéro au changement de mois calendaire. Leur volume dépend du niveau d'abonnement, lu côté serveur — jamais déclaré par le client. La clé personnelle n'apparaît pas ici : ces appels vont directement à Mistral et ne traversent pas notre fonction Edge, qui n'a donc rien à décompter.
| Enveloppe | Gratuit | Essentiel | Pro Volume | Pro | Comportement |
|---|---|---|---|---|---|
| Audio transcrit | 30 min / mois | 25 h / mois | 40 h / mois | 12 h / mois | Micro et imports confondus. Le solde s'affiche sous les 20 minutes restantes. |
| Jetons de texte | 150 000 / mois | 2 000 000 / mois | 4 000 000 / mois | 4 000 000 / mois | Synthèses, récaps et questions. Jamais bloqués par l'épuisement de l'audio : l'historique déjà extrait reste exploitable. |
| Transcription (ASR) | Groq, États-Unis | Groq, États-Unis | Groq, États-Unis | Mistral, France | Les trois offres servies par Groq font la séparation des intervenants sur l'appareil, hors ligne : c'est ce qui divise par quatre le coût d'inférence, et ce qui permet d'offrir le palier gratuit. Pro garde la diarisation serveur de Voxtral, plus précise. |
Une session en cours n'est jamais coupée en plein milieu. Le dépassement est toléré 20 minutes au-delà de l'enveloppe : l'extraction démarrée va au bout, puis le blocage s'applique à la session suivante. Au-delà de cette limite dure, un nouvel envoi audio est refusé et l'utilisateur en est informé.
Le décompte est porté par un identifiant d'appareil anonyme et tenu côté serveur : il n'est ni falsifiable depuis l'application, ni remis à zéro en recopiant des fichiers ailleurs. Un compteur local signé en SHA-256 subsiste pour l'affichage hors ligne, mais il ne fait pas autorité. L'identifiant est affiché et copiable dans les paramètres, et s'efface depuis le même écran.
9. Internationalisation
L'interface est disponible en 18 langues : français, anglais, espagnol, allemand, italien, portugais, néerlandais, arabe (avec disposition de droite à gauche), hindi, chinois traditionnel, chinois simplifié, coréen, japonais, indonésien, turc, polonais, danois, vietnamien.
Les chaînes sont centralisées dans une table écrite à la main, sans génération de code ni fichiers ARB — toute nouvelle clé doit être ajoutée aux 18 tables, ce qui est volontairement contraignant : une chaîne manquante se voit à l'écriture plutôt qu'à l'exécution.
Une table séparée nomme en clair les 35 langues que Voxtral peut détecter dans l'audio — un ensemble distinct de celui de l'interface. Les titres et résumés suivent par défaut la langue de l'enregistrement, avec une option pour les ramener dans la langue de l'interface.
10. Limites connues
Cette section n'est pas une clause de style. Ce sont les contraintes réelles de la version actuelle.
- L'audio est chargé en mémoire. C'est adapté à des réunions ; évitez les fichiers de plusieurs centaines de mégaoctets.
-
Chaque identifiant de modèle Voxtral a sa propre capacité allouée.
Une version retirée du pool répond
429 backend_out_of_capacityà chaque requête — un refus permanent indiscernable d'une saturation passagère. Une version a dû être retirée de la liste pour cette raison : mieux vaut ne jamais figer un identifiant de modèle sans vérifier sa capacité. - La diarisation ne donne pas les prénoms, et ne fournit aucune empreinte vocale stable d'une session à l'autre. L'association prénom ↔ voix se refait à la main à chaque session, aidée par l'autocomplétion.
- La découpe d'une session archivée est irréversible. L'audio d'origine et le texte effacé ne sont pas récupérables.
- L'exactitude n'est pas garantie. Transcription et synthèse sont des traitements automatiques qui produisent des erreurs : mots mal entendus, intervenants mal attribués, résumés approximatifs. Ces résultats se vérifient avant tout usage juridique, contractuel, médical ou disciplinaire.
- La signature de partage peut être effacée par l'utilisateur dans l'application de destination avant l'envoi. C'est une friction, pas un verrou, et c'est assumé.
- Le contournement du quota par réinstallation n'est pas traité. L'identifiant d'appareil est un UUID local ; réinstaller en génère un nouveau. Le sujet est écarté volontairement tant que le volume d'utilisateurs ne justifie pas la création de comptes — ce qui coûterait la propriété qui fait l'intérêt de l'application.
Une question technique qui n'aurait pas sa réponse ici ? Le formulaire de contact arrive directement chez nous.