Direct answer — How do you automate file transcription on a Mac? Three routes exist. Wire a shell script around whisper.cpp and ffmpeg, wrap it in a Shortcut, and maintain it yourself. Send files to a cloud transcription API and accept that the audio leaves your Mac. Or call a local HTTP API inside a transcription app, which keeps every file on the machine and needs no scripting to maintain.

If you want to automate transcription on a Mac, the hard part is rarely the speech recognition — local models have been good enough for years. It is the plumbing: the trigger, the format conversion, the queue, the export, and the thing that breaks after a Homebrew upgrade.

This guide compares the three routes — DIY scripts, macOS Shortcuts, and a transcription API local to your machine — with the code you would actually run for each.

What does automating transcription on a Mac actually involve?

Three layers, and only one of them is speech recognition. Confusing them is why most automation attempts stall halfway.

A cloud API collapses all three into one HTTP call, at the cost of uploading the audio. A DIY script gives you total control and all three layers to maintain. A local API keeps engine and audio on your Mac while still collapsing the call into one line.

Can macOS Shortcuts transcribe files on its own?

Not with a local engine, no. Shortcuts is excellent at triggers and plumbing — Apple describes a shortcut as “a quick way to get one or more tasks done with your apps” — but it ships no general-purpose offline transcription action you can point at an arbitrary MP4.

The community projects show the workaround. The shared mac shortcuts audio transcription repositories all work the same way: the Shortcut supplies the trigger and the file path, then a Run Shell Script action hands the work to an external engine.

One wraps a zsh script around the MacWhisper command line tool, falling back to whisper.cpp from Homebrew. Another imports a .shortcut calling a shell script that combines whisper.cpp with ffmpeg. Both make the same point: Shortcuts is the trigger, never the engine.

What does the DIY whisper.cpp route involve?

Setup and upkeep. The engine is free and excellent; the maintenance is the price, and it is not zero.

A minimal transcription automation script mac setup looks like this:

# 1. Install the engine and the converter
brew install ffmpeg
brew install whisper-cpp

# 2. Fetch a model file by hand (e.g. ggml-large-v3-turbo.bin)

# 3. Convert first — whisper.cpp's CLI reads 16-bit WAV only
ffmpeg -i input.mp3 -ar 16000 -ac 1 -c:a pcm_s16le output.wav

# 4. Then transcribe
whisper-cli -m ~/.cache/whisper.cpp/models/ggml-large-v3-turbo.bin -f output.wav

Step 3 is not optional. The official whisper.cpp README is explicit: “the whisper-cli example currently runs only with 16-bit WAV files, so make sure to convert your input before running the tool”, and it publishes the ffmpeg command above.

That constraint is where most whisper.cpp automation mac chains break: every new format, stereo interview and video container must be converted first, and the failure is silent until you read an empty transcript.

Add the other moving parts — renamed model files, a Homebrew upgrade, no job queue, no progress, no history — and an afternoon’s script becomes a small internal tool you now own. Our whisper.cpp setup guide covers that path in detail.

What is a local transcription API, and why does it change the workflow?

A local transcription API is an HTTP server running inside a desktop app on your own machine, so other programs can send it a file and get text back without any audio leaving the Mac. Same request shape as a cloud API, none of the upload.

Weesper Transcribe ships one as an optional Pro feature. It binds to the loopback address 127.0.0.1 — unreachable from your network — on a configurable port (8765 by default), it is off by default, and every endpoint except the health check requires an Authorization: Bearer token shown in Settings → Automation.

Two design details matter for automation:

The endpoints

EndpointAuthWhat it does
GET /v1/healthNoLiveness probe — status and version
GET /v1/modelsYesLists model ids and which are installed
POST /v1/transcribeYesSend audio bytes, get text and timestamped segments
GET /v1/jobs/<id>YesStatus, progress, then text and export path

Options ride as query parameters and anything you omit falls back to the app’s saved settings: model, language, task (transcribe or translate), format, name, export, async.

One call, end to end

TOKEN=   # copied from Settings → Automation

# Synchronous: transcribe and write an SRT into the auto-export folder
curl -s -X POST "http://127.0.0.1:8765/v1/transcribe?format=srt&name=meeting" \
     -H "Authorization: Bearer $TOKEN" \
     --data-binary @meeting.m4a | jq .text

# Asynchronous: long file, poll for the result
JOB=$(curl -s -X POST "http://127.0.0.1:8765/v1/transcribe?async=true&name=lecture" \
      -H "Authorization: Bearer $TOKEN" --data-binary @lecture.mp4 | jq -r .job_id)
curl -s "http://127.0.0.1:8765/v1/jobs/$JOB" -H "Authorization: Bearer $TOKEN" | jq

No conversion step, no model management, no queue to write. The response carries text and timestamped segments, and the app renders a file in the format you asked for — one of nine, including SRT and VTT when subtitles are the deliverable.

How do the three routes compare?

Match the route to what you are optimising for: control, privacy, or moving parts to own.

CriterionDIY scripts (whisper.cpp)Local API (Weesper Transcribe)Cloud transcription API
Audio leaves your Mac❌ Never❌ Never✅ Every file uploaded
Setup effortHigh — Homebrew, models, conversionLow — toggle on, copy tokenLow — API key
Format conversionManual (ffmpeg, 16-bit WAV)Handled by the appHandled by the service
Job queue and progressYou build itBuilt in, sync or asyncBuilt in
Works offline
Recurring costNoneOne-time Pro upgradePer minute or per seat
Who maintains itYouThe appThe vendor
History and searchYou build itBuilt in, keyword and semanticVendor-hosted

In short: DIY wins on control and costs only your time, cloud wins on scale and loses on confidentiality, and a local API is the middle path when the audio must not leave the machine.

Three automation recipes worth stealing

Start with the trigger you already use. The transcription step is one line in each.

  1. Finder Quick Action — build a Shortcut that takes files as input, add a Run Shell Script action with the curl call above and --data-binary @"$1", then right-click any recording to transcribe it. Keep the token in the script or a Keychain item, never in a URL parameter.
  2. Watched folder — point a Folder Action or a small fswatch loop at your recordings directory and fire the same call per new file. Set export=true and the transcript lands in your export folder.
  3. Orchestrator step — in n8n, an Execute Command node shells out to curl. Its documentation is explicit that the node runs commands “on the host machine that runs n8n”, “isn’t available on n8n Cloud”, and is disabled by default from n8n 2.0. A n8n local transcription step therefore needs a self-hosted instance on the same Mac — which is the point of a loopback API.

For a batch transcribe automation workflow, you may need no orchestrator at all: queue a folder inside the app, and use the API only for what your own tooling drives.

Which route should you choose?

Pick by the constraint that will not move.

Still weighing apps rather than routes? Our comparison of TranscribeNext and Weesper Transcribe covers the meeting-capture side of that decision.

Frequently asked questions

How do I automate transcription on a Mac without writing scripts?

Use an app that exposes a local transcription API, then call it from whatever already runs your work: a Shortcut, a Folder Action, a scheduled job or an n8n workflow. Weesper Transcribe ships an optional HTTP server bound to 127.0.0.1 and protected by a bearer token. One curl call sends the audio bytes and returns the text, plus a rendered file in your auto-export folder.

Can macOS Shortcuts transcribe an audio file on its own?

Not for arbitrary files with a local engine. Shortcuts is very good at the trigger and the plumbing: a Quick Action in Finder, a Folder Action, a share-sheet entry. The transcription has to come from somewhere, which is why the community shortcuts on GitHub wrap a Run Shell Script action around whisper.cpp or a third-party command line tool.

What does the DIY whisper.cpp automation route actually cost you?

Setup and maintenance rather than money. The published community scripts install ffmpeg and whisper.cpp through Homebrew, download model files by hand, and convert every input first, because the whisper.cpp command line tool runs only on 16-bit WAV files. A Homebrew upgrade, a renamed model file or an unhandled input format will break the chain quietly.

Is a local transcription API safe to leave switched on?

It depends on how it is bound and authenticated. The Weesper Transcribe API is off by default, listens only on 127.0.0.1 so it is unreachable from your network, and requires a bearer token on every endpoint except the health check. Requests carrying a browser Origin header are rejected, so a web page cannot call it behind your back.

Can I run a local transcription API from n8n or another automation tool?

Yes, when the tool runs on the same Mac. n8n’s documentation states that its Execute Command node runs shell commands on the host machine that runs n8n and is not available on n8n Cloud — so a self-hosted instance can shell out to curl, while a cloud instance cannot reach 127.0.0.1 on your laptop.

Conclusion

Automating transcription on a Mac has been possible for years, but only through scripts you had to build and keep alive. The community projects prove the demand and expose the cost: Homebrew dependencies, manual model files, a conversion step before every file.

A loopback API moves that work inside the app — same one-line call as a cloud service, same automation surface for Shortcuts, folder watchers and self-hosted orchestrators, and the audio never leaves the machine.

Ready to make transcription a pipeline step? See how Weesper Transcribe handles batches, exports and the local automation API, or get it from the Mac App Store — free to download, macOS 13 or later, one-time Pro upgrade, no subscription. Setup questions are answered in the support documentation.