Skip to content

Add apify-video-transcripts skill - #116

Open
steadyfetch wants to merge 2 commits into
apify:mainfrom
steadyfetch:add-apify-video-transcripts
Open

steadyfetch wants to merge 2 commits into
apify:mainfrom
steadyfetch:add-apify-video-transcripts

Conversation

@steadyfetch

Copy link
Copy Markdown

What this adds

skills/apify-video-transcripts/organic video and audio to text. One skill, four routing targets, all public pay-per-event Actors:

Source Actor
One YouTube video, Short or finished live VOD steadyfetch/youtube-transcript-scraper
A whole YouTube channel, de-duplicated, in one run steadyfetch/youtube-channel-transcripts
A creator's Instagram reels, with the first-3-seconds hook steadyfetch/instagram-reel-transcript-scraper
A podcast episode, a Loom, a Twitch VOD, an Archive.org item or a direct media file steadyfetch/media-transcriber

Output is the transcript plus timestamped segments and ready-made SRT / VTT.

Where it sits next to what already exists

The skill says this in its own first section, and routes users away from itself when something else is the better answer. The line is captions versus speech: a caption-only tool answers a video whose uploader turned captions on and returns nothing for one that did not — which is most re-uploads, many Shorts and reels, and live VODs. These Actors read captions first and fall back to speech-to-text, so the answer does not depend on the uploader, and a video with genuinely nothing spoken comes back as an honest uncharged row rather than as text a speech model invented over music.

  • pintostudio/youtube-transcript-scraper — named in the skill as the simpler tool when the video certainly has captions.
  • apify/instagram-reel-scraper — named as the right choice when the user wants reel metrics, not the spoken words.
  • apify-ad-creative-transcripts (my other skill, Add apify-ad-creative-transcripts skill #101) — named as the explicit boundary: paid ad creative from an ad library goes there, not here.

Validation

Every routed Actor was run live from the CLI, exactly as the skill writes the command, while this was written — 5 runs, ~$0.03 of owner usage. Field names, delivered statuses, the SRT output and the run-summary row come from those datasets rather than from schemas. Three things that only a live run surfaces are now warnings in the skill:

  • a charged: false repeat row still carries the full transcript, so a select(.charged == true) filter makes a working re-run look empty;
  • the text field is text on three Actors and transcript on the fourth, and the delivered status is ok on three and transcribed on the fourth;
  • steadyfetch/media-transcriber refuses a YouTube page with an uncharged unsupported_site row pointing at the dedicated Actor — so the skill routes by source, not by "it's a URL".

Checks run locally on this tree: scripts/lint_telemetry.sh ✅, scripts/lint_references.py --check-actors ✅, uv run scripts/generate_agents.py ✅ (generated files deliberately not committed). One skill, one directory, nothing else touched. Prices in the skill were read from each Actor's live pricing record on 2026-09-11 and the one record with a scheduled change says so in line.

Author: Steadyfetch. Disclosure: the steadyfetch/* Actors this skill routes to are paid, pay-per-event Apify Actors built and published by the author. No affiliate or referral parameters appear anywhere in this skill — every link is a plain Apify Store URL.

Organic video and audio to text: one YouTube video, Short or finished live VOD,
a whole channel in a single de-duplicated run, a creator's Instagram reels with
the first-3-seconds hook, and any podcast, Loom, Twitch VOD or direct media file
-- transcripts, timestamped segments, SRT and VTT.

Distinct from the caption-only tools the official index points at: these Actors
read captions first and fall back to speech-to-text, so an uncaptioned upload,
a live VOD or a Short still answers, and a video with nothing spoken comes back
as an honest uncharged row instead of hallucinated text.

Every routed Actor was run live while writing this (5 runs). Field names, the
delivered statuses, the repeat-row behaviour, the SRT output and the summary row
are taken from those datasets, not from schemas -- including two traps the skill
now warns about: charged:false repeat rows carry the full transcript, and the
text field is `text` on three Actors and `transcript` on the fourth.

Prices read live from each Actor's pricing record on 2026-09-11.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants