How to Repurpose YouTube Videos to Shorts, Reels, and TikTok
Turn one long-form YouTube video into vertical clips for Shorts, Reels, and TikTok. ffmpeg recipe + Postproxy publishing in one workflow.
The two halves of repurposing
The pipeline is two steps:
- Transform — long 16:9 → short 9:16. This is video work: crop, pad, trim. ffmpeg is the standard tool.
- Distribute — push the resulting MP4 to Shorts, Reels, and TikTok. This is API work, and it’s where Postproxy fits.
We’ll cover both, and how they connect.
Step 1 — crop and trim with ffmpeg
A 16:9 source at 1920×1080 needs to become 1080×1920. The simplest options:
Center crop (loses left/right edges):
ffmpeg -ss 00:01:30 -t 00:00:55 -i source.mp4 \ -vf "crop=608:1080:656:0,scale=1080:1920" \ -c:v libx264 -preset fast -crf 22 \ -c:a aac -b:a 128k \ -movflags +faststart \ short.mp4-ss 00:01:30 -t 00:00:55 extracts a 55-second clip starting at 1:30. The crop=608:1080:656:0 takes a vertical slice from the center.
Blurred background (keeps full frame):
ffmpeg -ss 00:01:30 -t 00:00:55 -i source.mp4 \ -vf "split[a][b]; \ [a]scale=1080:1920,boxblur=20:5[bg]; \ [b]scale=1080:-1[fg]; \ [bg][fg]overlay=(W-w)/2:(H-h)/2" \ -c:v libx264 -preset fast -crf 22 \ -c:a aac -b:a 128k \ -movflags +faststart \ short.mp4This produces a 1080×1920 video with the original 16:9 video centered over a blurred background — the look that’s become standard on Reels and Shorts.
The output short.mp4 satisfies the spec intersection in our cross-post guide. Upload it to your CDN.
Step 2 — publish to all three in one call
curl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "55 seconds: how we cut our publishing latency in half.\n\nFull video on YouTube ↓" }, "profiles": ["youtube", "instagram", "tiktok"], "media": ["https://yourcdn.com/short.mp4"], "platforms": { "youtube": { "title": "How we cut publishing latency in half (55s)", "privacy_status": "public" }, "instagram": { "format": "reel" }, "tiktok": { "privacy_status": "PUBLIC_TO_EVERYONE" } } }'Postproxy handles each platform’s upload flow:
- YouTube → resumable upload, sets title and description (the post body becomes the YouTube description). YouTube auto-classifies the upload as a Short when the file is 9:16 and ≤60s.
- Instagram Reels → container creation, processing wait, publish. The
format: "reel"flag is what routes the video to Reels instead of feed video. - TikTok → direct post upload, processing poll, publish.
privacy_statusis required.
A scripted end-to-end pipeline
pip install postproxy-sdk
import asyncioimport osimport subprocessfrom postproxy import ( PostProxy, PlatformParams, YouTubeParams, InstagramParams, TikTokParams,)
SOURCE = "long-form.mp4"CLIP_START = "00:01:30"CLIP_LEN = "00:00:55"OUTPUT = "short.mp4"CDN_URL = "https://yourcdn.com/short.mp4"
async def main(): # 1. Cut + reformat subprocess.run([ "ffmpeg", "-y", "-ss", CLIP_START, "-t", CLIP_LEN, "-i", SOURCE, "-vf", "split[a][b];[a]scale=1080:1920,boxblur=20:5[bg];[b]scale=1080:-1[fg];[bg][fg]overlay=(W-w)/2:(H-h)/2", "-c:v", "libx264", "-preset", "fast", "-crf", "22", "-c:a", "aac", "-b:a", "128k", "-movflags", "+faststart", OUTPUT, ], check=True)
# 2. Upload to your CDN (S3, R2, etc.) upload_to_cdn(OUTPUT, CDN_URL)
# 3. Cross-post via Postproxy async with PostProxy(os.environ["POSTPROXY_API_KEY"], profile_group_id="pg-abc") as client: post = await client.posts.create( "55 seconds on the new release. Full video on YouTube ↓", profiles=["youtube", "instagram", "tiktok"], media=[CDN_URL], platforms=PlatformParams( youtube=YouTubeParams( title="Release deep-dive (55s)", privacy_status="public", ), instagram=InstagramParams(format="reel"), tiktok=TikTokParams(privacy_status="PUBLIC_TO_EVERYONE"), ), ) print(post.id, post.status)
asyncio.run(main())Schedule this with cron, n8n, or a queue worker — see scheduling with cron and API.
Picking the right clip
Cropping is mechanical; what to crop is editorial. Common heuristics:
- The first 60 seconds — the YouTube hook is often the best opener for a Shorts version.
- A timestamped highlight — many YouTubers already mark “best moments” in chapters; reuse those timestamps.
- A captioned segment — pick a 30-second answer to a specific question and put the question on screen as a caption.
If you’re piping this through an LLM that picks timestamps from the YouTube transcript, the only thing that changes in the script above is CLIP_START and CLIP_LEN.
Different format per platform
The media array on a single post applies to every targeted profile — there’s no per-platform media swap. If you want a 60-second cut for Shorts and a 90-second cut for Reels and TikTok, run ffmpeg twice and send two requests:
# YouTube Shorts — 60scurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Highlights from this week's stream." }, "profiles": ["youtube"], "media": ["https://yourcdn.com/short-60s.mp4"], "platforms": { "youtube": { "title": "Stream highlights", "privacy_status": "public" } } }'
# Reels + TikTok — 90scurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Highlights from this week's stream." }, "profiles": ["instagram", "tiktok"], "media": ["https://yourcdn.com/short-90s.mp4"], "platforms": { "instagram": { "format": "reel" }, "tiktok": { "privacy_status": "PUBLIC_TO_EVERYONE" } } }'Why this is worth automating
Manual repurposing is a 30-minute job per video — open editor, scrub for highlights, crop, export, upload three times, write three captions. Doing this on a 3-per-week schedule is 4-5 hours a month of menial work. The script above runs in under 60 seconds and three of the four platforms confirm publish within 2 minutes.
For the cross-platform spec table and partial-success behaviour, see the cross-post guide and the blog post comparing Reels, TikTok, and Shorts publishing flows.