# AI Video Clipper: YouTube to Shorts, Reels & TikTok + Captions (`eliai/longform-to-shorts`) Actor

Turn a long YouTube video, podcast or interview into finished vertical Shorts, Reels and TikToks. AI picks the best moments; face-tracked 9:16 crop, word-by-word captions, hook title, plus SEO title, description and tags. $0.99 per Short, charged only when delivered.

- **URL**: https://apify.com/eliai/longform-to-shorts.md
- **Developed by:** [Broke to Built](https://apify.com/eliai) (community)
- **Categories:** Social media, Videos, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## AI Video Clipper: YouTube to Shorts, Reels & TikTok + Captions

**Turn one long video into finished vertical Shorts automatically.** Paste a YouTube link to a podcast, interview, keynote or stream. The AI Video Clipper finds the strongest moments, cuts each one into a 9:16 clip that makes sense on its own, tracks the speaker's face, burns in word-by-word captions and a hook title, and writes an SEO-ready title, description and tags for every clip.

$0.99 per Short delivered, with no subscription, no editor and no login. If no Short is delivered, nothing is charged.

### What you get for each Short

| | |
|---|---|
| **Video** | MP4, 1080×1920 (9:16), H.264 + AAC, loudness-normalized to -14 LUFS (YouTube's playback target) |
| **Edit** | Cold open: the most striking sentence plays first, then the context, then the payoff. Filler and tangents are cut. |
| **Framing** | Face-tracked vertical crop that re-frames on every camera change. Branded borders and letterboxing are trimmed automatically. |
| **Captions** | Word-by-word, active word highlighted, big bold type built for phone screens |
| **Hook title** | On screen for the first 3.6 seconds, placed below the face |
| **Credit** | Speaker and show name on screen, plus a link to the full source video in the description |
| **Metadata** | A title that names the speaker, a 2-3 sentence description stating who said what, and 12-18 search-phrase tags |
| **Why this moment** | One line on why a stranger would stop scrolling for it |

### How it works

1. **Transcribe.** The whole video is transcribed with Whisper (large-v3), with a timestamp on every word.
2. **Sentence-align.** The transcript is rebuilt into real sentences, so no cut ever starts or ends mid-sentence.
3. **Pick.** An AI editor reads the full transcript and proposes the strongest self-contained moments: surprising claims, stories and quotable lines that need no context.
4. **Quality gate.** Code rejects any proposal that is too short or too long (18-62 s), doesn't end on a full sentence, lacks metadata, or credits a person who appears nowhere in the video's title or transcript. The AI can't invent a speaker.
5. **Render.** Only the chosen seconds are used. Each Short is rendered frame by frame at 1080p with face tracking, captions and the hook.

### How long does it take, and why?

Measured on Apify's servers:

| Source video | Shorts | Run time |
|---|---|---|
| 3.4-minute interview | 1 | about 3.3 minutes |
| 66-minute podcast | 2 | about 10 minutes |

Most of the time goes to three things:

- **Downloading and transcribing the whole video.** The AI has to hear every minute to find the best one, so a longer source takes longer.
- **Reading the full transcript** to choose moments.
- **Rendering every frame** at full 1080×1920 with face tracking and captions: about 1-2 minutes per Short.

Asking for more Shorts from the same video adds only render time, because the video is downloaded and transcribed once. Start the run and come back to finished files. The default run timeout is 60 minutes; raise it for sources over about 2 hours.

### Input

| Field | Default | What it does |
|---|---|---|
| `videoUrl` | a 3-minute public-domain sample | A YouTube link, or any page or file yt-dlp can read (Vimeo, X/Twitter, direct .mp4) |
| `maxShorts` | 1 | Up to this many Shorts (1-10). The gate may return fewer if the video has fewer strong moments. You pay only for Shorts delivered. |
| `speakerName` | blank | Who to credit. Blank lets the AI name the guest, checked against the title and transcript. |
| `showName` | channel name | Shown in the on-screen credit |

### Copy-paste examples

**Input JSON.** Three Shorts from a podcast, crediting the guest:

```json
{
  "videoUrl": "https://www.youtube.com/watch?v=kwSVtQ7dziU",
  "maxShorts": 3,
  "speakerName": "Andrej Karpathy",
  "showName": "No Priors"
}
```

**curl.** Start a run and wait for the results in one call (replace `YOUR_TOKEN`):

```bash
curl -X POST "https://api.apify.com/v2/acts/EliAI~longform-to-shorts/run-sync-get-dataset-items?token=YOUR_TOKEN&timeout=3600" \
  -H "Content-Type: application/json" \
  -d '{"videoUrl": "https://www.youtube.com/watch?v=kwSVtQ7dziU", "maxShorts": 2}'
```

**JavaScript / Node.js** (`npm install apify-client`):

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('EliAI/longform-to-shorts').call({
  videoUrl: 'https://www.youtube.com/watch?v=kwSVtQ7dziU',
  maxShorts: 2,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const s of items.filter((i) => i.ok)) {
  console.log(s.title, s.videoUrl);   // MP4 link + ready-to-post title
}
```

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("EliAI/longform-to-shorts").call(run_input={
    "videoUrl": "https://www.youtube.com/watch?v=kwSVtQ7dziU",
    "maxShorts": 2,
})
for s in client.dataset(run["defaultDatasetId"]).iterate_items():
    if s["ok"]:
        print(s["title"], s["videoUrl"], s["tags"])
```

**Download every MP4 from a finished run** (bash + jq):

```bash
curl -s "https://api.apify.com/v2/datasets/DATASET_ID/items?clean=true" \
  | jq -r '.[] | select(.ok) | .videoUrl' | xargs -n1 curl -sO
```

**n8n / Make / Zapier.** Use the Apify app's "Run Actor" action with `EliAI/longform-to-shorts` and the input JSON above, then map `videoUrl`, `title`, `description` and `tags` straight into a YouTube, TikTok or Instagram upload step. Point a scheduled trigger at a channel's newest video to get Shorts every time a new episode drops.

### Output

One dataset row per Short. The MP4 is in the run's key-value store, linked from `videoUrl`.

```json
{
  "ok": true,
  "shortNumber": 1,
  "videoUrl": "https://api.apify.com/v2/key-value-stores/<store>/records/short-1-jensen-huang-culture-is-a-choice.mp4",
  "title": "Jensen Huang: Culture is a Choice",
  "description": "Jensen Huang, CEO of NVIDIA, explains that company culture is a direct result of the choices made during the employee selection process. He details the company's intense selectivity in hiring, offering to only 10% of interviewees with a 95% acceptance rate...",
  "tags": ["jensen huang", "nvidia", "company culture", "employee selection", "hiring process", "leadership", "..."],
  "durationSeconds": 50.88,
  "whyThisMoment": "A CEO reveals that company culture is a deliberate choice, not an accident.",
  "sourceUrl": "https://www.youtube.com/watch?v=Pnr_TVjYlj4",
  "sourceRangesSeconds": [[69.58, 75.0], [76.02, 99.235], [99.235, 121.435]],
  "width": 1080,
  "height": 1920
}
```

### Pricing

- **$0.99 per Short delivered.** This is the main charge.
- **$0.25 per extra hour of source video** past the first, charged only when at least one Short is delivered. A 66-minute podcast adds $0.25; a 20-minute interview adds nothing. It covers the download and transcription time that long sources need.
- **Never charged:** runs that deliver no Short, moments the quality gate drops, videos that can't be downloaded.

Example: 3 Shorts from a 90-minute podcast = 3 × $0.99 + 1 × $0.25 = **$3.22**.

### Use cases

- **Podcasters and YouTubers:** turn every episode into a week of Shorts, Reels and TikToks.
- **Clipping agencies and clipping campaigns:** batch long videos into ready-to-post clips via the API.
- **Social media managers:** repurpose webinars, keynotes and interviews without an editor.
- **Automation builders:** call it from n8n, Make, Zapier or your own code, then post with the YouTube Data API using the returned title, description and tags.

### FAQ

**How do I turn a YouTube video into Shorts automatically?**
Paste the video link into `videoUrl` and run. The AI Video Clipper transcribes the video, picks the best moments, and returns vertical 1080×1920 MP4s with captions, plus a title, description and tags for each.

**How do I turn a podcast into YouTube Shorts, Reels and TikToks?**
Use the podcast's YouTube (or video file) link. Podcasts and interviews are what it's built for: someone speaking on camera, with clear moments to cut.

**Is this an OpusClip alternative?**
It does the same job (long video in, captioned vertical clips out), but you pay per Short with no subscription, and it runs as an API you can automate.

**Does it add captions / subtitles?**
Yes. Word-by-word captions are burned into every Short, with the spoken word highlighted as it's said.

**Can I schedule the Shorts to YouTube?**
The output gives title, description and tags in the format YouTube's upload API expects. Upload as private with a `publishAt` date to schedule.

**What videos work best?**
Podcasts, interviews, panels, keynotes, lectures, streams and commentary. Music videos, silent footage and slides without a visible speaker are not a good fit.

**What languages?**
English works best. Other languages transcribe, but moment-picking quality varies.

**Why did my run return fewer Shorts than I asked for?**
The quality gate drops moments that cut mid-sentence or run too short or long. You are only charged for Shorts delivered.

### Limits and fair use

- Sources up to about 3 hours (raise the run timeout for long sources).
- Clip only content you have the right to use. Every Short credits the speaker and show on screen and links the full source in its description.

### Changelog

- **0.2 (2026-09-27):** first public release. Sentence-aligned cuts, face-tracked crop with automatic border trimming, word-by-word captions, hook title, AI-named speaker checked against the title and transcript, SEO/GEO metadata per Short.

# Actor input Schema

## `videoUrl` (type: `string`):

A YouTube link (or any page/file yt-dlp can read: Vimeo, X, direct .mp4). Podcasts, interviews, talks and streams work best: someone speaking to camera.

## `maxShorts` (type: `integer`):

The AI proposes the strongest moments and a quality gate drops weak cuts; you get up to this many. You pay only for Shorts delivered.

## `speakerName` (type: `string`):

Who the clip should credit and name in titles, e.g. `Andrej Karpathy`. Defaults to the channel name.

## `showName` (type: `string`):

Shown in the on-screen credit, e.g. `No Priors podcast`. Defaults to the channel name.

## Actor input object example

```json
{
  "videoUrl": "https://upload.wikimedia.org/wikipedia/commons/c/ce/2016-03-12_President_Obama%27s_Weekly_Address.webm",
  "maxShorts": 1,
  "speakerName": "",
  "showName": ""
}
```

# Actor output Schema

## `results` (type: `string`):

Every Short with its MP4 link, title, description and tags.

## `files` (type: `string`):

The rendered Shorts in this run's key-value store.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videoUrl": "https://upload.wikimedia.org/wikipedia/commons/c/ce/2016-03-12_President_Obama%27s_Weekly_Address.webm"
};

// Run the Actor and wait for it to finish
const run = await client.actor("eliai/longform-to-shorts").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "videoUrl": "https://upload.wikimedia.org/wikipedia/commons/c/ce/2016-03-12_President_Obama%27s_Weekly_Address.webm" }

# Run the Actor and wait for it to finish
run = client.actor("eliai/longform-to-shorts").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videoUrl": "https://upload.wikimedia.org/wikipedia/commons/c/ce/2016-03-12_President_Obama%27s_Weekly_Address.webm"
}' |
apify call eliai/longform-to-shorts --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eliai/longform-to-shorts"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CftwJtcSzelMj43W4/builds/Drfs6b8lbfQLYJeTQ/openapi.json
