realtime-dual-transcriber is a Windows desktop application for live transcription from two audio sources at the same time:
- microphone input, shown as
You - system speaker output, shown as
Speaker
The application displays a real-time transcript in a desktop UI and can optionally use an OpenAI-compatible API provider such as Groq for faster multilingual transcription and Indonesian translation.
- Dual-source transcription for microphone and speaker audio
- Desktop interface built with CustomTkinter
- WASAPI loopback support for capturing default speaker output on Windows
- Local transcription mode with Faster Whisper
- API transcription mode with Groq or another OpenAI-compatible endpoint
- Optional Indonesian translation for each finalized transcript block
- Configurable fast/accurate transcription mode, language, prompt context, phrase timeout, audio filtering, and UI refresh
- Secret-safe local configuration through
.envorkeys.py - Built-in unit tests for transcript state and API authentication handling
This project is open source under the MIT License and welcomes forks, pull requests, bug reports, and documentation improvements.
Start contributing:
- Fork this repository.
- Create a branch from
main. - Make a focused change.
- Run the tests.
- Open a pull request.
git clone https://github.com/YOUR_USERNAME/realtime-dual-transcriber.git
cd realtime-dual-transcriber
git checkout -b feature/your-changeHelpful links:
Good first contributions include Windows setup improvements, UI polish, transcript-state tests, provider configuration examples, and safer defaults for noisy audio environments.
git clone https://github.com/Diyoncrz18/realtime-dual-transcriber.git
cd realtime-dual-transcriber- Windows 10 or Windows 11
- Python 3.8 or newer
- FFmpeg available on
PATH - Working microphone and default speaker device
- Optional: Groq or OpenAI-compatible API key for API mode
Install FFmpeg with Chocolatey:
choco install ffmpegOr install FFmpeg manually and make sure ffmpeg.exe is available from PowerShell:
ffmpeg -versionCreate and activate a virtual environment:
python -m venv .venv
.\.venv\Scripts\Activate.ps1Install dependencies:
python -m pip install --upgrade pip
pip install -r requirements.txtThe recommended configuration method is .env.
Copy-Item .env.example .envEdit .env and replace placeholder values with your own credentials.
Groq example:
GROQ_API_KEY=your-groq-api-key-here
GROQ_TRANSCRIPTION_MODEL=whisper-large-v3-turbo
GROQ_TRANSLATION_MODEL=llama-3.1-8b-instantFor mode-based model selection, set:
RTDT_TRANSCRIPTION_MODE=fastUse fast for lower latency (whisper-large-v3-turbo) or accurate for better accuracy (whisper-large-v3).
When RTDT_TRANSCRIPTION_MODE is set, it selects the Groq transcription model. Without it, an explicit GROQ_TRANSCRIPTION_MODEL value is used.
OpenAI-compatible endpoint example:
OPENAI_API_KEY=your-openai-compatible-api-key
OPENAI_BASE_URL=https://your-provider.example/v1
OPENAI_TRANSCRIPTION_MODEL=whisper-1You can also configure credentials through keys.py:
Copy-Item keys.example.py keys.pyKeep real credentials local. .env and keys.py are ignored by Git and should never be committed.
These values are optional and can be added to .env when needed:
RTDT_TRANSCRIPTION_MODE=fast
RTDT_TRANSCRIPTION_LANGUAGE=en
RTDT_TRANSCRIPTION_TEMPERATURE=0
RTDT_TRANSCRIPTION_PROMPT=This is an English motivational speech. Common words: power of words, adversity, opportunity, weakness, strength, disabled, differently abled, disability.
RTDT_RECORD_TIMEOUT=1.0
RTDT_PHRASE_TIMEOUT=3.0
RTDT_PAUSE_THRESHOLD=0.50
RTDT_MIN_AUDIO_SECONDS=0.30
RTDT_MIN_AUDIO_RMS=120
RTDT_MIN_MIC_RMS=120
RTDT_MIN_SPEAKER_RMS=90
RTDT_ENABLE_AUDIO_NORMALIZATION=1
RTDT_TARGET_AUDIO_RMS=800
RTDT_PRIORITIZE_SPEAKER=1
RTDT_UI_REFRESH_MS=150
RTDT_PROCESSING_STATUS_DELAY=0.15Model recommendation:
whisper-large-v3-turbofor lower latencywhisper-large-v3for higher accuracy
Set RTDT_TRANSCRIPTION_LANGUAGE=auto to let the provider detect the language. For English video/audio, prefer en or auto; do not force id unless the source audio is Indonesian.
Run local transcription mode:
.\.venv\Scripts\python.exe main.pyRun API transcription mode:
.\.venv\Scripts\python.exe main.py --apiAPI mode is recommended when you need better multilingual support, faster transcription, and Indonesian translation.
flowchart TD
mic["Microphone input"] --> mic_recorder["DefaultMicRecorder"]
speaker["System speaker output"] --> speaker_recorder["DefaultSpeakerRecorder via WASAPI loopback"]
mic_recorder --> mic_queue["Mic audio queue"]
speaker_recorder --> speaker_queue["Speaker audio queue"]
mic_queue --> transcriber["AudioTranscriber"]
speaker_queue --> transcriber
transcriber --> filter["Filter short or quiet audio"]
filter --> cleanup["Light audio normalization"]
cleanup --> model_router["TranscriberModels"]
model_router --> local_model["Local Faster Whisper"]
model_router --> api_model["Groq or OpenAI-compatible API"]
local_model --> transcript_state["Transcript state"]
api_model --> transcript_state
transcript_state --> ui["CustomTkinter transcript card"]
ui --> finish["User clicks Selesai"]
finish --> translation_queue["Background translation queue"]
translation_queue --> translation_model["Groq chat translation model"]
translation_model --> ui
sequenceDiagram
participant Audio as "Mic or Speaker"
participant Recorder as "AudioRecorder.py"
participant Queue as "Audio queue"
participant Transcriber as "AudioTranscriber.py"
participant Model as "TranscriberModels.py"
participant UI as "main.py UI"
Audio->>Recorder: Voice is detected
Recorder->>Queue: Push short audio chunk
Queue->>Transcriber: Drain pending chunks
Transcriber->>UI: Show speaking status
Transcriber->>Transcriber: Skip noise or very short audio
Transcriber->>Model: Send cleaned WAV chunk
Model-->>Transcriber: Return original transcript text
Transcriber->>Transcriber: Merge chunk into active segment
Transcriber->>UI: Update active card only
UI-->>UI: Show translation placeholder
UI->>Transcriber: User clicks Selesai
Transcriber->>Model: Translate active transcript only
Model-->>Transcriber: Indonesian translation
Transcriber->>UI: Update the same card
stateDiagram-v2
[*] --> Waiting: No transcript yet
Waiting --> Speaking: Audio chunk detected
Speaking --> Processing: Chunk is sent to transcription model
Processing --> Ready: Original text is available
Ready --> Translating: User clicks Selesai
Translating --> Done: Translation returned
Ready --> Speaking: More audio in same segment
Done --> Speaking: New phrase starts
Done --> [*]: Clear Transcript
AudioRecorder.pycaptures microphone audio and default speaker loopback audio.AudioTranscriber.pyfilters short or silent audio, merges phrase fragments, and manages transcript state.TranscriberModels.pyroutes transcription to either Faster Whisper or an OpenAI-compatible API provider.main.pyrenders the live transcript UI and refreshes it as transcript revisions change.
.
|-- AudioRecorder.py # Microphone and speaker recording
|-- AudioTranscriber.py # Transcript state, merging, filtering, translation queue
|-- TranscriberModels.py # Local and API transcription providers
|-- main.py # Desktop UI entry point
|-- custom_speech_recognition/ # Speech recognition compatibility layer
|-- tests/ # Unit tests
|-- .github/ # GitHub Actions and contribution templates
|-- .env.example # Environment variable template
|-- CONTRIBUTING.md # Contributor onboarding guide
|-- CODE_OF_CONDUCT.md # Community behavior expectations
|-- LICENSE # MIT License
|-- keys.example.py # Python credential template
|-- requirements.txt # Python dependencies
`-- README.md # Project documentation
Run the unit test suite:
.\.venv\Scripts\python.exe -m unittest discover -s testsCompile-check the main Python files:
.\.venv\Scripts\python.exe -m py_compile main.py AudioRecorder.py AudioTranscriber.py TranscriberModels.pyIf the terminal shows Invalid API Key or expired_api_key, create a new provider key, update .env or keys.py, and restart the application.
Make sure FFmpeg is installed and available from PowerShell:
ffmpeg -versionThe application captures the default Windows speaker output through WASAPI loopback. Set the target output device as the Windows default speaker before starting the app.
Translation runs when you click the Selesai button. While speaking, the active transcript block keeps updating and the translation field waits for that manual finish action.
- Do not commit
.env,keys.py, model files, recordings, or logs. - The repository includes a GitHub Actions secret scan for common API key patterns.
- If a real API key was ever committed, revoke it immediately and create a new one.
realtime-dual-transcriber is an independent open-source project developed and maintained by Diyoncrz18.
This project is licensed under the MIT License.
Maintained by Diyoncrz18.