Intermédiaire·3 min·21 août 2026

Circleback passe son moteur d'enregistrement en natif : pourquoi Swift gagne

🎧 Résumé audio0:00 / 0:00
Electron ne peut pas capturer l'audio-vidéo en temps réel. Circleback a recodé tout ça en natif et ça change tout.
Circleback passe son moteur d'enregistrement en natif : pourquoi Swift gagne

Pourquoi ça compte pour toi

Si tu construis une app desktop qui capture ou traite du flux temps réel (diffusion, enregistrement, live), tu dois savoir : JavaScript + navigateur = impossible. La vraie leçon n'est pas « utilise Swift » mais « certaines tâches exigent du natif, point ». Circleback a aussi ouvert la boîte noire sur comment synchroniser trois sources de temps différentes en hardware — utile même hors enregistrement.

Ce qu'il faut retenir

  • 1.Electron + capture vidéo/audio = pauses GC et limitations trop imprévisibles pour du temps réel
  • 2.Solution : ScreenCaptureKit (macOS) + libobs (Windows) + pont Swift réactif = zéro boîte noire
  • 3.Atomic (leur outil interne) : les @Published Swift deviennent automatiquement des atoms Jotai — pas de code de liaison
  • 4.Sur macOS, synchroniser 3 horloges matérielles différentes (micros, écran) exige détection d'anomalies et correction par crossfade
  • 5.MP4 fragmenté = un crash à la trentième minute ne fait perdre qu'une seconde, pas la session entière

Tu galères avec le jargon ?

Lis la version réécrite en mode débutant — toutes les idées, sans le jargon.

Pourquoi Electron craque sur la capture temps réel

Circleback construit une app desktop qui enregistre des réunions sans bot. Pendant des mois, le moteur d'enregistrement était instable : une fuite mémoire corrigée, une autre surgissait la semaine suivante.

Le problème racine ? Un render process Electron n'est pas un environnement temps réel. Le moteur du navigateur fait des pauses GC, du throttling, de la réconciliation React — toutes choses acceptables pour l'UI, mortelles pour la capture audio/vidéo synchronisée. Une pause de 100ms tue la continuité.

Leur solution : sortir du navigateur entièrement.

L'architecture native à deux vitesses

Sur macOS, ils utilisent ScreenCaptureKit (Apple natif, accélération GPU). Sur Windows, ils enveloppent libobs dans du Swift qu'ils appellent OBSKit.

Ces deux moteurs sont foncièrement différents :

  • macOS : reçoit trois flux bruts (écran, micro système, micro), les synchronise manuellement, assemble le fichier MP4
  • Windows : la capture est un graphe unique (capture → mixage → encodage → multiplexage)

Sur Windows, ils gèrent aussi deux solutions de repli : Graphics Capture en principal, BitBlt si ça rame, détection des images noires (jeux, fenêtres émulées).

Synchroniser l'insynchronisable : trois horloges matérielles

Le vrai problème macOS : trois sources = trois horloges matérielles indépendantes. Même horloge système, pilotes différents, décalages différents.

Circleback :

  1. Horodate les deux flux audio
  2. Les convertit en index global
  3. Fait drainer les deux files en lockstep (pause si l'une est vide)
  4. Détecte l'immobilité après 500ms → bascule en mode mono

Le pire cas : les pilotes audio qui mentent. Certains virtuels annoncent 48kHz mais livrent à 44.1kHz. Sur 30 minutes, ça dérive de façon audible. Solution = mesurer la cadence réelle et, si elle contredit le format sur 3 tampons consécutifs, réinterpréter avec crossfade (sans clics).

Windows évite cette complexité grâce au mixeur interne du moteur.

Atomic : le pont réactif qui supprime le code de liaison

Le problème classique : tu veux relier Swift à React.

La mauvaise solution = sérialiser chaque valeur, typer avec des chaînes, mettre à jour trois fichiers (classe Swift + liaison C++ + enveloppe TypeScript) à chaque propriété ajoutée.

Atomic (outil interne) : chaque @Published en Swift devient automatiquement un atom Jotai en React. Aucun code de liaison.

@NodeExport public final class AudioPlayer {
  @Published public var isPlaying: Bool = false
  public func play() { isPlaying = true }
}

En React, c'est un atom normal. Que le booléen vive dans un thread Swift ? Invisible. La macro @NodeExport génère tout à la compilation. Les types se correspondent automatiquement (Int → number, String? → string | null).

Bonus : Atomic fonctionne aussi sur Windows (OpenCombine à la place des frameworks Apple).

Résistance aux pannes : MP4 fragmenté

Un MP4 classique écrit ses métadonnées à la fin. Crash avant ? Perte totale.

Circleback utilise le MP4 fragmenté : chaque segment est autonome. Crash à la trentième minute = perte du dernier segment (quelques secondes). Les segments sont envoyés en parallèle en local et dans le cloud. Si le réseau tombe, la reprise est automatique après reconnexion.

Résultat : l'enregistrement est devenu la partie ennuyeuse de l'app — celle qui fonctionne toute seule.

À retenir

Pas : « migre vers Swift ». Mais : certaines tâches exigent du natif, pas du JavaScript. Capture temps réel, traitement du signal, calcul intensif. Electron est excellent pour du desktop conventionnel (éditeur, chat, IDE), inadapté au streaming.

Le travail de synchronisation des horloges sur macOS est aussi une leçon d'ingénierie pour quiconque traite du temps réel multi-source.

Et concrètement pour toi ?

Choisis ton profil — la lecture de l'article change selon qui tu es.

🔭 Curieux

Pour toi, retiens que les apps que tu utilises tous les jours cachent des couches natives que tu ne vois pas. Quand tu enregistres une réunion Zoom sans décalage, il y a un ingénieur quelque part qui synchronise les horloges matérielles. Circleback l'a enfin expliqué : maintenant tu sais pourquoi c'est compliqué.

📊 Cours en bourse

Newsletters Noésis

3 minutes d'IA dans ta boîte mail, chaque matin.

Rejoins les francophones qui comprennent, essaient et progressent avec l'IA. Choisis ce que tu veux recevoir. Désabonnement en 1 clic.

Explorer les thèmes de cet article :