Skip to content

gitubpatrice/files_tech_voice

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

files_tech_voice

Module Speech-to-Text on-device pour les applications Files Tech.

License Flutter Android

Wrapper Flutter de whisper.cpp conçu pour l'écosystème Files Tech : transcription vocale 100 % locale, sans serveur, avec contrôle strict de l'intégrité du modèle (SHA-256) et du cycle de vie des données audio.

Utilisé par :

  • Notes Tech — dictée vocale dans l'éditeur de notes (v0.6+)
  • AI Tech — voice input pour le chat IA (planifié v0.5+)

✨ Garanties

  • 🔒 100 % offline — aucun appel réseau au runtime ; le modèle est importé manuellement par l'utilisateur (cf. flux SAF dans Notes Tech)
  • 🛡️ Intégrité cryptographique — SHA-256 vérifié au téléchargement et avant chaque chargement natif (anti-MITM, anti-substitution disque)
  • 🗑️ Aucune persistance audio — le WAV de capture vit dans le tmp dir le temps de la transcription puis est supprimé (couvert dans tous les chemins : succès, annulation, erreur, kill)
  • 🚫 Pas de FFmpeg embarqué — basé sur whisper_ggml_plus qui sort la dépendance ffmpeg dans un companion optionnel non installé. Compatible Android 16 / API 36 (les autres wrappers cassent au JNI_OnLoad)
  • ✍️ API stable et minimale — interface SpeechToText swappable, sealed exception hierarchy, pas de fuite des types internes du wrapper bas-niveau

🏗 Architecture

lib/
  files_tech_voice.dart                 # barrel d'exports publics
  src/
    speech_to_text.dart                 # interface SpeechToText + SttTranscription + SttSegment
    whisper_ggml_stt.dart               # impl WhisperGgmlStt (singleton .instance)
    stt_model.dart                      # SttModel (validation regex sur l'id)
    stt_model_catalog.dart              # whisper-base-q5_1 + whisper-tiny-q5_1
    stt_model_downloader.dart           # HTTP streaming + SHA-256 + tmp/rename atomique
    stt_model_importer.dart             # import SAF (apps sans permission INTERNET)
    stt_session.dart                    # capture micro + transcribe (state machine)
    stt_exceptions.dart                 # sealed SttException + 7 sous-types

API publique

Type Rôle
SpeechToText Interface stable du moteur (initialize / transcribeFile / dispose)
WhisperGgmlStt.instance Implémentation whisper_ggml_plus
SttSession Capture micro WAV 16 kHz mono + orchestration transcription
SttModel, SttModelCatalog Catalogue de modèles avec hashes SHA-256 attendus
SttModelImporter.instance Import SAF avec vérif SHA-256 (apps offline-only)
SttModelDownloader.instance Download HTTP avec SHA-256 (apps avec INTERNET)
SttException (sealed) Hiérarchie d'erreurs typées : missing model, checksum mismatch, permission, recording, transcription, download

🚀 Usage minimal

import 'package:files_tech_voice/files_tech_voice.dart';

// 1. Choisir un modèle dans le catalogue
final model = SttModelCatalog.defaultModel; // whisper-base-q5_1, ~57 Mo

// 2a. Si l'app a la permission INTERNET : download direct
await SttModelDownloader.instance.ensureInstalled(
  model,
  onProgress: (p) => print('${(p.fraction * 100).toStringAsFixed(0)}%'),
);

// 2b. Sinon (apps "100% offline" comme Notes Tech) : import SAF
//     L'utilisateur télécharge le .bin depuis HuggingFace,
//     puis sélectionne le fichier via FilePicker.
final pickedPath = '/storage/.../ggml-base-q5_1.bin';
await SttModelImporter.instance.importFromPath(
  pickedPath,
  model: model,
  onProgress: (p) => print('${p.phase} ${(p.fraction * 100).toStringAsFixed(0)}%'),
);

// 3. Initialiser le moteur (lazy-friendly, idempotent)
final stt = WhisperGgmlStt.instance;
await stt.initialize(model);

// 4. Capturer + transcrire
final session = SttSession(stt: stt);
await session.start();
// ... utilisateur parle ...
final result = await session.stopAndTranscribe(language: 'fr');
print(result.text);

// 5. Nettoyage
await session.dispose();

🔐 Sécurité

Aspect Garantie
Intégrité du modèle SHA-256 strict comparé à une constante hardcodée dans SttModelCatalog ; mismatch → fichier supprimé + SttModelChecksumMismatch
Atomicité du download Écriture dans <id>.bin.tmp puis rename POSIX ; jamais de .bin partiel
Stockage privé Modèle dans getApplicationSupportDirectory()/stt/<id>.bin, inaccessible aux autres apps
Audio capturé getTemporaryDirectory()/stt_capture_<ts>.wav, supprimé après transcribe (try/finally couvre tous les chemins)
Mode panique SttModelDownloader.uninstallAll() + purgeTempCaptures() — efface modèles + WAV orphelins
Permission RECORD_AUDIO Demandée runtime, distinction denied / permanentlyDenied exposée via SttPermissionDenied.permanently
Path traversal SttModel.fileName valide regex ^[a-z0-9_-]+$

📥 Modèles supportés

ID Taille Recommandation
whisper-base-q5_1 ~57 Mo Défaut. Bonne qualité française, ~3 s pour 5 s d'audio sur milieu de gamme
whisper-tiny-q5_1 ~32 Mo Plus rapide, qualité française approximative. Pour téléphones bas de gamme

Source officielle des .bin : huggingface.co/ggerganov/whisper.cpp

Le catalogue est juste une commodité pour l'UI standard — n'importe quel SttModel valide construit à la main peut être passé à SttModelDownloader.ensureInstalled ou SttModelImporter.importFromPath.


🤝 Licence

Apache License 2.0 — voir LICENSE et NOTICE.

Dépendances tierces et leurs licences : voir NOTICE.


📩 Contact

contact@files-tech.com · files-tech.com

About

Files Tech — Speech-to-Text Whisper on-device module (Flutter, Apache 2.0). Used by Notes Tech, AI Tech.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages