nickdin20 downloadsRecords the microphone, or a meeting (system audio plus microphone), into the daily log or the active note, with a level meter showing that audio is being captured.
An Obsidian plugin that records audio straight into your vault: a quick spoken thought into today's daily log, a note at the cursor, or a meeting or lecture with both sides of the audio (Meet, Zoom, Discord, anything that plays through your computer). Each recording can then be turned into text and handed to an agent that summarises or tidies it — or left as audio, which is all a fresh install does.
Everything runs inside Obsidian. There is no separate program to install and no native binary: the on-device speech engine is bundled into main.js in compressed form, which is why main.js is about 9.5 MB.
Numbers such as #82 in the code and its comments refer to the author's private design record, which is not published, and so do the files they cite that are not in this repository.
One recording at a time. Each mode is a toggle: click to start, click again to stop. Each has a ribbon icon and a command.
![[Recording …]] last under the notes heading of today's daily log, above the next heading of any level, creating the section if it is missing. The notes heading is a setting, text plus level, # Notes by default. It is found by its level and its text, regardless of capitals and runs of spaces: # notes and # Notes match # Notes, while another level or more words is a different heading. Refuses to start if today's daily log does not exist.While recording, a level meter appears as a fourth ribbon icon and moves with the audio. If it stops moving during a meeting, the system-audio side has gone quiet.
Files are named Recording YYYYMMDDHHMMSS.<ext> and land in the audio file folder from the settings (Obsidian's attachment folder when that setting is empty). The filename pattern is fixed, so other tools can rely on it. The format is chosen once when the plugin loads: .m4a where the platform supports it, otherwise .webm. .m4a names the container, not the codec — on desktop Obsidian the codec inside is usually Opus, on iOS AAC. The settings' Troubleshooting section shows the current choice.
Recordings are made at 32 kbit/s, mono, about 14 MB an hour. A phone is asked for the same and may ignore it, so a phone's files can be larger.
Each recording mode — daily log, cursor, meeting — has its own transcriber, which turns the recording into text, and its own agent, which acts on that text. Each can be None, and a fresh install has None everywhere: it records audio and nothing else until you choose. The text goes into a transcript note next to the recording (or in the transcript folder, when one is set).
The three transcriber kinds, and what each sends where:
<address>/audio/transcriptions — the request shape OpenAI made common: a multipart upload of the file and the model name, the language when you set one, and the key as a bearer token when you set one — and plain text comes back. Used for a meeting, it returns text without speakers.The two agent kinds:
<address>/chat/completions (the OpenAI-style chat request), with the key as a bearer token when you set one. Nothing else is sent.There is no on-device agent.
How the agent behaves:
- [ ] lines, nothing added that was not said.Speaker 1, Speaker 2 and so on; click a label to name it, from your own name and the meeting note's participant list. An agent that is sure may name them from the same list; the plugin ignores any name not on it, and a wrong name costs you one rename.https://api.anthropic.com/v1, model claude-haiku-5-5, and a key from platform.claude.com. On seven Swedish and English daily-log recordings it answered each in the transcript's language, in about two seconds, with nothing added, for under one cent in all. Your recording's text then leaves your device for Anthropic, and Anthropic describes this OpenAI-compatible address as meant for testing and comparing models rather than for production. Two small models run locally did not do the job in Swedish: llama3.2 added, repeated or garbled words, and qwen3.5:4b thought for over ten minutes on one sentence.Transcribe by hand. The command Transcribe this recording, used on an older recording, builds the request the recording would have had at stop, using the mode of the note that links it. The other commands — Cancel this recording's transcription, Try this recording's transcription again, Cancel this recording's agent — act on the recording in focus, and Open the transcription queue (also a ribbon icon) opens a side panel that lists the transcript notes by state — waiting, being transcribed, overdue, failed, finished recently and so on.
The plugin contacts nothing on its own. It reaches the network only in these cases:
huggingface.co), only when you press a speech model's download button in the settings. It fetches that model's files, pinned to one exact version, into the model folder (default vault-recorder/models, one subfolder per model). None of your recordings or notes are sent. Files you place there by hand count the same. The list holds four models: KB-Whisper tiny and base for Swedish, Whisper tiny and base for other languages; base is recommended in each.Authorization header to the address it belongs to.The settings' Troubleshooting section lists, for every mode, exactly what is sent where with your current choices.
The plugin lists your vault's notes, and the list stays on your device. Obsidian's plugin listing reports this as "Enumerates all files in the vault". The plugin goes through the list to pick out its own transcript notes, the ones with a rule-version property, using Obsidian's index of note properties, so going through the list opens no other note. It needs those notes to move each recording through its transcriber and agent, to draw the transcription queue, to delete audio whose keep time has passed and count what a shorter keep time would delete, to let go of this device's own unanswered requests when Obsidian starts or you come back to it, and for Transcribe this recording to find a recording's note and mode. Separately, it reads Obsidian's index of links to find the notes that link to a recording: Transcribe this recording uses them to tell the mode, and the entries that remove a recording use them to say what can be done and which notes are affected. Neither the list nor the index is sent anywhere. The only notes the plugin sends are the ones named above, to a service agent you chose.
Keys stay on each device. A key is kept in Obsidian's Keychain and typed once on each device that needs it; the settings file holds only its name, so Obsidian Sync never carries a secret. This needs Obsidian 1.11.4 or newer.
Undocumented API. While Use the Daily notes settings is on, the plugin reads the daily-log folder and filename pattern from the core Daily Notes plugin's configuration through an internal Obsidian API that is not documented. If that ever breaks, switch the setting off and fill in the two fields by hand.
At 32 kbit/s a minute is about 240 kB. The plugin never splits a recording: one over a service's limit is refused and shows as failed, and you pick a service with a higher limit, or hand-off. The services' published limits, read on 2026-10-02, as minutes of recording:
| Service | Limit | Minutes at 32 kbit/s |
|---|---|---|
| OpenAI | 25 MB | 104 |
| Groq, free tier | 25 MB | 104 |
| Groq, paid | 100 MB | 416 |
| Together AI | 80 MB per upload | 333 |
| Mistral (Voxtral; no Swedish) | 1 GB and 3 hours | 180 |
| A server you run (Speaches, LocalAI, whisper.cpp) | none documented | not measured |
Services that use their own request format instead of OpenAI's — Deepgram, AssemblyAI, ElevenLabs, Speechmatics, Gladia, Azure — cannot be used.
Obsidian Sync Standard carries no file over 5 MB — about 21 minutes of recording. A hand-off recording that Sync does not carry never reaches your program and goes overdue in the queue. On Sync Standard, hand-off therefore works for recordings under about 20 minutes; longer ones need an on-device transcriber, or a service on the recording device. Sync Plus carries 200 MB.
The plugin's own file is over that limit too, which is the warning Obsidian's plugin listing shows. main.js is about 9.5 MB because it holds the speech engine that on-device transcription runs on. Fetching the engine after installation would come close to Obsidian's rule that a plugin must not install its own dependencies, so it ships inside the file. The speech models are not in the file; they are the separate downloads described under Outside addresses the plugin contacts. On Sync Standard, whichever transcriber you use, Sync does not carry the plugin between your devices: install it on each device, as described under Install.
iPhone and Android follow the same rules; they were measured on an iPhone, and Android has not been tested. A phone records in daily-log and cursor mode only; the meeting mode is desktop only. A mode's transcriber and agent apply as chosen.
http://) makes the recording wait with the reason, and a serving device takes it.Four entries take a recording out of a note: Remove link, Remove link and audio, Remove everything and Delete audio.
Per mode: a transcriber and an agent, with their fields (speech model; or address, key name and model; and for an agent, the instruction and a context note). Also the notes heading (text and level), Your name, the participant list property, the language spoken in recordings, the daily-log folder and filename pattern (or Use the Daily notes settings), the audio, transcript and model folders, the keep time and the overdue time, This device (its name and whether it is the serving device), Keep the screen awake while recording, and a read-only Troubleshooting section.
From Obsidian's community plugins, once the plugin is listed there: Settings → Community plugins → Browse, search for Vault Recorder, install and enable it.
By hand: download main.js, manifest.json and styles.css from a release and copy them into <your vault>/<config folder>/plugins/vault-recorder/ (the config folder is .obsidian unless you changed it), then enable the plugin under Settings → Community plugins.
Needs Node.js and npm.
npm ci # install dependencies
npm run build # type check, then bundle into main.js
npm test # run the tests
npm run lint # Obsidian's lint rules
npm test runs the tests without type-checking them; npm run build is the type check.
src/ holds the plugin's modules, each beside its tests; each module's header says what it does. The hand-off rule and its example notes are in docs/.
MIT. See LICENSE.