Video Merge API

POST /merge_urls

About this tool

Playlist stitching, episodic compilations, and automated highlight reels belong on `/merge_urls`, where FFmpeg concatenates multiple remote assets with optional stylistic transitions. Pass an array-derived list of HTTPS locations plus `transition` (`fade`, `pixelize`, or `dissolve`) and the `duration` of the transition envelope in JSON; we handle demux synchronization, timeline assembly, and the async bookkeeping you’d rather not reimplement atop raw ffmpeg CLI strings. Subscription-gated API keys ensure fair sharing of muxer slots during traffic spikes.

Because merges pull every source sequentially, weakest-link networking dominates runtime: one slow CDN hop stalls the graph. Operational teams prefetch URLs via signed HEAD requests on their side, verify codecs match when possible, and only then trigger Droid Apps jobs. Unlike consumer joiners that upload each file manually, everything stays declarative: you emit JSON referencing already-hosted media, preserving provenance trails for rights management.

Transition math is FFmpeg-accurate, not Premiere-flexible; read the anchored docs when you wonder whether audio crossfades align with pixel transitions or if certain pixelization radii imply extra scaling. Extend the pipeline by preceding merges with `/cut` trims so bumpers snap cleanly between segments. When something fails midway, reuse the logged task IDs in support tickets so engineers can correlate internal traces quickly.

Expect larger output bitrates whenever transitions force full re-encoding; budget storage accordingly. QA teams often diff loudness profiles after merges; if levels swing wildly between sources, preprocess with normalization tools before hitting this endpoint. Throughout, remember there is zero multipart shortcut: every reel must already live at stable HTTPS URIs reachable without session cookies.

Operational playbooks mirror broadcast master control: log each constituent URL’s codec id, FPS, PAR, and channel layout before enqueueing merges so mismatches surface in spreadsheets instead of surprises at midnight. Teams on enterprise subscriptions occasionally mirror our queue depth dashboards into PagerDuty, waking someone only when SLA timers exceed thresholds. Developers building “one click highlight” UXes should prefetch poster frames from `/frame/last` in parallel while merges run so thumbnails appear instantly after polling completes.

Try it now

How it works

  1. List HTTPS sources

    Collect one URL per line in the `urls` textarea equivalent to a JSON array of strings. Each must be public and fetchable anonymously over TLS.

  2. Choose transition metadata

    Select `fade`, `pixelize`, or `dissolve`, then specify `duration` seconds so FFmpeg builds the matching filter graph before muxing outputs.

  3. Submit and poll asynchronously

    POST with your API key, capture `status_url`, and GET it until FFmpeg finishes or surfaces a descriptive failure for a given input index.

  4. Distribute merged master

    Download the stitched asset from the success payload and publish to streaming packaging workflows or archival buckets under your retention policy.

Frequently asked questions

How many clips can I stitch together?

There is no fixed small limit, but very long playlists take more time and may hit tier timeouts. Trim sources first or split into several merge jobs for hour-long compilations.

My clips have different resolutions: will merge still work?

FFmpeg can often reconcile mismatched sizes and frame rates, but some combinations fail. Transcode outliers to a common format before merging when QA shows glitches.

Do fade and dissolve transitions affect audio?

Transitions apply to both picture and sound according to the filter graph. See the API docs for how long the crossfade lasts relative to the duration you set.

Which plan includes transition effects?

Fade, pixelize, and dissolve transitions require Boost or Elite. Basic can merge clips without styled transitions.

One URL in my list failed: do I rerun the whole merge?

Fix or replace the bad URL and submit a new job. Each attempt gets its own task ID for tracking.

Why is the merged file larger than the sources combined?

Transitions force re-encoding, which can raise bitrate. Normalize loudness and resolution upstream if file size matters for delivery.

How do I use the Video Merge API?

POST to /merge_urls with a JSON body containing urls, transition and your X-API-Key header. The API returns a task_id; poll GET /task/{task_id} until status is "completed" to retrieve the download_url.

Via the REST API

curl -X POST https://droidapps.one/merge_urls \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_KEY" \
  -d '{
         "urls": "https://cdn.example.com/part1.mp4\nhttps://cdn.example.com/part2.mp4",
         "transition": "YOUR_TRANSITION",
         "duration": 0.75
       }'

Via the MCP server (droidapps-ffmpeg)

const job = await mcp.callTool("submit_job", {
  path: "/merge_urls",
  body: {
    urls: "https://cdn.example.com/part1.mp4
https://cdn.example.com/part2.mp4",
    transition: "YOUR_TRANSITION",
    duration: 0.75
  }
})
// Returns: { task_id: "abc123", status: "queued" }

const result = await mcp.callTool("wait_for_task", {
  task_id: job.task_id
})
// Returns: { status: "completed", download_url: "https://..." }