1Glink
LYA Translator
Prototyper une conversation vidéo multilingue où transcription et traduction deviennent lisibles presque en temps réel.
01 · Le prototype
Rendre visible une interaction qui dépend encore de services à connecter
Le besoin consistait à démontrer une conversation vidéo entre deux personnes parlant des langues différentes. Chaque prise de parole devait apparaître progressivement, puis recevoir presque immédiatement une traduction distincte et lisible.
J’ai construit ce travail comme un prototype frontend : le scénario et sa temporalité sont séparés des composants, afin que l’interface puisse être évaluée sans prétendre reproduire le futur moteur de traduction. Le même découpage prépare ensuite le remplacement de la simulation par des événements backend ou WebRTC.
- Parole · Événement
- Transcription · Progression
- Traduction · Restitution
Une démonstration crédible sans coupler l’interface au scénario simulé
02 · Flux temps réel
Préparer l’interface à recevoir une autre source de données
La simulation et le futur service de traduction doivent pouvoir alimenter le même état de vue. L’adaptateur constitue la frontière entre le transport et les composants.
01 · Source
Recevoir les événements
Un scénario local, un WebSocket ou un SDK média émettent des fragments sans connaître l’interface.
02 · Adaptateur
Normaliser le flux
Chaque source produit le même contrat : locuteur, langue, texte, nature et état de finalisation.
03 · État réactif
Assembler les messages
Les fragments sont regroupés par prise de parole et exposés sous forme de ViewModels immuables.
04 · Interface
Afficher et suivre
Le panneau distingue transcription et traduction, suit le message actif et conserve l’historique lisible.
Résultat Le passage de la maquette au flux réel peut se concentrer sur l’adaptateur, sans réécrire la présentation.
03 · Expérience en direct
Conserver l’échange humain au centre
La traduction est un support de compréhension. Elle doit rester identifiable sans prendre toute la place face aux deux interlocuteurs.
Deux niveaux de lecture
La transcription et la traduction utilisent des repères distincts, stables et accompagnés de leur langue.
Une progression perceptible
L’apparition graduelle des caractères matérialise le traitement en cours sans ajouter un indicateur de chargement permanent.
Un direct maîtrisable
Les contrôles média restent regroupés et les timers sont stoppés dès la fin ou la destruction de la vue.

04 · Exemple technique
Du scénario simulé au service réel sans changer les composants
Ces extraits sont anonymisés, simplifiés et réécrits pour le portfolio. Ils expliquent la structure du prototype sans reprendre le code, les scénarios ou les contrats internes du client.
Port applicatif
Définir le flux attendu par le frontend
L’interface dépend d’un contrat minimal que peuvent implémenter aussi bien une simulation qu’un service distant.
export interface TranslationEvent {
readonly utteranceId: string;
readonly speaker: 'local' | 'remote';
readonly kind: 'transcript' | 'translation';
readonly language: string;
readonly text: string;
readonly final: boolean;
}
export abstract class TranslationGateway {
abstract connect(sessionId: string): Observable<TranslationEvent>;
abstract disconnect(): void;
}État réactif
Dériver la conversation affichée
Les signaux conservent une source d’état compacte. Les données triées sont calculées sans mutation du tableau original.
const events = signal<readonly TranslationEvent[]>([]);
const conversation = computed(() =>
groupByUtterance(events()).map((utterance) => ({
...utterance,
transcript: joinFragments(utterance, 'transcript'),
translation: joinFragments(utterance, 'translation'),
})),
);
function append(event: TranslationEvent): void {
events.update((current) => [...current, event]);
}Cycle de vie
Nettoyer les ressources du direct
Les flux, timers et médias doivent s’arrêter avec le composant afin d’éviter une démo qui continue en arrière-plan.
const destroyRef = inject(DestroyRef);
const gateway = inject(TranslationGateway);
gateway
.connect(sessionId())
.pipe(takeUntilDestroyed(destroyRef))
.subscribe(append);
destroyRef.onDestroy(() => {
playbackClock.stop();
gateway.disconnect();
});05 · Cohérence UI
Une interface technique qui reste calme
La surface sombre concentre le regard sur les participants. Le panneau de conversation utilise la palette claire du produit et réserve la couleur à la nature du contenu et aux états actifs.
Couleurs
- NuitEspace de conversation vidéo
#171a33 - IndigoTranscription et actions
#2457ff - VioletTraduction
#6861d9 - BrumePanneau de lecture
#f5f7fb - AlerteFin d’appel
#d74354
Typographie
Inter · Regular / Medium / Semibold
Une conversation, deux langues, un même rythme.
Chaque fragment précise son locuteur, sa langue et sa fonction sans surcharger le direct.

