VOD Dubbing Automation Example
Build an automated multi-video dubbing system with the MK.IO API and webhooks. Submit the dubbing jobs, then use webhooks to start track insertion when each job completes.
What you will build:
-
A job submission script that creates temporary assets and submits dubbing jobs
-
A webhook listener that automatically inserts dubbed tracks when jobs complete
Before starting you will need encoded source videos in separate assets
You need three English-language videos that are already encoded for streaming using the mp4-v4 format, each in its own asset with a .mpd manifest present (for example, video-001-encoded, video-002-encoded, video-003-encoded).
If you do not have these yet, follow the previous guide to upload, create assets, and run an encoding job before using this demo.
Prerequisites
Step 1: Install Python Packages
- Terminal window
Step 2: Install ngrok
Why ngrok? (local webhooks):Webhooks must call a publicly reachable HTTPS URL - localhost is not accessible from MK.IO’s servers.ngrok creates a temporary public URL that tunnels to your local Flask server so MK.IO can POST job events to your machine during development.In production, you can replace ngrok with a real HTTPS endpoint (cloud/app host) and keep the same webhook flow. Installing ngrok: macOS (Homebrew):
Windows (Chocolatey):
Linux:
Download from ngrok.com/download,
- unzip, and add the binary to your PATH
Step 3: Create Environment File
Create a file named .env in your project directory:
Add these lines (replace with your actual values):
How to get each value:
Step 4: Create Transforms
You need to create 4 transforms in your MK.IO project. These are reusable templates that define how to process videos.
Important: Refer to the VOD Dubbing Demo Guide section “Create Transforms” for the exact API requests. You need to create:
-
dubbing-multi-lang- The main dubbing transform (English → Spanish, German, French) -
insert-spanish- Add Spanish audio track -
insert-german- Add German audio track -
insert-french- Add French audio track
All 4 should return 200 OK.
Creating the Scripts
File 1: submit_jobs.py
This script creates temporary assets for dubbed audio and submits dubbing jobs.
Create a file named submit_jobs.py:
submit_jobs.py
Edit lines 23-26 and change VIDEOS to your actual video asset names
What it does:
-
For each video: creates a temp asset + submits a dubbing job
-
Takes ~1-2 seconds per video
-
Then exits and tells you what to do next
File 2: webhook_listener.py
This script receives webhooks from MK.IO and automatically handles track insertion.
Create a file named webhook_listener.py:
Webhook_listener.py
Running the Complete Pipeline
Step 1: Set Up ngrok Tunnel
Open a new terminal and run:
The terminal displays the forwarding URL:
Copy the HTTPS URL (the https://abc123def456.ngrok.io part).
Add /webhook to the end of the ngrok URL when creating the webhook rule below.
Step 2: Create Webhook Rule
Using Postman, make a PUT request:
Replace:
-
YOUR_PROJECT_NAMEwith your project name -
YOUR_API_TOKENwith your API token -
https://abc123def456.ngrok.iowith your ngrok URL from Step 3 +/webhook -
<YOUR_WEBHOOK_SECRET>with yourWEBHOOK_SECRETfrom.env
You should get 200 OK.
Step 3: Start the Webhook Listener
Open a terminal and run:
Output:
This server is now listening for webhooks on your local machine at localhost:5000.
Step 4: Submit Dubbing Jobs
Open a new terminal and run:
Output:
Monitor the workflow
The webhook listener terminal will start showing live updates:
You should also see on the MK.IO dashboard the jobs appear and complete, as well as assets being created and populated:
Jobs” src=“/images/mkio-vod-dubbing-multi-lang-2.png”/>
Once all jobs are complete you should see the following new tracks in your encoded assets:
From here you can set up your streaming endpoints and locators to playback and test the new dubbed audio!
Understanding the Code
Key Concepts
Job Naming Convention:
-
Dubbing jobs:
dub-{source_asset}→ Makes it easy to parse in webhooks -
Track insertion:
insert-{source_asset}-{lang}→ Identifies which video and language
Webhook Flow:
-
MK.IO processes a job
-
When complete, MK.IO POSTs to your webhook URL
-
Your webhook handler parses the job name
-
If it is a dubbing job, automatically submit track insertion.
-
If it is track insertion, log completion.
Authentication:
-
Webhook verification via Bearer token in Authorization header
-
This ensures webhooks come from MK.IO, not malicious third parties
Next Steps
Once you see this working, you can:
-
Add asset purging for dubbed-audio assets
-
Add automatic subtitle generation/ insertion stages
-
Scale to more videos
Remove hardcoded VIDEOS list
-
Query all assets via API
-
Loop through them
-
Optimise:
Submit multiple dubbing jobs in parallel
- Adjust delays and settings based on your needs
Key Files
-
submit_jobs.py- Submits the dubbing jobs (one-time run) -
webhook_listener.py- Listens for webhooks and auto-inserts tracks (long-running) -
.env- Your credentials (never commit to git)
Both scripts read from .env for configuration, so you only need to update credentials in one place.