DEV Community

Cover image for Transcribe TikTok and Instagram videos to text with Python (Whisper, no API key)
fguiraud · Data Tools
fguiraud · Data Tools

Posted on AI-assisted

Transcribe TikTok and Instagram videos to text with Python (Whisper, no API key)

Short videos are where a lot of today's marketing, product feedback and trends live, but the words are locked inside the video. TikTok and Instagram don't give you the transcript, and most videos have no captions.

The usual do-it-yourself route has three parts: download the video (TikTok and Instagram block many server IPs), extract the audio, and run a speech-to-text model. In this post I'll do all three with one API call from Python, and then go one step further: transcribe a whole TikTok account and rank its videos by views, with the first sentence of each one (the "hook").

Disclosure: I built the tool used here, Video to Text Transcriber on Apify. It runs open-source Whisper and costs $0.006 per minute of video; videos with only music are not charged. Apify's free plan includes monthly credits.

Setup

pip install apify-client
export APIFY_TOKEN=your_token
Enter fullscreen mode Exit fullscreen mode

Transcribe TikTok and Instagram links

import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("fguiraud/video-to-text-transcriber").call(run_input={
    "sources": [
        {"url": "https://www.tiktok.com/@tiktok/video/7689568478570843422"},
        {"url": "https://www.instagram.com/reel/C0hQSaMpD97/"},
    ],
    "outputs": ["text"],
})

for item in client.dataset(run.default_dataset_id).iterate_items():
    v = item.get("video") or {}
    views = f"{v['views']:,} views" if v.get("views") else "views not public"
    print(f"{v.get('platform')} | {v.get('author')} | {views} | {item['billedMinutes']} min")
    print("  ", item.get("text", "")[:110], "...")
Enter fullscreen mode Exit fullscreen mode

Real output (October 2026):

tiktok | tiktok | 335,300 views | 1 min
   You three look so good. I'm getting serious 2000 flashbacks. Thanks. I have this disposable camera. If I were  ...
instagram | NASA Goddard | views not public | 1 min
   Hey Space Nerds, I got a special delivery for you. So picture this. You're on a military range in the middle o ...
Enter fullscreen mode Exit fullscreen mode

Instagram doesn't make view counts public for every Reel, so that field can be empty; likes and comments are there. X (Twitter) and Facebook video links work the same way.

A whole TikTok account, ranked by views

Instead of collecting links by hand, give the account. This saves the newest videos of @nasa to a CSV with their date, views, likes and the first sentence of what is said:

import csv
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("fguiraud/video-to-text-transcriber").call(run_input={
    "profiles": ["@nasa"],          # or https://www.tiktok.com/@nasa
    "maxVideosPerProfile": 5,
    "onlyNewVideos": False,         # True on a weekly schedule: only new videos are transcribed and billed
    "outputs": ["text"],
})

rows = []
for item in client.dataset(run.default_dataset_id).iterate_items():
    if item.get("status") != "ok" or not item.get("text"):
        continue  # music-only videos come back as "no speech" and are not billed
    v = item["video"]
    hook = item["text"].split(". ")[0][:90]   # the first sentence: what grabs attention
    rows.append({"date": v["uploadDate"], "views": v["views"], "likes": v["likes"], "hook": hook, "url": v["url"]})

rows.sort(key=lambda r: r["views"] or 0, reverse=True)
with open("nasa_tiktok.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=rows[0].keys())
    writer.writeheader()
    writer.writerows(rows)
for r in rows:
    print(f"{r['date']}  {r['views']:>9,} views  {r['hook']}")
Enter fullscreen mode Exit fullscreen mode

Real output (October 2026):

2026-09-18    243,300 views  From the skies over Pittsburgh to the path back to the moon, NASA's mission kept moving fo
2026-09-17    163,800 views  NASA's reusable shuttle orbiter, part of a new, less expensive space transportation system
2026-09-25    105,900 views  This week NASA inspired future explorers, prepared the next crew for launch, studied life
Enter fullscreen mode Exit fullscreen mode

Five videos were requested and three rows came back: the other two had only music, so they were marked as having no speech and were not charged.

Track an account every week

Set "onlyNewVideos": True and run the script on a schedule (cron, or an Apify schedule on the Actor itself). Videos transcribed in earlier runs are skipped, so each week you pay only for what was posted since. That gives you a running log of what a creator or a competitor says, ready for a spreadsheet or an LLM summary.

Subtitles instead of text

Ask for "outputs": ["srt", "vtt"] and you get subtitle files with readable line lengths (42 characters, 2 lines), ready to re-upload with your own videos.

Cost

$0.006 per started minute of video, so a typical 15 to 60-second TikTok or Reel costs $0.006 and an account with 30 short videos about $0.18. Music-only videos and links that can't be downloaded (private videos, for example) are not charged. Instagram profiles can't be listed without a login, so for Instagram pass the Reel links.

Tips

  • Paste mixed lists: TikTok, Instagram, X and Facebook links, and direct MP4/MP3 files, all in one run.
  • Set "language": "es" (or any code) when you know the language; otherwise it's detected automatically.
  • Use "model": "small" for noisy audio or accents ($0.012 per minute, more accurate).

Questions or ideas for what to do with this data? Leave a comment.

Top comments (0)