App demo di traduzione vocale in tempo reale, PWA installabile su PC e smartphone, costruita con React + Vite + Bootstrap 5 + Bootstrap Icons che usa l'OpenAI Realtime API (modello gpt-realtime) tramite WebRTC.
L'utente parla nel microfono, il modello riceve l'audio in streaming e produce contemporaneamente:
- la trascrizione testuale della frase di partenza,
- la traduzione testuale nella lingua di destinazione,
- l'audio della traduzione (text-to-speech integrato del modello).
Funziona da PC e da smartphone grazie a getUserMedia + RTCPeerConnection standard.
⚠️ Solo demo. La chiave API viene letta dallocalStoragedel browser. Per la produzione predisporre un backend che generi token effimeri tramitePOST /v1/realtime/sessions, in modo da non esporre la chiave principale.
- 📱 PWA installabile (Add to Home Screen su iOS/Android, Install su Chrome/Edge)
- 🎙️ Microfono live (PC, iPhone, Android) via WebRTC
- 🌍 17 lingue (con bandiere e nome nativo) + modalità auto-detect della sorgente
- 🔁 Inversione lingue con un click
- 🗣️ Risposta audio della traduzione + trascrizione testuale
- 📜 Cronologia delle frasi tradotte nella sessione
- 🎚️ Indicatori di stato (connesso, in ascolto, sta parlando)
- 🧊 Glass UI moderna, gradient blob animati, mobile-first
- 💾 Tutte le preferenze persistono in
localStorage - 🔗 Immagine Open Graph + Twitter Card per link sharing su social
- 📦 Service Worker con Workbox (cache app shell, NetworkOnly sull'API OpenAI)
- 🔊 Attiva/disattiva riproduzione audio della traduzione
- 📝 Attiva/disattiva trascrizione della sorgente (Whisper)
- 🎨 8 voci di output (alloy, ash, ballad, coral, echo, sage, shimmer, verse)
- 🎯 3 stili di traduzione: Naturale · Letterale · Bilanciato
- 🎤 Selezione esplicita del microfono (quando ce ne sono più di uno)
- 🧠 Selezione del modello Realtime (gpt-realtime, gpt-4o-realtime-preview, gpt-4o-mini-realtime-preview)
- 🕘 Visualizzazione della cronologia on/off
| Idea | Note |
|---|---|
| Backend Node/Express per token effimeri | Sostituisce l'inserimento manuale della chiave |
| Modalità conversazione bidirezionale | Due voci alternate per dialogo dal vivo |
| Selettore di formalità (tu/Lei) | Aggiunto come istruzione nel system prompt |
| Esportazione MP3/WAV della traduzione | Registrazione MediaRecorder lato client |
| Glossario personalizzato | Dizionario di nomi propri / acronimi mantenuti |
| Push notification per riconnessione | Tramite il service worker già attivo |
| Tema scuro/chiaro automatico | Media query prefers-color-scheme |
| Sottotitoli sincronizzati / karaoke | Highlight parola per parola sui delta |
| Salvataggio cronologia su file/JSON o cloud | Export .json o sync con backend |
| Riconoscimento del parlante (diarization) | Più speaker, etichette distinte |
| Modalità offline parziale | Cache delle frasi già tradotte |
Richiede Node.js 18+.
npm install
npm run assets # genera favicon, icone PWA e og-image (una sola volta)
npm run devL'app gira su http://localhost:5173.
npm run devnon genera automaticamente gli asset per essere veloce: lancianpm run assetsmanualmente la prima volta.npm run buildinvece li rigenera automaticamente (prebuild).
Vite è configurato con host: true, quindi è già esposto sulla LAN. Per accedere dallo smartphone:
npm run dev
# nota l'indirizzo Network: http://192.168.x.x:5173Il microfono in browser richiede HTTPS se non sei su localhost. Per testare via LAN da mobile usa uno tra:
mkcertper generare certificati di sviluppo,ngrok http 5173(tunnel HTTPS pubblico),- oppure deploy su Vercel/Netlify (HTTPS automatico).
- Chrome / Edge (desktop) → icona di installazione nella omnibox, oppure menu ⋮ → Installa Realtime Translate
- iOS Safari → pulsante Condividi → Aggiungi alla schermata Home
- Android Chrome → banner "Aggiungi alla schermata Home" o menu ⋮ → Installa app
Una volta installata, l'app gira in finestra standalone con la sua icona, status bar tematizzata e supporto offline dell'app shell (l'API OpenAI rimane sempre NetworkOnly, per sicurezza).
Tutte le immagini sono derivate da due soli file SVG sorgente, modificabili a piacere:
public/icon.svg # 512x512 — master per favicon e icone PWA
public/og-image.svg # 1200x630 — master per immagine Open Graph / Twitter Card
Lo script npm run assets genera in public/ (file gitignorati):
| File | Sorgente | Uso |
|---|---|---|
favicon.svg, favicon.ico |
icon.svg |
favicon browser |
apple-touch-icon-180x180.png |
icon.svg |
iOS home screen |
maskable-icon-512x512.png |
icon.svg |
Android adaptive icon |
pwa-64x64.png, pwa-192x192.png, pwa-512x512.png |
icon.svg |
manifest PWA |
og-image.png (1200x630) |
og-image.svg |
Open Graph + Twitter Card |
Le icone PWA usano @vite-pwa/assets-generator con il preset minimal-2023.
L'immagine OG viene rasterizzata da SVG a PNG con sharp tramite scripts/render-og.mjs.
Per rigenerare manualmente:
npm run assets:icons # solo favicon + icone PWA
npm run assets:og # solo og-image.png
npm run assets # entrambiIn produzione (npm run build) lo step prebuild rigenera tutto in automatico.
- Apri l'app nel browser
- Clicca l'icona ingranaggio in alto a destra
- Inserisci la tua chiave API OpenAI (
sk-…) - Scegli modello, voce, microfono e opzioni
- Chiudi il pannello, scegli lingua di partenza e lingua di arrivo
- Premi il pulsante microfono al centro e parla
La chiave resta esclusivamente nel localStorage del tuo browser. Non viene inviata da nessuna parte se non direttamente all'endpoint https://api.openai.com/v1/realtime.
Il brief originale citava gpt-realtime-translate, che non è un modello OpenAI pubblico. Il modello GA equivalente è gpt-realtime (più i preview gpt-4o-realtime-preview / gpt-4o-mini-realtime-preview). L'app utilizza l'endpoint POST /v1/realtime con un system prompt specializzato per la traduzione, ottenendo lo stesso comportamento di un modello dedicato. Il selettore del modello è esposto nelle impostazioni: si può inserire qualsiasi identificatore compatibile.
┌─────────────────────────────────────────────────────────┐
│ Browser (PWA: React + Bootstrap + Workbox SW) │
│ │
│ ┌───────────────┐ ┌────────────────────┐ │
│ │ UI controls │ │ useRealtime hook │ │
│ └───────────────┘ └─────────┬──────────┘ │
│ │ │
│ ┌────────▼─────────┐ │
│ │ RealtimeClient │ │
│ │ (WebRTC + DC) │ │
│ └─┬───────────────┬┘ │
│ getUserMedia() │ │ DataChannel JSON │
│ ┌─▼────────────┐ │ │
│ │ Microfono │ │ │
│ └──────────────┘ │ │
│ ▼ │
│ RTCPeerConnection │
└──────────────────────────────────┬──────────────────────────┘
│ SDP + audio RTP
▼
https://api.openai.com/v1/realtime
Il client invia un evento session.update con le instructions di traduzione (basate sulle lingue scelte), riceve sul MediaStreamTrack audio remoto la voce tradotta e sul DataChannel gli eventi:
input_audio_buffer.speech_started/speech_stoppedconversation.item.input_audio_transcription.delta/.completedresponse.audio_transcript.delta/.doneresponse.done
realtime-translate/
├── index.html # entrypoint, contiene meta PWA / OG / Twitter
├── vite.config.js # configurazione Vite + VitePWA
├── pwa-assets.config.js # configurazione @vite-pwa/assets-generator
├── package.json
├── public/
│ ├── icon.svg # master 512x512 (favicon + icone PWA)
│ ├── og-image.svg # master 1200x630 (Open Graph)
│ └── *.png / *.ico # generati da `npm run assets`
├── scripts/
│ └── render-og.mjs # rasterizza og-image.svg → .png con sharp
└── src/
├── main.jsx # entry point + registrazione service worker
├── App.jsx # composizione UI principale
├── styles.css # stili custom (glass UI, gradient, mobile)
├── utils/
│ ├── languages.js # elenco lingue + voci
│ └── realtimeClient.js # wrapper WebRTC OpenAI Realtime
├── hooks/
│ └── useRealtimeTranslation.js
└── components/
├── Header.jsx
├── LanguageSelector.jsx
├── MicButton.jsx
├── TranscriptPanel.jsx
├── HistoryList.jsx
├── SettingsPanel.jsx
└── StatusBadge.jsx
- Su iOS Safari l'autoplay audio richiede una prima interazione utente: il tap sul pulsante microfono soddisfa questo requisito.
- WebRTC richiede HTTPS in produzione e accesso al microfono autorizzato dal browser.
- L'API OpenAI è marcata
NetworkOnlynel service worker: nessuna richiesta versoapi.openai.comviene mai cacheata. - La demo non implementa rate limiting né gestione costi: tenere d'occhio l'uso dell'API.
Demo costruita per esplorare le potenzialità della Realtime API di OpenAI.