Process user-generated content for moderation
Every upload needs to be screened before it goes live. โFeedloopโ (a social platform like Reddit or TikTok) processes thousands of video uploads per hour and routes each one through a review queue with representative thumbnails and a web-ready transcode.
Step 1: Extract thumbnails at intervals
Pull frames at regular intervals so moderators can scan the video without watching it:
ittybit image \
-i https://feedloop-app.com/uploads/user-video-8812.mp4 \
--start 2 \
--width 640 \
--format webpconst thumbnails = [2, 10, 30, 60].map((start) => ({
input: 'https://feedloop-app.com/uploads/user-video-8812.mp4',
kind: 'image',
options: {
start,
width: 640,
format: 'webp',
},
}));
for (const task of thumbnails) {
const res = await fetch('https://api.ittybit.com/jobs', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(task),
});
const data = await res.json();
}import requests
api_key = "your_api_key"
for start in [2, 10, 30, 60]:
task = {
"input": "https://feedloop-app.com/uploads/user-video-8812.mp4",
"kind": "image",
"options": {
"start": start,
"width": 640,
"format": "webp",
},
}
res = requests.post(
"https://api.ittybit.com/jobs",
headers={"Authorization": f"Bearer {api_key}"},
json=task,
)
data = res.json()TASK='{
"input": "https://feedloop-app.com/uploads/user-video-8812.mp4",
"kind": "image",
"options": {
"start": 2,
"width": 640,
"format": "webp"
}
}'
curl -X POST https://api.ittybit.com/jobs \
-H "Authorization: Bearer $ITTYBIT_API_KEY" \
-H "Content-Type: application/json" \
-d "$TASK" Repeat with start values at 10, 30, and 60 to cover the full video. Moderators see a filmstrip without downloading the original.
Step 2: Transcode for the review player
Moderators need a lightweight preview. Transcode to a capped resolution so the review UI loads fast:
{
"input": "https://feedloop-app.com/uploads/user-video-8812.mp4",
"kind": "video",
"options": {
"width": 720,
"format": "mp4",
"quality": "medium"
}
}
CLI
Run both steps locally:
# Thumbnails at 2s, 10s, 30s, 60s
for t in 2 10 30 60; do
ittybit image \
-i user-video-8812.mp4 \
-o "thumb-${t}s.webp" \
--start $t \
--width 640
done
# Review-quality transcode
ittybit video \
-i user-video-8812.mp4 \
-o review-preview.mp4 \
--width 720 \
--quality medium
Feeding the review queue
A typical webhook payload after both tasks complete:
{
"type": "job.succeeded",
"data": {
"id": "task_abc123",
"kind": "image",
"status": "completed",
"output": {
"url": "https://cdn.ittybit.com/feedloop/thumb-2s.webp"
}
}
}
Listen for job.succeeded events, collect the thumbnail URLs and the preview MP4, then insert a row into your moderation queue with the original upload ID and the generated assets.
Moderation pipeline summary
| Step | Kind | Output | Purpose |
|---|---|---|---|
| Thumbnails | image | 4 x WebP stills | Visual scan for reviewers |
| Transcode | video | 720p MP4 | In-browser preview playback |
Thumbnails arrive in seconds. The transcode follows. Once both are done, the upload is ready for a human decision.