Designing a Private Media Processing Workflow
A video-subtitle pipeline that uses Cloudflare for coordination and a local machine for private, CPU-heavy media work.
I wanted a private workflow that accepts a video, produces translated subtitles, and returns a finished file. My laptop should process the media, but it should not be the application server or the place where every file is handed around.
The resulting design is easiest to understand as one job moving through the system: intake, local processing, and output. Cloudflare keeps the handoffs durable; the processor handles the work that belongs on a private machine.
Follow one video through the pipeline
Cloudflare coordinates the job and stores the media. The local processor performs transcription, translation, and rendering.
- The owner starts a job in the browser and uploads a source video.
- The browser sends the video directly to R2, then confirms the upload with the Worker.
- A local processor polls for work, claims the job, and downloads the source directly from R2.
- It transcribes, translates, writes subtitles, and renders the finished video.
- It uploads the SRT and video to R2, reports completion, and the browser receives temporary download links.
The browser never needs storage credentials or a route to the local machine. The processor never needs to serve a public request. Those two boundaries keep the job simple to operate.
Intake: Cloudflare keeps the control plane small
Cloudflare Access protects the private browser interface. Workers Static Assets serves that interface beside a small API, so the dashboard and job endpoints can share one hostname without a separate application server.
The Worker creates a job record in D1 and issues a short-lived R2 upload URL. The browser transfers the video directly to R2, then marks the job ready. The Worker coordinates permission and state; it does not relay video bytes.
D1 stores ownership, input and output keys, state, lease information, attempts, and expiry times. R2 stores the source video, subtitle file, and rendered video. Keeping the bytes out of D1 makes the job record small and inspectable.
A scheduled Worker handles retention: it clears expired media and recovers jobs whose uploads or processing attempts did not finish. There is no queue or Durable Object today because one D1-backed job record and one processor are enough for this workload.
Processing: the local machine handles the heavy path
The processor initiates every connection over HTTPS and authenticates with a machine credential. It polls for ready jobs, claims one with a time-limited lease, and renews that lease while it works. No inbound port on the local machine is required.
After downloading the source from R2, the processor extracts audio and runs Whisper locally. The video and audio stay on the machine during transcription, which is the most sensitive and CPU-heavy stage.
Translation has a different boundary. The processor sends subtitle segments and any glossary context to a DeepSeek model through OpenRouter, then keeps the translated text with its timestamps for review. It does not send the original video to the translation service.
It then adjusts timing, writes an SRT file, and optionally burns the subtitles into the video. Each stage has an inspectable output: extracted audio, transcript, translated segments, SRT, and final render.
Output: return files without making the Worker a file proxy
The processor uploads the SRT and rendered video directly to R2, then marks the job complete in D1. The Worker verifies the state transition and gives the owner short-lived download links for the resulting objects.
If a stage fails, the job records a safe error category and retains the source for a short retry window. A processor that loses its lease cannot overwrite a newer attempt, and each retry starts from the R2 source rather than half-written local files.
The useful split is not “cloud versus local.” Cloudflare provides identity, coordination, durable state, and file handoff. The local processor owns the private, model-dependent work: Whisper transcription, DeepSeek translation, and video rendering.