Escapement Studio
Escapement Studio is a personal application that produces original short-form educational videos and uploads them to its developer's own YouTube channels using the YouTube Data API. It is written in Python and runs on the developer's own computer and on a private server rented by the developer.
This is not a public product. Escapement Studio has exactly one user: the developer who wrote it. There is no sign-up, no user account system, no hosted service, and no way for anyone else to install or run it. It authorises only against YouTube channels owned by that same developer, and it never requests access to any other person's Google account or YouTube data.
Channels it uploads to. Each channel is authorised separately, and each has its own stored OAuth token on the developer's machine:
- Paper Empires
(
UCtmD1eUkrilPv_O89cquvLg) — the channel currently in use. Every public video on it was produced and uploaded by this application. - Escapement (
@escapementco) — a second channel by the same developer, being set up for English-language content. It has no videos yet.
What it does
Each production run turns a written editorial brief into one finished vertical video and publishes it. The channel currently in use carries two editorial lines: short Turkish-language explainers about the natural world, and English-language documentary shorts about documented business collapses. The second channel is being prepared for an English-language series about hidden mechanisms — how things actually work, why they fail, and what is commonly misunderstood about them — across four recurring series (mechanism, scale, creature, myth).
- Script drafting. A large language model drafts the narration from series briefs, structural rules and topic constraints that the developer writes and maintains by hand. Drafts are validated against length, structure and repetition rules before they proceed.
- Narration. The script is converted to speech by a third-party text-to-speech service.
- Visuals. Footage and images come from licensed stock libraries (Pexels, Pixabay) and from AI image generation. A local index prevents the same asset from being reused across videos.
- Captions. Word-level captions are produced by a speech-recognition model that runs locally on the machine, then burned into the video.
- Music and attribution. Background music is used only under licences that permit it. When a track requires attribution, the credit line is added to the video description automatically.
- Assembly. FFmpeg renders the final 1080×1920 MP4.
- Publishing. The finished file is uploaded to the developer's own YouTube channel through the YouTube Data API as a private video, with a scheduled publish time.
How it works
The application is a command-line program with an optional local web control panel. A single run of the full pipeline looks like this:
| Stage | What happens | Runs where |
|---|---|---|
| 1. Script | LLM drafts narration, title, description, tags and one pinned comment from the developer's series brief; output is validated and rejected if it breaks the brief's rules. | Third-party LLM API |
| 2. Voice | Narration text is synthesised to an MP3 track. | Third-party TTS API |
| 3. Visuals | Per-scene search terms fetch licensed stock media; some shots are generated with an AI image model. Duplicates are filtered out. | Stock & image APIs |
| 4. Edit | Transcription produces caption timings; FFmpeg assembles video, audio, captions and music into a 1080×1920 MP4. | Local machine |
| 5. Publish | Resumable upload to YouTube, then a scheduled publish time is set. One comment written in the script is posted on the video once it is public. | YouTube Data API |
Runs are triggered manually (python main.py pipeline), on a
schedule by a local daemon, or from the control panel. Interrupted runs
resume from the stage that failed rather than starting over.
Example of a production run
> python main.py pipeline
============================================================
TITLE : Why Escapement Wheels Tick
TOPIC : mechanical clock escapement
HOOK : The sound your clock makes is a controlled failure.
TAGS : #Escapement, #Horology, #Mechanism
SCENES : 7 scenes, ~44 seconds
============================================================
Voice ready: voiceover.mp3 (43.8 s)
Media ready: media/ (source mix: pexels=5, ai=2)
VIDEO READY: final.mp4
Duration : 44.2 s
Size : 11.4 MB
Captions : yes | Music: yes
YouTube upload starting: 'Why Escapement Wheels Tick' | 11.4MB | privacy=private
UPLOAD COMPLETE [OK] https://youtube.com/shorts/XXXXXXXXXXX (private)
Video XXXXXXXXXXX scheduled for 2026-07-29T13:00:00Z [OK]
How Escapement Studio uses YouTube API Services
Escapement Studio uses YouTube API Services. It authorises through Google OAuth against the developer's own Google account, and it holds one separate set of credentials per channel, each stored in its own local token file on the developer's machine.
OAuth scopes requested
| Scope | Why it is needed |
|---|---|
youtube.force-ssl |
Upload videos to the developer's own channel; set and read their privacy status and scheduled publish time; read the developer's own videos; post the developer's own first comment on the developer's own videos. |
yt-analytics.readonly |
Read aggregate performance metrics for the developer's own channel only, so the developer can decide which topics are worth continuing. Optional — the application still uploads without it. |
API endpoints called
| Endpoint | Purpose |
|---|---|
videos.insert (resumable upload) |
Upload a finished video file with its title, description, tags and status. |
videos.update (part=status) |
Set the scheduled publish time on a video that has already been uploaded. |
videos.list |
Read back the status and basic details of the developer's own uploads. |
channels.list (mine=true) |
Confirm which channel the stored credentials belong to and show the channel's own totals in the control panel. |
commentThreads.insert |
Post one comment, written as part of the script, on the developer's own video after it becomes public. |
reports.query (YouTube Analytics,
ids=channel==MINE) |
Retrieve aggregate metrics for the developer's own channel for a local report. |
The application never reads, writes, searches, scrapes or stores data belonging to any other channel, video or user. It does not resell, redistribute or expose YouTube API data to anyone.
Policy compliance
- Synthetic media is declared. Every upload sets
containsSyntheticMedia = true, because the narration voice and part of the imagery are generated. The corresponding disclosure is shown by YouTube on the video. - Audience is declared. Every upload explicitly sets
selfDeclaredMadeForKids = false. The channel is not directed to children. - Upload volume is capped. The application enforces its own daily upload limit and refuses to exceed it, as protection against both quota exhaustion and spam-like behaviour.
- No duplicate uploads. Once a production run records a video ID, that run can never upload again, so a retry cannot produce a second copy of the same video.
- Original content. Videos are assembled from newly written scripts, synthesised narration, and stock or generated imagery that is licensed for this use. The application never re-uploads or re-edits other people's videos.
- Language is declared. Each upload sets its
defaultLanguageanddefaultAudioLanguageexplicitly so that YouTube's translation and dubbing features are not fed incorrect metadata. - Attribution is automatic. Where a music track's licence requires credit, the credit line is inserted into the video description by the application, not left to memory.
Technical details
- Python 3.12, run from the command line; optional local control panel
built with FastAPI, bound to
127.0.0.1by default. - FFmpeg for rendering; a locally executed speech-recognition model for caption timing.
- YouTube uploads use the resumable upload protocol with 8 MB chunks and exponential backoff, so a dropped connection resumes instead of restarting.
- OAuth credentials are stored in a single local file on the developer's own machine. There is no user database and no cloud credential store.
- The application has no public interface. Nothing it runs is reachable by a third party.
Contact
Questions about this application, its use of YouTube API Services, or the policies below can be sent to sivrii1940@gmail.com. See the contact page for more detail.