Limited Time Offer: Get 50% OFF Starter & Basic Yearly Plans 🎉

Automate OBS Scene Transitions When a Video Finishes Playing

Oct 13, 2026

Why Automated Transitions Change the Way You Produce

Manual scene switching is one of the last genuinely manual steps in an otherwise heavily automated production pipeline. An operator watches a preview monitor, waits for the intro video to hit its final frame, and taps a key at exactly the right moment. Do that ten times in a two-hour stream and you will miss the timing at least once. Automating the handoff removes the human reaction delay, guarantees frame-consistent behaviour across every run, and frees the operator to focus on content rather than on button timing.

The use cases are broader than live streaming. A course creator recording lessons in batches wants the intro bumper to hand off to the webcam scene without touching the keyboard between takes. A VTuber wants an opening animation to end and gameplay capture to appear in one motion. A church tech team wants a pre-recorded welcome segment to roll and then cut to the live room camera while the presenter is already walking on stage. A product team running a launch livestream wants a set of pre-rendered segments to play in sequence with branded stinger transitions between each one.

All of these share the same mechanics: a media source reaches its end state, an event fires inside OBS, and a scene change is executed with a chosen transition. The complexity is not in the concept, it is in the details — how the event is detected, how the scene is mapped, and what happens when the source restarts.

This guide walks through three separate implementation paths, from the no-code plugin approach to a fully scripted WebSocket listener, plus the timing and troubleshooting knowledge that separates a reliable automation from one that fails on the day it matters.

How OBS Detects That a Video Has Finished

Before choosing a tool, understand what information OBS actually exposes. A media source (a file, a local stream, or a network URL loaded into the Media Source type) moves through a small set of internal states: none, playing, opening, buffering, paused, stopped, ended, and error. The state you care about is ended, which fires when playback reaches the end of the file rather than when it is paused or stopped manually.

Event-driven detection versus polling

There are two ways to know the state changed. The first is event-driven: OBS emits a signal or an external event the moment the state transitions to ended. The second is polling: you ask "is this source still playing?" on a timer, and act when the answer changes. Event-driven is almost always correct. Polling introduces latency equal to your interval, hammers the scripting API, and can double-fire if the state flickers. Use polling only as a fallback when a plugin or an unusual source type gives you no other option.

The three reliable signals

In practice you have three trustworthy signals available:

  • The scripting signal media_ended, available to Lua and Python scripts attached through the OBS scripting interface.
  • The WebSocket event MediaInputPlaybackEnded, delivered to any external client connected to the built-in WebSocket server.
  • The macro condition in automation plugins that watch media sources and evaluate whether a source has ended.

Each maps to a different implementation path, and each has trade-offs in setup effort, portability, and debuggability. The rest of this article takes them one at a time.

Option One: Built-In Media Source Settings and Their Limits

Start here because it costs nothing and it clarifies what native OBS can and cannot do.

In the properties of a Media Source you will find options such as Loop, Restart playback when source becomes active, Show nothing when playback ends, and Close file when inactive. Together these control what the source does on its own, but none of them switch a scene. OBS has no native "on media end, change scene" checkbox, and it likely never will, because scene logic belongs to automation layers rather than to individual sources.

What the native settings are genuinely useful for:

  • Show nothing when playback ends prevents the final frame from freezing on screen while your automation catches up.
  • Close file when inactive releases the file handle so the next activation starts cleanly, which matters when the same bumper plays multiple times in a show.
  • Restart playback when source becomes active gives you automatic replay-on-scene-activation, which is useful for looping backgrounds but dangerous for one-shot intros.

That last point causes more broken automations than anything else. If a source is set to restart when active, and your automation briefly toggles scene state, the media may restart and fire a second ended event later, producing an unexpected scene change mid-show. Turn that option off for any one-shot video you intend to automate against.

Option Two: Scripting with the Native Media Ended Signal

This is the most self-contained approach: a small script lives inside OBS, listens for the signal, and switches scenes. It requires no external process and survives OBS restarts once loaded.

Setting up the scripting environment

Open Tools → Scripts, click the plus icon, and create a new .lua file (Python works too if the Python scripting module is installed). OBS exposes the obslua module with the full source API. You will need the exact name of the media source and the exact name of the destination scene — both are case-sensitive and both are the reason most first attempts fail silently.

A minimal working script

The pattern is short. Register a callback on the source's signal handler, then act on it:

local obs = obslua

local SOURCE_NAME = "Intro Video"
local TARGET_SCENE = "Main Camera"
local DELAY_MS = 300

local source_ref = nil
local timer_active = false

local function switch_scene()
  local scene = obs.obs_frontend_get_scene_by_name(TARGET_SCENE)
  if scene then
    obs.obs_frontend_set_current_scene(scene)
    obs.obs_source_release(scene)
  else
    obs.script_log(obs.LOG_WARNING, "Target scene not found: " .. TARGET_SCENE)
  end
  timer_active = false
end

local function on_media_ended(cd)
  if timer_active then return end
  timer_active = true
  obs.timer_add(switch_scene, DELAY_MS)
end

function script_description()
  return "Switch scene when a media source finishes playing."
end

function script_load(settings)
  local source = obs.obs_get_source_by_name(SOURCE_NAME)
  if source then
    obs.signal_handler_connect(
      obs.obs_source_get_signal_handler(source),
      "media_ended",
      on_media_ended
    )
    obs.obs_source_release(source)
  else
    obs.script_log(obs.LOG_WARNING, "Source not found: " .. SOURCE_NAME)
  end
end

Three details in that code matter more than the rest. First, the timer_active guard prevents double-firing if the signal is emitted more than once. Second, the release calls are mandatory — the OBS API is reference counted and leaks will accumulate over a long session. Third, the delay is deliberate: switching on the identical frame the file ends can clip the final audio sample or produce a visible flicker with certain containers.

For a Python implementation, the equivalent listener uses the same signal name through the obspython module, or you skip in-process scripting entirely and use an external client.

When to prefer an external WebSocket client

If your automation needs to do more than switch a scene — post to a chat service, start a recording, log to a spreadsheet, trigger a lighting change — move the logic outside OBS. Enable the WebSocket server under Tools → WebSocket Server Settings, note the port and password, then connect from Python, Node, or any language with a client library. Subscribe to MediaInputPlaybackEnded, and on receipt call the scene-change request. The advantage is that one process can orchestrate OBS, lighting, audio, and notifications together, and you can hot-reload business logic without touching OBS.

Option Three: Automation Plugins and Macro Builders

If you would rather not write code, the plugin ecosystem covers this ground well. The general pattern across these tools is the same: define a trigger condition, define an action, and set an evaluation interval.

A typical macro to build:

  1. Trigger: media source "Intro Video" has the state "Ended".
  2. Extra condition: current scene is "Standby". This prevents the macro from acting when the intro plays as a background element somewhere else.
  3. Action: switch to scene "Main Camera" with transition "Fade" over 400 ms.
  4. Optional action: start recording, unmute the host microphone, or send a WebSocket command to another machine.

Evaluation intervals as low as 50 ms are usually safe on a modern machine, but anything below 200 ms is wasted effort — human perception will not distinguish it, and tighter loops cost CPU that your encoder needs.

Plugins are excellent for operators who value visual editing and rapid iteration. Their weakness is portability: a macro built on one machine does not automatically transfer to another unless you export the configuration. If your production runs on multiple machines, document every macro in a plain-text runbook so it can be rebuilt quickly.

Designing Transition Logic That Does Not Look Robotic

The automation is the easy part. Making it feel like a deliberate creative choice is where the craft lives.

Match the transition to the content

A hard cut from an energetic intro into a static talking-head scene feels like a mistake. A long dissolve between two fast-paced gameplay segments kills momentum. Build a small decision table before you write a single line of automation:

  • Bumper to live camera: fade or stinger, 300–600 ms.
  • Segment to segment in a fast show: cut, or stinger under 400 ms.
  • Tutorial chapter change: short fade with a lower-third graphic added on the new scene.
  • Outro video to end card: slow fade, 800 ms or more, with audio bed continuing underneath.

Handle the transition tail explicitly

If your outro video has audio that should ring out under the new scene, do not switch the moment the file ends. Either bake the tail into the video, loop the audio in a separate source that stays alive across the scene change, or add a deliberate audio-only fade on the incoming scene. Silent gaps are the most common quality complaint in automated productions, and they almost always come from treating the scene change as the end of the sequence rather than the middle of it.

Keep a manual override

Every automated system needs a human escape hatch. Bind a hotkey that cancels the pending switch and lets the operator take control. If a guest keeps talking through the planned bumper, the automation should not bulldoze the moment.

Testing, Timing, and the Failures That Bite Later

Automations rarely fail in obvious ways. They fail in specific, repeatable patterns that you can pre-empt.

Source name drift

Renaming a source breaks any script that references it by name and any macro keyed to it. Two defences: adopt a naming convention and freeze it before you build automation, and add a loud log warning when a referenced source is missing at load time rather than failing silently.

Nested scenes and groups

Media sources inside a group or a nested scene still emit signals, but code that walks the scene tree by index will break the moment someone reorganises the layout. Always resolve sources by name from the top level, and test after any structural change to a scene collection.

Double firing

The ended signal can be emitted twice in edge cases, especially with network sources that reconnect. Always guard with a boolean flag and a short cooldown, exactly as in the script above.

Playlist behaviour

A media source in playlist mode fires ended events per item, not per playlist. If you want one scene switch after the whole playlist, listen for the playlist-ended condition or count items. If you want a switch between items, the ended event is exactly right — just map the sequence deliberately rather than assuming chronological order.

WebSocket disconnects and reconnects

External clients must reconnect automatically. Build in an exponential backoff and re-subscribe to events on reconnect, and log the reconnect to a file you will actually check. A silent disconnect means an automation that simply stops working halfway through a show.

Audio bleed and monitoring

If the outgoing video's audio is still routed to the stream mix after the scene change, you will hear a fragment of it over the new scene. Verify with a recording, not with headphones on a live monitor — the output mix and the monitoring mix are not always identical.

Version differences

The built-in WebSocket server, its port conventions, and some scripting APIs have changed across major OBS releases. Pin your production machine to a known-good version, test any update on a spare machine, and keep a rollback plan. Nothing ruins a live show faster than an update applied an hour before going live.

A Complete Automated Show Flow, Start to Finish

Here is how these pieces fit together for a typical 60-minute produced livestream:

  1. Pre-show. A looping holding scene with music and a countdown graphic. No automation needed, just a loop-enabled media source.
  2. Open. At the scheduled time, the operator (or a scheduler) switches to the intro scene. The intro video plays to completion, fires ended, and the script switches to the host camera with a 400 ms fade.
  3. Segments. Each pre-recorded segment lives in its own scene. Segment videos fire ended and advance to the next scene using a stinger transition. A manual override hotkey pauses the chain if the host runs long.
  4. Ad or break. A break scene plays a looping ident while chat catches up. A scheduled action returns to live after 90 seconds.
  5. Close. The outro video plays, fires ended, and switches to an end card scene. The external controller waits ten seconds, then stops the stream and the recording through the WebSocket API.

The whole chain relies on exactly two mechanisms: a media ended event, and a scene change with a named transition. Everything else is sequencing.

When OBS Alone Is Not the Right Tool

For a single-machine, single-operator show, OBS plus one automation layer is enough. Beyond that, consider alternatives honestly.

  • Multi-machine productions often route video over a network protocol and keep switching logic on a control machine, with a hardware or software control surface driving it.
  • Dedicated playout software handles scheduled, frame-accurate broadcast chains better than a general-purpose compositor. If your show is fundamentally a playlist with graphics, that category of tool is worth evaluating.
  • Pre-rendered deliverables should be edited rather than switched live. If there is no live element, switching scenes in real time adds risk with no benefit; assemble the sequence in an editor instead.
  • Companion-style control surfaces bridge physical buttons and scene switching for operators who want tactile control with automation as a backstop.

The decision rule is simple: automate the parts that are deterministic, and keep humans on the parts that require judgement.

Where Generative Video Fits Into the Workflow

Automated transitions become far more useful when your source material is cheap to produce. Teams that previously made one intro bumper per quarter now generate short segment intros, animated lower-thirds, and location-specific stingers on demand using text-to-video and image-to-video tools.

Two practical implications follow. First, keep generated clips to a fixed specification — resolution, frame rate, aspect ratio, and audio sample rate — so the media source behaves identically every time and your automation never needs special cases. Second, keep a naming and folder convention that makes it obvious which assets are finished and which are drafts, because a half-finished clip that happens to be sitting in the automation folder will eventually play on stream.

Render length matters too. Generated clips often land at odd durations such as 4.2 seconds or 7.8 seconds. Round them to deliberate durations during post so your transition timing is predictable and your schedule math stays simple.

Frequently Asked Questions

Can OBS switch scenes automatically without any plugin or script?
No. Native OBS controls what a media source does when playback ends, but it does not change scenes. You need a script, a WebSocket client, or an automation plugin.

Which approach should a solo streamer start with?
Start with the scripting route if you are comfortable with a text editor, and with a macro plugin if you are not. Both take under an hour to get working for a single intro-to-camera handoff.

Does this work for recorded videos, not just livestreams?
Yes. Scene switching is independent of the output target, so the same automation works while recording locally, streaming, or both.

Why did my scene switch fire twice?
Usually a source set to restart when active, a reconnecting network source, or a missing guard flag in the script. Add a cooldown and disable auto-restart on one-shot clips.

Can I use a different transition for each switch?
Yes. Set the active transition before requesting the scene change, or use per-switch overrides in your macro tool. Just remember the transition name must match exactly.

What if the destination scene does not exist yet?
The switch fails silently in most implementations. Always log a warning when a scene lookup returns nothing, and verify scene names after importing a collection onto a new machine.

How much delay should I add after the media ends?
Between 200 and 500 ms is a safe default. Below that you risk clipping the final audio tail; above that the pause becomes noticeable to viewers.

Key Takeaways and a Build Checklist

Automating scene changes on media completion is a small amount of code or configuration wrapped around a well-understood event. The difficulty is not the mechanism — it is the discipline of naming, testing, and guarding against the edge cases that only appear under live pressure.

Before your next show, confirm the following:

  • Your one-shot media sources have Restart playback when source becomes active disabled.
  • Every automated switch resolves its source and scene by exact name, with a logged warning on failure.
  • A guard flag or cooldown prevents double firing.
  • A manual override hotkey exists and is known to the operator.
  • There is a 200–500 ms delay between the ended event and the scene change.
  • Transition choices are documented in a decision table, not improvised.
  • The full chain has been rehearsed twice with a short test clip before going live.
  • The production machine's OBS version is pinned, and any update is tested elsewhere first.

Build it once, rehearse it, and then stop thinking about it. The point of automation is not to remove the operator — it is to let the operator spend attention on the parts of the show that only a human can handle.

Alexander

Alexander