A desktop app to transcribe audio and video from files, URLs, YouTube, or your mic, then edit, translate, summarize, subtitle, and chat with your transcripts.
audiotext-showcase.mov
- About the Project
- Getting Started
- Usage
- Troubleshooting
- Roadmap
- Authors
- Contributing
- Acknowledgments
- License
- Support
Audiotext transcribes audio files, videos, YouTube videos, media file links, microphone recordings, and entire folders into any of its 100 supported languages. You can transcribe files with WhisperX on your computer, for free and without sending your audio anywhere. Alternatively, you can transcribe files with the Whisper API and the Google Speech-to-Text API. You can then play the transcription segment by segment, correct it, translate it, summarize it, and export it.
- Any source: sources can include audio and video files, YouTube videos, direct links to media files, live text transcription of your speech via the microphone, files from a folder (with or without subfolders) excluding those you choose, and a folder that transcribes files added to it even after the app has been restarted.
- All the files in a folder in one place: each file is displayed with its status, duration and size, as well as a preview of the text. You can then search, filter and sort the files, transcribe them again with different settings or export several files to a single TXT, Markdown or Word file.
- Private and offline: WhisperX can run on your computer's CPU, or much faster on an NVIDIA GPU with CUDA, or on a Mac's Apple Silicon GPU using MLX Whisper.
- Speaker identification, word-level timings, background noise reduction for quiet speakers and hum, and keywords and context to spell names and terms correctly.
- Translation while transcribing, with Whisper, or afterwards with OpenAI, Claude, Gemini, DeepSeek, Mistral, Grok, Ollama, DeepL, or Google Translate.
- A transcript you can play: click a subtitle to play it, change the speed, search (and replace) the text, watch videos with their subtitles, rename the speakers, and edit the text while maintaining the timestamps.
- Summaries with the key points and the chapters of the transcription.
- Questions about the transcription, answered by the language model you choose for them, with links to where the answer is said.
- Export to plain text, Markdown, Word, SRT, VTT, ASS (with a color per speaker), TSV, or JSON.
- Burn subtitles into the video to share it where subtitle files can't be loaded.
- History of all your transcriptions, with search, groups, pins, tags and notes. There is also a queue for transcribing while you continue working, and you will receive a notification when each transcription is ready or when a new file is added to a watched folder.
- Command-line interface for transcribing scripts.
- The interface in 22 languages, with a light, dark or system theme.
The full Audiotext documentation is available at getaudiotext.com, in all the interface languages (Català, Čeština, Deutsch, English, Español, Français, Galego, हिन्दी, Bahasa Indonesia, Italiano, 日本語, 한국어, Nederlands, Polski, Português, Română, Русский, Svenska, Türkçe, Українська, Tiếng Việt and 简体中文). The website opens in the language of your browser, and the app opens it in the language of its interface under Preferences → About → Documentation.
Both WhisperX and the Whisper API can transcribe and automatically detect about 100 languages. Audiotext transcribes the most common audio and video formats, including .mp3, .wav, .m4a, .mp4, .mkv, .webm, and exports to .txt, .md, .docx, .srt, .vtt, .ass, .tsv and .json. See the full lists in formats and languages.
ASCII folder structure
│ .env.example
│ .gitignore
│ .pre-commit-config.yaml
│ audiotext.spec
│ config.ini
│ LICENSE
│ pyproject.toml
│ README.md
│ uv.lock
│
├───.github
│ │ CONTRIBUTING.md
│ │ dependabot.yml
│ │ FUNDING.yml
│ │
│ ├───ISSUE_TEMPLATE
│ │ bug_report_template.md
│ │ feature_request_template.md
│ │
│ ├───PULL_REQUEST_TEMPLATE
│ │ pull_request_template.md
│ │
│ ├───scripts
│ │ build_bundle.sh
│ │ compile_translations.py
│ │ make_gpu_addon.py
│ │ smoke_test_app.py
│ │ update_translations.py
│ │
│ └───workflows
│ build.yml
│ code-quality.yml
│ release.yml
│
├───docs/ (images of this README)
│
├───packaging
│ ├───licenses
│ │ third_party_licenses.py
│ │ <license>.txt (license texts of the bundled third-party software)
│ │
│ ├───linux
│ │ install.sh
│ │ make_archive.sh
│ │
│ ├───macos
│ │ dmg-background.png
│ │ dmg-background@2x.png
│ │ dmg_settings.py
│ │ make_dmg.sh
│ │ make_dmg_background.py
│ │
│ └───windows
│ ChineseSimplified.isl (Inno Setup messages missing from Inno Setup 6)
│ installer.iss
│
├───res
│ ├───img
│ │ file-explorer.png
│ │ icon-dark.png
│ │ icon-light.png
│ │
│ ├───locales
│ │ │ audiotext.pot
│ │ │
│ │ └───<language>
│ │ └───LC_MESSAGES
│ │ audiotext.mo
│ │ audiotext.po
│ │
│ ├───macos
│ │ entitlements.plist
│ │ icon.icns
│ │
│ └───windows
│ icon.ico
│
├───src
│ │ app.py
│ │ cli.py
│ │ launcher.py
│ │
│ ├───controllers
│ │ __init__.py
│ │ directory_report.py
│ │ folder_transcriber.py
│ │ main_controller.py
│ │ mic_recorder.py
│ │ transcription_saver.py
│ │ transcription_validator.py
│ │
│ ├───handlers
│ │ __init__.py
│ │ ai_providers.py
│ │ audio_handler.py
│ │ google_api_handler.py
│ │ live_transcriber.py
│ │ openai_api_handler.py
│ │ summary_handler.py
│ │ transcribers.py
│ │ translation_handler.py
│ │ url_handler.py
│ │ whisperx_handler.py
│ │ youtube_handler.py
│ │
│ ├───interfaces
│ │ __init__.py
│ │ transcribable.py
│ │ transcriber.py
│ │ transcription_view.py
│ │
│ ├───models
│ │ │ __init__.py
│ │ │ history.py
│ │ │ summary.py
│ │ │ transcript_segment.py
│ │ │ transcription.py
│ │ │ transcription_settings.py
│ │ │ translation.py
│ │ │
│ │ └───config
│ │ __init__.py
│ │ config_ai.py
│ │ config_subtitles.py
│ │ config_system.py
│ │ config_transcription.py
│ │ config_whisper_api.py
│ │ config_whisperx.py
│ │
│ ├───utils
│ │ __init__.py
│ │ audio_player.py
│ │ audio_utils.py
│ │ cancellation.py
│ │ config_manager.py
│ │ constants.py
│ │ enums.py
│ │ env_keys.py
│ │ errors.py
│ │ exporters.py
│ │ folder_watcher.py
│ │ history_store.py
│ │ i18n.py
│ │ media.py
│ │ notifications.py
│ │ path_helper.py
│ │ progress.py
│ │ subtitle_cues.py
│ │ system.py
│ │ time_format.py
│ │ transcript_editing.py
│ │ update_checker.py
│ │ validators.py
│ │
│ └───views
│ │ __init__.py
│ │
│ ├───entries
│ │ __init__.py
│ │ delegates.py
│ │ entry_header.py
│ │ folder_view.py
│ │ progress_card.py
│ │ status_view.py
│ │
│ ├───history
│ │ __init__.py
│ │ formatting.py
│ │ history_row.py
│ │ history_sidebar.py
│ │
│ ├───main_window
│ │ __init__.py
│ │ entry_actions.py
│ │ main_window.py
│ │ top_bar.py
│ │ transcription_jobs.py
│ │ welcome_view.py
│ │
│ ├───new_transcription
│ │ __init__.py
│ │ microphone_view.py
│ │ new_transcription_view.py
│ │
│ ├───settings
│ │ │ __init__.py
│ │ │ option_labels.py
│ │ │ preferences_dialog.py
│ │ │ settings_form.py
│ │ │
│ │ └───cards
│ │ __init__.py
│ │ base.py
│ │ context_card.py
│ │ engine_card.py
│ │ folder_card.py
│ │ language_card.py
│ │ live_card.py
│ │ options_card.py
│ │ output_card.py
│ │
│ ├───style
│ │ __init__.py
│ │ icons.py
│ │ theme.py
│ │
│ ├───transcript
│ │ __init__.py
│ │ corrections.py
│ │ edit_dialogs.py
│ │ media_layout.py
│ │ player_bar.py
│ │ summary_panel.py
│ │ transcript_text.py
│ │ transcript_view.py
│ │ translation_panel.py
│ │ video_pane.py
│ │
│ └───widgets
│ __init__.py
│ bindings.py
│ button.py
│ level_meter.py
│ option_menu.py
│ pill.py
│ placeholder.py
│ scrollable_frame.py
│ search_entry.py
│ searchable_option_menu.py
│ splitter.py
│ stepper.py
│ text_dialog.py
│ textbox.py
│
└───tests/ (the test suite (pytest))
- CustomTkinter for the interface, and tkinterdnd2 for dropping files and folders on the window.
- WhisperX for fast automatic speech recognition on your computer. Uses faster-whisper, which is a reimplementation of OpenAI's Whisper model using CTranslate2, and pyannote.audio to identify the speakers.
- MLX Whisper, which runs Whisper on the GPU of Apple Silicon with MLX.
- PyTorch and Torchaudio, which WhisperX runs on, with CUDA for NVIDIA GPUs.
- OpenAI Python API library for the Whisper API, and for the summaries and translations with OpenAI, DeepSeek, Gemini, Mistral, Grok and Ollama.
- Anthropic Python API library for the summaries and translations with Claude.
- SpeechRecognition for the Google Speech-to-Text API.
- FFmpeg and pydub to extract and process the audio of the files.
- python-sounddevice to record from the microphone and play the audio of the transcriptions.
- pytubefix to download the audio of YouTube videos.
- python-docx to export Word documents.
- Babel for the translations of the interface and the names of the languages.
- keyring to keep the API keys in the credential store of the system, and python-dotenv to read them from
.envfiles. - Astro Starlight for the documentation website.
Download the file for your system from the latest release. FFmpeg is included, so you don't need to install anything else.
| System | File |
|---|---|
| macOS 15 or later (Apple Silicon) | Audiotext-X.Y.Z-macos-arm64.dmg |
| Windows (64-bit) | Audiotext-X.Y.Z-windows-x64-setup.exe |
| Linux (x86_64) | Audiotext-X.Y.Z-linux-x86_64.tar.gz |
- macOS: open the
.dmgand dragAudiotextintoApplications. The app isn't notarized, so allow it the first time inSystem Settings>Privacy & Security>Open Anyway. - Windows: run the installer. SmartScreen may warn you because the installer isn't signed. Click
More info>Run anyway. - Linux: extract the archive and run
./install.sh.
If you have an NVIDIA GPU, the installer on Windows and Linux offers to download GPU acceleration with CUDA. The installation guide explains each step and the requirements.
- Install the system dependencies: FFmpeg (required to process audio and video files) and PortAudio (required to record from the microphone and play audio). On Linux, PortAudio is requires; on macOS and Windows, it's included in the
sounddevicepackage:Homebrew's FFmpeg can't burn subtitles into videos, since it's built without libass. To burn subtitles into videos on macOS, build the version that the app bundles after cloning the repository, then add it to the# macOS brew install ffmpeg # Ubuntu/Debian sudo apt install ffmpeg libportaudio2 # Windows choco install ffmpeg
PATHvariable with the commandpackaging/macos/build_ffmpeg.sh && export PATH="$PWD/build/ffmpeg/bin:$PATH". - Clone the repository by running
git clone https://github.com/HenestrosaDev/audiotext.gitand change the current working directory toaudiotextby runningcd audiotext. - Install uv, which manages the project's dependencies and virtual environment. It also downloads a supported version of Python (3.10 to 3.13, since WhisperX doesn't support Python 3.14 yet) if you don't have one.
- Run
uv syncto create the virtual environment (.venv) and install the dependencies, including the development ones.uv syncinstalls PyTorch with CUDA support, which is a large download (several GB) on Linux and Windows. If you don't have an NVIDIA GPU, runuv sync --no-group cuda --group cpuinstead to install the CPU-only build. On macOS, the CPU build is always used because there's no CUDA, and Macs with Apple Silicon transcribe using their GPU with MLX Whisper.
- If you intend to contribute to the project, run
uv run pre-commit installto install the pre-commit hooks in your.git/directory. These hooks are required to contribute because they perform the same checks as the Code Quality workflow on each commit. This ensures that commits that would fail the checks are not created. - (Optional) You can set the API keys from the app. To set them in advance, copy the
.env.examplefile to the.envfile in your user configuration folder (see the notes below) and fill in the necessary information. The API keys can also be set as environment variables. - Run
uv run src/app.pyto start the program. The first time a WhisperX model is used, it's downloaded (from ~75 MB fortinyto ~3 GB forlarge-v2), so it may take a while. To try the program quickly, choose thetinymodel in theEnginesettings of the transcription. - (Optional) Run
uv run pytestto run the test suite.
- The project's
config.inifile contains the default settings and is never modified by the app. Your settings, history, and recordings are stored in your user configuration folder, or inAUDIOTEXT_CONFIG_DIR. The API keys are stored in the credential store of your system, or in environment variables, such asOPENAI_API_KEYandHF_TOKEN. For more information, see Files and Data.
The documentation explains how to use each feature:
- Your first transcription: the window and the keyboard shortcuts.
- Audio sources: files, URLs, the microphone and folders.
- Transcription settings: the language, the context and the options.
- Engines: WhisperX, the Whisper API and the Google API, and their models.
- The transcript: playing, searching and correcting the transcription.
- Summary, questions and translation: the AI providers and their models.
- History and preferences.
Audiotext can also transcribe from the command line, e.g. from scripts. The installed app runs it when a command is given:
| System | Command |
|---|---|
| Linux | audiotext (installed in ~/.local/bin by install.sh) |
| macOS | /Applications/Audiotext.app/Contents/MacOS/Audiotext |
| Windows | audiotext-cli.exe, in the folder where Audiotext is installed (%LOCALAPPDATA%\Programs\Audiotext by default) |
From the source code, run uv run src/cli.py instead:
# Transcribe a file. The text is also printed, so it can be redirected
audiotext transcribe interview.mp3 --language es --output-types txt,srt
# Transcribe the files of a folder identifying the speakers
audiotext transcribe recordings/ --diarize --speakers 2 --output-dir transcriptions/
# Save the subtitles and a Word document, summarize it, and translate it into Spanish
audiotext transcribe talk.mp4 --output-types srt,docx --summarize --translate-to es
# Transcribe the files added to a folder until stopped with Ctrl+C
audiotext watch inbox/ --output-types srt
# The same, transcribing first the files it already contains
audiotext watch inbox/ --existingThe transcription method doesn't save output types that it doesn't recognize (e.g., .md or .docx), so they are exported from its result. The --summarize option writes a *.summary.md file next to each transcription. The --translate-to option writes the translation in one of the output types (e.g., talk.es.srt), using the providers configured in the app unless the --summary-provider or --translation-provider options are specified.
Run audiotext transcribe --help to see all the options, or see the command-line interface.
See troubleshooting for common problems and their solutions. If yours isn't there, open an issue.
See the project backlog.
You can propose a new feature by creating a discussion!
- HenestrosaDev github@henestrosa.dev (José Carlos López Henestrosa)
See also the list of contributors who participated in this project.
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please read the CONTRIBUTING.md file, where you can find more detailed information about how to contribute to the project.
The interface is translated using gettext. Texts marked with one of the following:
_(), for texts that are translated once, when they are first displayed.L_()for texts that are translated again when the language changes.P_()for texts with a plural form.C_()for texts translated differently in a specific context.
The translations are in res/locales/audiotext.pot. Translations for each language are in res/locales/<language>/LC_MESSAGES/audiotext.po and are compiled into audiotext.mo files that the app loads.
After changing the text of the code or editing a .po file (e.g., with Poedit), run the following command:
uv run .github/scripts/update_translations.pyIt extracts the text into the template, updates the catalogs, and compile them. Then, it lists the texts that still need to be translated or reviewed. New texts are empty, and changed ones are marked as fuzzy. These texts are shown in English until they're translated and the fuzzy flag is removed.
Tests (tests/test_translations.py) fail when a catalog is out of date or when a translation doesn't keep the placeholders of the original text (e.g., {count}).
To add a language, first create its catalog. Then, add the language to the UI_LANGUAGES list in the src/utils/i18n.py file. Next, translate the language. Finally, run the script.
uv run pybabel init -i res/locales/audiotext.pot -d res/locales -D audiotext -l <code>
uv run .github/scripts/update_translations.pyThe source for getaudiotext.com is in the audiotext-docs repository. It's built with Astro Starlight and requires Node.js 22.12 or later. Each language has its own folder in src/content/docs (e.g., en, es or zh-cn), and the website's root redirects to the browser's language or English.
git clone https://github.com/HenestrosaDev/audiotext-docs.git
cd audiotext-docs
npm install
npm run dev # serves the website at http://localhost:4321
npm run build # builds the website into distUpdate the English page and its translations when a feature changes. Pages that haven't been translated yet are shown in English with a notice in the other languages.
See Releasing a Version in the contributing guide.
The following resources were used to create this project:
- Buzz, which inspired the folder watching, the transcript viewer, the speaker identification and the command-line interface.
- Extracting speech from video using Python
- How to translate Python applications with the GNU gettext module
- Speech recognition on large audio files
Distributed under the MIT license. See LICENSE for more information.
The app includes third-party software under its own licenses. For example, FFmpeg is licensed as GPL on Linux and Windows and as LGPL on macOS. These licenses are listed in THIRD_PARTY_LICENSES.txt, which is included with the app.
Would you like to support the project? That's very kind of you! However, I would suggest that you to consider supporting the packages that I've used to build this project first. If you still want to support this particular project, you can go to my Ko-Fi profile by clicking on the button down below!