--- title: "Node.js Demo App" section: "Real-time translation" order: 3 sidebarLabel: "Node.js demo app" parent: "Integrations" --- This is a minimal working example that demonstrates real-time speech translation in a browser. https://github.com/pinch-eng/pinch-realtime-demo ## Quick Start #### 1. Clone the repository ```bash git clone https://github.com/pinch-eng/pinch-realtime-demo cd pinch-realtime-demo ``` #### 2. Install Dependencies ```bash npm install ``` #### 3. Add Your API Key Create a `.env` file in the project root: ```text PINCH_API_KEY=your_api_key_here ``` Don't have an API key? Login to the [Pinch Developer Portal >](https://portal.startpinch.com/dashboard/developers) #### 4. Run the Demo ```bash npm start ``` You'll see:
EXAMPLE OUTPUT
Pinch Real-Time Demo running at http://localhost:3000
#### 5. Try It Out 1. Open your browser to `http://localhost:3000` 2. Click the **Connect** button 3. Allow microphone access when prompted 4. Start speaking and watch the real-time translation appear! ## How It Works The demo has two simple parts: **Backend (server.js)** - Express server that runs on your computer - Proxies requests to the Pinch API (keeps your API key secret) - Serves the HTML file to your browser **Frontend (index.html)** - Single HTML file with embedded JavaScript - Connects to the translation service - Captures microphone audio and sends it for translation - Displays transcripts and plays translated audio ## Understanding the Code #### Session Creation (Backend) The backend creates a secure session: ```jsx // server.js app.post("/api/session", async (req, res) => { const response = await fetch("https://api.startpinch.com/api/beta1/session", { method: "POST", headers: { "Authorization": `Bearer ${PINCH_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ source_language: "en-US", target_language: "es-ES", voice_type: "clone" }) }); const data = await response.json(); res.json(data); }); ``` #### Connecting to the Room (Frontend) ```jsx // Get credentials from backend const { url, token } = await fetch("/api/session", { method: "POST" }).then(r => r.json()); // Connect to LiveKit room const room = new Room(); await room.connect(url, token); // Start streaming microphone await room.localParticipant.setMicrophoneEnabled(true); ``` #### Receiving Transcripts (Frontend) The browser listens for transcript messages: ```jsx room.on(RoomEvent.DataReceived, (payload) => { const message = JSON.parse(new TextDecoder().decode(payload)); if (message.type === "original_transcript") { // Display original text in left panel displayOriginal(message.text, message.is_final); } else if (message.type === "translated_transcript") { // Display translation in right panel displayTranslated(message.text, message.is_final); } }); ``` #### Receiving Audio (Frontend) The browser plays translated audio automatically: ```jsx room.on(RoomEvent.TrackSubscribed, (track) => { if (track.kind !== Track.Kind.Audio) return; // Create audio element const audioEl = document.createElement("audio"); audioEl.autoplay = true; audioEl.playsInline = true; // Attach translated audio stream track.attach(audioEl); document.body.appendChild(audioEl); }); ``` #### Change Languages Edit `server.js` to translate between different languages: ```jsx body: JSON.stringify({ source_language: "en-US", // Change this target_language: "es-ES", // Change this voice_type: "clone" }) ``` Check [Supported languages >](/docs/supported-languages) for the full list.