Automate Shopify Product Videos with FFmpeg Micro

Every Shopify store with product videos runs into the same bottleneck. You shoot the video, export it, manually compress it so the page doesn't take 8 seconds to load, upload it to Shopify, and repeat for every SKU. If you sell 200 products, that's 200 manual video exports. If you sell across markets and need different aspect ratios for Instagram, TikTok, and your storefront, multiply that by three.
You can automate the entire pipeline by connecting Shopify webhooks to the FFmpeg Micro API. When a product gets a new video, a webhook fires, FFmpeg Micro compresses and reformats it, and the processed version writes back to Shopify through the Admin API. No manual exports. No video editing software.
The Architecture
The setup has three pieces:
- Shopify webhook fires when a product is created or updated
- Your server (a simple Node.js endpoint, Cloudflare Worker, or n8n workflow) receives the webhook, extracts the video URL, and sends it to FFmpeg Micro
- FFmpeg Micro processes the video and hits your callback URL when it's done
- Your callback handler takes the processed video and pushes it back to Shopify via the Admin API
No desktop software involved. Videos get processed in the cloud and land back in your Shopify product listing automatically.
Step 1: Get Your API Keys
You need two things:
- An FFmpeg Micro API key from ffmpeg-micro.com. The free tier works for testing and low-volume stores.
- A Shopify Admin API access token from your Shopify app settings (Settings > Apps and sales channels > Develop apps).
For the Shopify token, you need the write_products and read_products scopes at minimum.
Step 2: Send a Product Video to FFmpeg Micro
When you have a product video URL from Shopify, send it to the FFmpeg Micro API for processing. This example compresses to web-optimized MP4:
const API_KEY = process.env.FFMPEG_MICRO_API_KEY;
async function processProductVideo(videoUrl) {
const response = await fetch('https://api.ffmpeg-micro.com/v1/transcodes', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
inputs: [{ url: videoUrl }],
outputFormat: 'mp4',
preset: { quality: 'high', resolution: '1080p' },
}),
});
if (response.status !== 201) {
throw new Error(`Transcode failed: ${await response.text()}`);
}
const job = await response.json();
return job.id;
}
For e-commerce, file size matters more than anything. A 50MB product video that loads in 12 seconds on mobile will kill your conversion rate. This preset compresses while keeping visual quality high.
Step 3: Poll and Download the Result
After creating the job, poll until it finishes and grab the download URL:
async function waitAndDownload(jobId) {
const headers = { 'Authorization': `Bearer ${API_KEY}` };
while (true) {
const statusRes = await fetch(
`https://api.ffmpeg-micro.com/v1/transcodes/${jobId}`,
{ headers }
);
const job = await statusRes.json();
if (job.status === 'completed') {
const dlRes = await fetch(
`https://api.ffmpeg-micro.com/v1/transcodes/${jobId}/download`,
{ headers }
);
const { url } = await dlRes.json();
return url;
}
if (job.status === 'failed') {
throw new Error(`Job failed: ${job.error}`);
}
await new Promise(r => setTimeout(r, 2000));
}
}
Step 4: Generate Multiple Formats at Once
Product videos need different specs for different surfaces. Your Shopify storefront wants MP4. Instagram Reels wants 9:16 vertical. TikTok wants the same but with different bitrate preferences.
Run multiple transcode jobs from the same source:
async function processAllFormats(videoUrl) {
const formats = [
{
name: 'storefront',
outputFormat: 'mp4',
preset: { quality: 'high', resolution: '1080p' },
},
{
name: 'vertical-reel',
outputFormat: 'mp4',
options: [
{ option: '-vf', argument: 'crop=ih*9/16:ih,scale=1080:1920' },
{ option: '-c:v', argument: 'libx264' },
{ option: '-crf', argument: '23' },
],
},
{
name: 'thumbnail',
outputFormat: 'jpg',
options: [
{ option: '-ss', argument: '2' },
{ option: '-frames:v', argument: '1' },
{ option: '-vf', argument: 'scale=800:-2' },
],
},
];
const jobs = await Promise.all(
formats.map(async (fmt) => {
const body = { inputs: [{ url: videoUrl }], outputFormat: fmt.outputFormat };
if (fmt.preset) body.preset = fmt.preset;
if (fmt.options) body.options = fmt.options;
const res = await fetch('https://api.ffmpeg-micro.com/v1/transcodes', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
const job = await res.json();
return { name: fmt.name, jobId: job.id };
})
);
return jobs;
}
Three API calls, three outputs. Storefront MP4, vertical crop for Reels, and a thumbnail extracted from the 2-second mark.
Step 5: Wire Up the Shopify Webhook
Register a webhook through the Shopify Admin API that fires when products are updated:
const SHOPIFY_STORE = 'your-store.myshopify.com';
const SHOPIFY_TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
async function registerWebhook(callbackUrl) {
const res = await fetch(
`https://${SHOPIFY_STORE}/admin/api/2024-10/webhooks.json`,
{
method: 'POST',
headers: {
'X-Shopify-Access-Token': SHOPIFY_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
webhook: {
topic: 'products/update',
address: callbackUrl,
format: 'json',
},
}),
}
);
return res.json();
}
Your callback endpoint receives the product payload, checks for video media, and kicks off the transcode pipeline. In production, filter for new or changed media to avoid reprocessing videos that haven't changed.
Step 6: Complete Webhook Handler
Here's a full Express handler that ties the pieces together:
app.post('/webhooks/shopify/product-update', async (req, res) => {
res.status(200).send('OK');
const product = req.body;
const videos = (product.media || []).filter(
(m) => m.media_type === 'VIDEO' && m.status === 'READY'
);
for (const video of videos) {
const sourceUrl = video.sources?.[0]?.url;
if (!sourceUrl) continue;
const jobId = await processProductVideo(sourceUrl);
const processedUrl = await waitAndDownload(jobId);
console.log(`Processed ${product.title}: ${processedUrl}`);
}
});
Respond to Shopify immediately with a 200 (they'll retry if you don't), then process videos asynchronously. The processed URLs can go back into Shopify as external video sources, or you can download and re-upload them through the Shopify Staged Uploads API.
Common Pitfalls
Shopify webhook timeouts. Shopify expects a response within 5 seconds. Always respond with 200 immediately and do the actual processing in the background. If you try to process the video synchronously inside the webhook handler, Shopify will mark the webhook as failed and eventually disable it.
Product update loops. If your callback handler updates the product (to attach the processed video), that triggers another products/update webhook. Guard against this by checking whether the video has already been processed, or use a flag field in product metafields.
Video URLs from Shopify CDN expire. Shopify's video URLs are authenticated and time-limited. If you queue a job and don't start processing quickly, the source URL might expire before FFmpeg Micro can download it. Process videos promptly after receiving the webhook.
Aspect ratio math for vertical crops. The crop filter crop=ih*9/16:ih gives you a centered 9:16 crop from landscape footage. If your source videos are already vertical or square, this crop will cut off content. Check the source dimensions first and skip the crop if it's already the right ratio.
FAQ
Can I use this with Shopify's free plan?
Webhooks require a Shopify app with API access. You can create a custom app on any Shopify plan, including Basic. The webhook registration and Admin API access are available to all plans with app development enabled.
How much does video processing cost per product?
FFmpeg Micro charges by minutes of video processed. A typical 30-second product video costs fractions of a cent. If you process 200 product videos at 30 seconds each, that's about 100 minutes of processing. The free tier covers initial testing. See ffmpeg-micro.com/pricing for exact rates per plan.
Can I do this with Make.com or n8n instead of custom code?
Absolutely. FFmpeg Micro has a native Make.com integration and works with n8n via HTTP nodes. You'd set up a Shopify trigger module, connect it to the FFmpeg Micro transcode module, and map the output back. No code required.
What about Cloudinary? How does this compare?
Cloudinary offers video transformation as part of a broader media management platform. It works, but pricing scales with storage and transformations. For Shopify stores that just need video compression and format conversion without a full DAM, FFmpeg Micro is simpler and cheaper. You're paying for processing time, not storage or bandwidth.
Does this handle Shopify's 3D/AR media too?
No. FFmpeg processes video and audio files. Shopify's 3D models (GLB/USDZ) are a different media type. This pipeline only triggers on media_type === 'VIDEO'.
FFmpeg Micro handles the video processing so you can focus on selling products, not compressing files. Sign up for a free API key and automate your first Shopify product video today.
*Last verified: July 2026. Code examples tested against Shopify Admin API 2024-10 and FFmpeg Micro API v1.*
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

How to Add FFmpeg to an Airtable Automation
Connect Airtable automations to FFmpeg Micro API for automated video transcoding triggered by record changes.

FFmpeg in Make.com: 7 Scenarios That Don't Require Self-Hosting
Learn 7 Make.com video automation scenarios using the FFmpeg Micro API. Convert formats, trim clips, crop to vertical, compress, and add text with no servers.

FFmpeg in n8n: 5 Video Automations You Can Ship Today
Five copy-paste n8n workflows for video processing with FFmpeg Micro API: thumbnails, format conversion, batch resize, watermarks, and compression.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free