Selaou (breton: "écouter") - Outil open source d'annotation de transcriptions audio pour l'entraînement IA.
Selaou permet de valider et corriger des transcriptions audio (format Whisper) via une interface web simple et intuitive. Idéal pour créer des datasets de fine-tuning.
- Interface d'annotation simple et rapide
- Lecteur audio intégré avec lecture en boucle du segment
- Correction mot par mot avec indication de confiance
- Sélection intelligente des segments (priorise les segments incertains)
- Système de feedback pour signaler les problèmes audio
- Espace personnel (
/me) avec stats détaillées, heatmap d'activité et étapes franchies - Classement public (
/contributeurs) des annotateurs sur 7 jours, 30 jours ou depuis le début - Pseudo public auto-généré avec opt-out du classement
- Export JSONL/CSV compatible HuggingFace
- Système d'import flexible (SQL, fichiers JSON, API)
- Interface d'administration sécurisée par token
- Exclusion automatique des segments signalés comme problématiques
- Déploiement Docker simple
- Node.js 20+
- Docker et Docker Compose (pour MySQL)
# Cloner le repo
git clone https://github.com/Synapsr/Selaou.git
cd Selaou
# Installer les dépendances
npm install
# Copier la configuration
cp .env.example .env.local
# Démarrer MySQL avec Docker
docker compose up -d db
# Générer le schéma de base de données
npm run db:push
# (Optionnel) Ajouter des données de test
npx tsx scripts/seed.ts
# Démarrer le serveur de développement
npm run devOuvrir http://localhost:3000
# Configurer l'environnement
cp .env.example .env
# Éditer .env avec vos valeurs
# Lancer avec l'image pré-construite
docker compose -f docker-compose.hub.yml up -d
# L'application est disponible sur http://localhost:3000# Configurer l'environnement
cp .env.example .env
# Éditer .env avec vos valeurs
# Lancer l'application complète (build local)
docker compose up -d
# L'application est disponible sur http://localhost:3000curl -X POST http://localhost:3000/api/sources/import \
-H "Content-Type: application/json" \
-H "Authorization: Bearer VOTRE_ADMIN_TOKEN" \
-d '{
"name": "Mon episode",
"audioUrl": "https://example.com/audio.mp3",
"whisperJson": { ... }
}'Note: L'import nécessite le token admin configuré dans
ADMIN_TOKEN.
Configurer dans .env:
DATASOURCE_SQL_ENABLED=true
DATASOURCE_SQL_HOST=your-db-host
DATASOURCE_SQL_DATABASE=your-database
DATASOURCE_SQL_USER=your-user
DATASOURCE_SQL_PASSWORD=your-password
DATASOURCE_SQL_QUERY="SELECT id, title, audio_url, whisper_json FROM episodes WHERE ..."Puis lancer:
npx tsx scripts/sync-sources.tsDATASOURCE_JSON_ENABLED=true
DATASOURCE_JSON_PATH=./data/episodes
DATASOURCE_JSON_PATTERN=*.jsoncurl "http://localhost:3000/api/export?format=jsonl&min_reviews=2"Sortie:
{"audio":{"path":"...","start":0.0,"end":3.5},"text":"Bonjour...","is_correction":false}curl "http://localhost:3000/api/export?format=csv&only_corrections=true"L'interface d'administration est accessible à /admin et permet de:
- Voir la liste des annotateurs (triée par nombre d'annotations)
- Consulter l'historique des annotations
- Gérer les alertes et remarques signalées par les utilisateurs
- Supprimer des segments problématiques
- Générer un token sécurisé:
openssl rand -hex 32- Ajouter dans
.env.local:
ADMIN_TOKEN=votre_token_genere- Accéder à
http://localhost:3000/adminet entrer le token.
- Les segments signalés avec une alerte audio sont automatiquement exclus de la sélection pour les annotateurs
- Les remarques simples n'excluent pas le segment mais sont visibles dans l'admin
selaou/
├── src/
│ ├── app/ # Pages et API Next.js
│ │ ├── page.tsx # Page d'accueil
│ │ ├── review/ # Interface d'annotation
│ │ ├── admin/ # Interface d'administration
│ │ └── api/ # Routes API
│ │ └── admin/ # Routes API admin (sécurisées)
│ ├── components/ # Composants React
│ │ ├── ui/ # shadcn/ui
│ │ ├── audio/ # Lecteur audio
│ │ └── review/ # Composants d'annotation
│ ├── lib/
│ │ ├── db/ # Schema Drizzle + connexion
│ │ └── data-sources/ # Adaptateurs d'import
│ └── types/ # Types TypeScript
├── scripts/ # Scripts utilitaires
├── docker-compose.yml
└── Dockerfile
Variables d'environnement principales:
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
URL de connexion MySQL | - |
ADMIN_TOKEN |
Token d'accès à l'interface admin | - |
SELECTION_UNCERTAINTY_WEIGHT |
Poids pour prioriser segments incertains (0-1) | 0.7 |
SELECTION_MAX_REVIEWS |
Reviews max par segment | 3 |
Voir .env.example pour toutes les options.
| Endpoint | Méthode | Description |
|---|---|---|
/api/segments/next |
GET | Prochain segment à annoter |
/api/reviews |
POST | Soumettre une annotation |
/api/feedback |
POST | Signaler un problème sur un segment |
/api/export |
GET | Exporter les données |
/api/stats |
GET | Statistiques globales |
/api/me/stats |
GET | Stats détaillées de l'annotateur connecté (heatmap, étapes…) |
/api/me/settings |
PATCH | Mise à jour du pseudo public et de l'opt-in classement |
/api/leaderboard |
GET | Classement public (?period=week|month|all) |
| Endpoint | Méthode | Description |
|---|---|---|
/api/sources/import |
POST | Importer une source audio |
/api/admin/reviewers |
GET | Liste des annotateurs |
/api/admin/reviews |
GET | Liste des annotations |
/api/admin/feedback |
GET | Alertes et remarques |
/api/admin/segments |
GET | Liste des segments |
/api/admin/segments/:id |
DELETE | Supprimer un segment |
Les contributions sont les bienvenues ! N'hésitez pas à ouvrir une issue ou une pull request.
- Fork le projet
- Créer une branche (
git checkout -b feature/amélioration) - Commit (
git commit -m 'Ajout fonctionnalité') - Push (
git push origin feature/amélioration) - Ouvrir une Pull Request
Selaou utilise Drizzle ORM pour gérer le schéma. Les migrations sont versionnées dans src/lib/db/migrations/.
npm run db:migrateToutes les migrations seront appliquées dans l'ordre.
db:push synchronise le schéma sans créer d'entrée dans __drizzle_migrations. Si vous mettez à jour une telle instance, certaines migrations peuvent échouer parce que les tables existent déjà. Dans ce cas, appliquez manuellement uniquement les ALTER TABLE pertinents :
-- Pour la migration 0001_public_profiles (mise à jour vers les profils publics) :
ALTER TABLE reviewers ADD COLUMN display_name varchar(100) NULL;
ALTER TABLE reviewers ADD COLUMN is_public boolean NOT NULL DEFAULT true;
ALTER TABLE reviewers ADD CONSTRAINT reviewers_display_name_unique UNIQUE(display_name);
CREATE INDEX display_name_idx ON reviewers (display_name);Le display_name est nullable et auto-généré par l'API au prochain login (backfill paresseux), donc aucune donnée n'est perdue.
- Authentification lazy par email
- Espace personnel et classement public
- Système de vérification d'email pour les annotateurs
- Dashboard de statistiques avancées (admin)
- Support multi-langues
MIT - voir LICENSE