Skip to content
streamneo.
Tools14 min read

How to Make FFmpeg Crossfade Between Videos in a YouTube Livestream

Build a two-video FFmpeg xfade, understand timing and audio choices, and test a filtered feed before sending it to YouTube Live.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

To crossfade two videos in an FFmpeg YouTube livestream, connect their video streams with xfade in a -filter_complex graph, encode the filtered output, and send it to YouTube’s ingest address. The transition’s duration and offset must match the clips’ actual timelines, and the inputs need compatible video parameters.

This is a transition between two inputs in one encoded feed, not a playlist scheduler. The example below gives you a starting point to adapt and test; it is not guaranteed to work unchanged with arbitrary media, make every transition seamless, or schedule an endless playlist.

What xfade does in a live workflow

FFmpeg’s xfade filter blends one decoded video stream into another over a specified interval. For a live workflow, FFmpeg reads both inputs, applies the filter, encodes the resulting frames, and sends the output to an ingest destination. The transition happens as the feed is being processed; it is not an instruction to YouTube to combine uploaded files.

The distinction matters if your goal is simply to prepare a finished video. You can render a transition to a file before going live, then stream that file. If the transition needs to happen during transmission, you need a running FFmpeg process that has access to both inputs and can keep encoding and sending its output. Filtering changes the frames, so the video cannot be passed through with stream copy. FFmpeg’s command-line documentation explains that filtering is a common reason to transcode and that streams are transcoded by default unless copying is requested.

A two-input filter graph is also not a complete 24/7 scheduling system. It has a defined set of inputs and transition points; it does not decide which programme comes next tomorrow, recover a playlist schedule after a reboot, or endlessly cycle through a library by itself. If you need planned changes without ending a broadcast, see how to schedule a playlist change without ending a YouTube livestream. That is a different operational problem from blending a particular pair of clips.

A hard cut may be preferable when the clips are unrelated, their audio should not overlap, or the source timing is unpredictable. A crossfade is useful when a gradual visual hand-off is part of the programme, such as moving from one devotional artwork to another. Decide first whether you need a visual transition, an audio transition, or both: xfade only addresses the video.

Check duration and stream compatibility first

Before writing a graph, inspect each source file. You need to know which streams exist, the video dimensions and frame rates, how long the usable video runs, and whether each clip has audio. FFmpeg’s ffprobe can report stream and format details; a simple starting inspection is:

ffprobe -v error -show_streams -show_format first.mp4

Repeat it for the second file. Do not assume that two files with the same extension have the same properties. One might be 1920 by 1080 at 25 frames per second while another is 1280 by 720 at a different rate or has a different pixel format. A filter may reject incompatible parameters, or the output may not behave as you expect.

The command later in this article is intentionally minimal. It assumes compatible inputs and a particular audio choice. If FFmpeg reports that xfade cannot configure, inspect the installed filter’s help and normalise the sources to consistent dimensions, frame rate, time base and pixel format as needed. There is no universal normalisation chain that is right for every pair: scaling, cropping, padding and frame-rate conversion each change the resulting picture or cadence.

A practical way to reduce surprises is to create two short test clips with the same intended output properties before using full-length media. Keep an eye on variable frame rate sources, unusual rotations, and clips that start with offset timestamps. If you find such issues, make a standardised intermediate copy or add appropriate filters ahead of xfade, then test the resulting graph. The correct filters depend on the files, so verify the output rather than copying a long conversion chain blindly.

Duration is just as important as compatibility. The offset is measured on the active timeline, and the transition must begin while the first stream still has frames available and continue for the requested duration. A fade that starts too late can overrun the first clip; one that starts earlier than intended can hide too much of it. Identify the usable endpoint of the first clip, not merely the duration displayed by a media player if the file has unusual timestamps or trailing material.

If you are preparing a radio-style channel, remember that a valid picture transition does not determine how music or narration should behave. You may want a continuous soundtrack independent of the visual clips. For a computer-based playback setup, the guide to OBS media source loop settings for YouTube Live covers a different route for looping media; it does not replace the timing work needed for an FFmpeg graph.

Build a two-video filter graph

For two compatible inputs, a compact starting command is:

ffmpeg -re -i first.mp4 -re -i second.mp4 \
  -filter_complex "[0:v][1:v]xfade=transition=fade:duration=2:offset=8[v]" \
  -map "[v]" -map 0:a? \
  -c:v libx264 -c:a aac -f flv \
  "rtmps://YOUR_YOUTUBE_INGEST/YOUR_STREAM_KEY"

Replace the destination with the RTMPS ingest address and stream key shown in YouTube Live Control Room. Keep the key private. The placeholders are not a real destination, and the command is not a tested end-to-end broadcast recipe for your files or account.

The first -i is input 0 and the second is input 1. Within the graph, [0:v] selects the first video stream from the first input, and [1:v] selects the first video stream from the second. The xfade filter combines them and the label [v] names its output. The -map "[v]" option tells FFmpeg to include that labelled video in the output. Complex graphs are useful when multiple inputs feed filters and labelled graph outputs need to be mapped; see the FFmpeg documentation on filtergraphs and stream selection.

transition=fade selects the transition style. FFmpeg supports multiple transition options; check the filter reference for the options supported by your installed build and their behaviour. A simple fade is often easier to evaluate than a more decorative wipe, because it makes timing and image compatibility easier to see.

The two -re options read each input at its native rate rather than consuming it as fast as possible. They do not turn the command into a playlist manager or guarantee that the output will remain live indefinitely. The process still depends on the inputs, encoder workload, network path and correct output settings. If your source files have different lengths or the command reaches the end of its inputs, the process will not automatically invent the next programme segment.

The optional audio mapping -map 0:a? means include audio from input 0 if it exists. The question mark makes that map optional, so the command does not fail merely because the first input has no audio stream. It also means this example does not crossfade the audio from the two files. Change the maps deliberately to reflect what you want viewers to hear.

Choose duration and offset from the timeline

In xfade=transition=fade:duration=2:offset=8, duration=2 requests a two-second visual blend, while offset=8 sets the point where it begins on the first input’s timeline. These values illustrate the syntax, not a recommended timing for every clip. If the first clip should play for longer, calculate a later offset; if the overlap should be gentler, choose a longer duration and confirm there are enough frames on both sides.

Think of the transition as an overlap, not as extra programme time. If the first clip ends at its normal endpoint and the second joins before that endpoint, the total combined timeline is shorter than the sum of both clip durations by the overlap. This is why the next transition in a longer chain cannot simply be placed at the next source file’s original start time.

A useful planning method is to write down the first clip’s usable duration, the desired transition length, and the intended start point. Check that the start plus transition length does not exceed the available first-clip material. Then verify where you want the second clip to finish relative to the first clip’s timeline. Use actual timestamps from your sources, and render a local test around the transition before sending it to an audience.

When chaining more than two clips, apply each later xfade to the timeline already produced by the previous filters. Calculate offsets after accounting for previous overlaps. A three-clip graph is not just a matter of adding [2:v] and repeating the same offset: each stage has its own accumulated programme duration. Sketch the durations and overlaps first, then inspect the output around every join. If the arithmetic is uncertain, render a short local segment and check the timestamps and visible result before building a longer graph.

Decide what should happen to audio

The video xfade filter does not mix sound. If you map only 0:a?, viewers hear the first input’s audio when it exists, while the second clip’s audio is not blended in by that video filter. This can be the right choice if the first clip holds a continuous music bed or narration for the whole programme, but it can be wrong if each clip has its own essential sound.

For two clip-specific audio tracks that should overlap, use FFmpeg’s separate acrossfade audio filter and map the resulting labelled audio stream. The FFmpeg filter documentation describes acrossfade as a crossfade between audio inputs with a configurable duration. It requires its own graph and timing decisions; matching its overlap to the picture is a production choice, not something xfade does automatically.

For a continuous programme soundtrack, map that intentional audio source instead of treating incidental clip audio as the programme. Check that the output has an audio track, that the chosen source remains available for the whole segment, and that the level does not jump when the image changes. A missing audio map can result in a silent broadcast even when the video appears correct in a local preview.

The easiest way to make an audio decision is to listen to the transition, not just watch it. If the image fades but the soundtrack cuts abruptly, that may be acceptable for a news or visual information loop, but it can sound jarring in bhajans or lofi music. If audio fades while the image holds, that may also be intentional. Treat the picture and sound as separate tracks and verify both.

Encode the filtered output for YouTube Live

Because xfade operates on decoded pictures, the filtered video must be encoded. In the example, -c:v libx264 chooses H.264 video encoding and -c:a aac chooses AAC audio encoding. Do not replace the video encoder with -c:v copy: stream copy bypasses the frame processing needed to create a crossfade. Encoding adds work for the computer or other machine running FFmpeg, so test whether it can sustain the chosen output settings before relying on it through a long session.

Select a resolution, frame rate and bitrate that fit both the programme and your available upload connection. YouTube’s live encoder settings guidance lists supported ingest codecs and recommends CBR bitrate encoding and a two-second keyframe interval, which should not exceed four seconds. These are platform recommendations, not proof that your connection can sustain a particular stream. As listed on YouTube Help’s guidance page accessed in October 2026, 1080p at 30 frames per second using H.264 has a 5 Mbps minimum and 14 Mbps recommended bitrate. Check the current page for the setting you intend to use.

The example does not set a target bitrate or keyframe interval, because those depend on the output you choose and YouTube’s current guidance. Add suitable encoder options only after deciding on the resolution and frame rate, and confirm the encoder actually applies them. Leave headroom on an upload connection shared with other devices. A connection that performs well during an idle test may behave differently when household or studio use increases.

A long-running feed also needs an operator’s plan for interruptions. Keep a local copy of the graph, note which files it expects, and test what happens at end of input or after a process restart. If you run a channel from a personal computer, the practical burden includes keeping that machine powered, connected and able to recover. This is separate from transition design. For a persistent channel, choosing an operating system for a 24/7 YouTube stream helps frame the maintenance trade-offs of running the process yourself.

If the specific problem is keeping a prepared video broadcast running without leaving your computer on, StreamNeo can remove that particular task of operating a local FFmpeg process; it does not turn a two-input transition command into a scheduler or decide how your clips should be joined.

Send the feed to YouTube Live

In YouTube Live Control Room, prepare the broadcast and obtain the ingest destination and stream key for the encoder. Put those values into the output URL in place of the placeholders. YouTube recommends RTMPS for live ingest; use the address supplied for your broadcast rather than guessing a server URL. Treat the stream key as a credential: do not publish it in a screenshot, share it in a public command log, or leave it in material another person can access.

Start with a private or unlisted test where appropriate to your channel, and confirm that the incoming picture and sound match your plan before a public session. YouTube advises testing before going live with audio and video movement similar to the planned stream, then monitoring stream health during the event. A still image and silence are not a useful test of a transition that must change moving frames and maintain sound.

Check for a stable picture before, during and after the blend, and look at YouTube’s stream health indicators while the test runs. An FFmpeg process that remains open does not by itself prove that viewers are receiving a healthy broadcast. Likewise, a successful preview does not prove that every later transition or input will behave the same way. Make a note of the exact files and settings used in a successful test so you can reproduce it.

Test and diagnose the failures that matter

When a transition fails, isolate whether the problem is input compatibility, timing, graph mapping, audio, encoding or delivery. Read the first useful FFmpeg error rather than changing several options at once. A message about filter initialisation points towards stream parameters or the graph; a missing mapped stream suggests the audio or video selection; a stream-health warning after the output begins may instead concern encoding settings or the connection.

Symptom Likely area to inspect Practical next check
xfade will not initialise Different dimensions, frame rates, time bases or pixel formats Compare both input streams with ffprobe; test a normalised pair
Fade begins too early or late Offset is wrong for the usable first clip timeline Render a short local test and adjust the offset from measured duration
First clip ends during the blend Offset plus transition duration exceeds available footage Move the transition earlier or use a longer first input
Picture changes but audio cuts Video filter only; audio mapping is separate Choose continuous programme audio or build an acrossfade graph
Output is silent No suitable mapped audio stream Inspect available audio streams and map the intended source
YouTube preview is unstable Output settings, encoder load or upload connection Check stream health, chosen bitrate and sustained upload capacity

Do not assume that an error means every source file must be re-encoded. First inspect the inputs and the specific failure. If a normalised pair works, preserve that tested path for the production files. If it does not, reduce the graph to one input or render the filtered output locally to determine whether the failure occurs before the YouTube connection is involved.

Test transitions at more than one point if you have a longer sequence. A first join can succeed while a later join uses an incorrect accumulated offset. Watch the whole overlap and listen through it. Keep the original assets unchanged while testing so a conversion mistake does not destroy the source you need to compare against.

For a multi-clip channel that needs planned playlist changes, use a scheduler or a workflow designed for that job rather than treating a longer xfade graph as a forever-running playlist. A playlist change has decisions about ordering, fallback content, and recovery that are not provided by the crossfade filter. Similarly, a reboot recovery plan is distinct from timing a visual transition; see how to make a YouTube radio stream start after a reboot if restart behaviour is part of your setup.

Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.

FAQ

How do I make FFmpeg crossfade between two videos?

Use both videos as inputs in a -filter_complex graph and connect their video streams with xfade. Set a duration and offset based on the first clip’s timeline, map the labelled output, and encode it. Check that the files’ stream parameters are compatible before assuming the graph will run.

How do I do it live on YouTube?

Run FFmpeg with both inputs, the transition graph, an encoder and the RTMPS destination and stream key shown in YouTube Live Control Room. Test the feed in YouTube before a public broadcast, including moving video and audio, and monitor stream health. This two-input example handles a defined transition; it does not schedule an endless playlist.

Why does xfade fail when my clips have different settings?

The filter expects compatible inputs, and differing dimensions, frame rates, time bases or pixel formats can prevent it from configuring. Inspect the streams with ffprobe, then normalise the relevant properties for your files and test again. The right conversion choices depend on the source material and intended output.

How do I fade the audio too?

Build a separate audio graph using acrossfade for the two clip audio streams, then map its labelled output. Alternatively, map a continuous music or narration source if that is meant to run beneath both visuals. Check the sound through the join, because xfade changes video only.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Tools guides ↗ · All topics ↗