A Windows UWP app for triggering pre-programmed audio and visual effects during live theater performances. Built in C# with XAML.
During live theater productions, someone backstage needs to trigger sound effects, music, background images, and video clips at precise moments. Commercial theater control software is expensive and overkill for small/amateur productions.
This app provides a simple two-window setup: an operator control panel with a scrollable list of effects, and a theater display window that outputs to a projector or second screen. The operator clicks (or navigates with Next/Prev) through effects in performance order.
I built this to help run effects for several theater plays I was involved with. It's intentionally simple: big buttons, clear labels, color-coded effect list — designed to be used in a dark backstage environment under time pressure.
Operator panel with "School of Miracles" loaded — selecting effects from the color-coded list and triggering playback on the theater display. Watch the full demo video.
Operator control panel — color-coded effect list, playback controls, and status bar:
Both windows — operator panel (left) with the theater display (right) showing a background image:
graph LR
subgraph Operator["Operator Panel (MainPage)"]
EL[Effect List<br/>color-coded by type]
BTN[Playback Controls<br/>Next / Prev / Pause / Stop]
SB[Status Bar<br/>show name, now playing]
end
subgraph Theater["Theater Display (ScreenView)"]
P1[Media Player A]
P2[Media Player B]
CF{{"Crossfade Engine<br/>(3s Storyboard)"}}
P1 <--> CF
CF <--> P2
end
YAML["YAML Show File<br/>+ Media Folder"] -->|ShowLoader| Operator
Operator -->|"TheaterEffectSelectedEvent<br/>(trigger effect)"| Theater
Theater -->|"OnMediaEnded<br/>(auto-advance)"| Operator
style Operator fill:#1a1a2e,stroke:#e0e0e0,color:#e0e0e0
style Theater fill:#1a1a2e,stroke:#e0e0e0,color:#e0e0e0
style YAML fill:#2a2a3e,stroke:#aaa,color:#e0e0e0
style CF fill:#145a5a,stroke:#e0e0e0,color:#e0e0e0
The operator panel and theater display run in separate windows (separate CoreApplicationView instances). They communicate through a custom event delegate for triggering effects and a callback for auto-advance when media finishes. The crossfade engine alternates between two layered MediaPlayerElement controls, using a Storyboard to animate opacity and volume simultaneously.
- Launch the app, click "Open Theater Screen" to select the folder containing media files for the current show
- A second window opens (the theater display) — drag it to the projector/audience screen
- The operator control panel shows a scrollable list of all effects for the show
- During the performance, click effects in order (or use Next/Prev buttons) to trigger them
- The theater display crossfades between effects with a 3-second transition
- Two-window setup — operator control panel + theater display output
- Crossfade transitions — dual media players with smooth 3-second opacity/volume fade between effects
- Multiple media types — video (.mp4), audio (.mp3), and background images (.jpg, .png)
- Background sound — separate background audio track with independent pause/replay controls
- Playback controls — Next, Previous, Pause, Stop, Replay, Jump to End, volume slider
- Auto-advance — effects can be configured to automatically trigger the next effect when they finish
- Color-coded effect list — effects are color-coded by type for quick visual identification
- Skip FG — option to skip foreground playback (jump to end) for testing or rehearsal
| Component | Technology |
|---|---|
| Language | C# |
| UI Framework | UWP (Universal Windows Platform) / XAML |
| Media Playback | Windows.Media.Playback (MediaPlayer, MediaPlaybackList) |
| Video Effects | Win2D (GPU-accelerated blur effect) |
| Show Definitions | YAML files parsed with YamlDotNet |
| Target | Windows 10 (SDK 10.0.22621.0, min 10.0.17763.0) |
| IDE | Visual Studio 2022 with UWP workload |
TheaterEffectsViewerApp/
├── TheaterEffectsViewerApp.sln
├── TheaterEffectsViewerApp.csproj
├── Package.appxmanifest # UWP app manifest
├── App.xaml / App.xaml.cs # Application entry point
├── MainPage.xaml / .xaml.cs # Operator control panel
├── ShowLoader.cs # YAML show file parser + effect builder
├── ScreenView.xaml / .xaml.cs # Theater display (dual-player crossfade engine)
├── MediaPlayerElementWithAudioVolume.cs # Custom control: animatable audio volume
├── Effects/
│ └── VideoEffectComponent/ # Win2D GPU blur video effect
├── shows/ # Show definition files (YAML)
│ ├── school-of-miracles.yaml
│ └── space-story-2024.yaml
├── Assets/ # UWP app icons and tiles
├── Properties/
│ ├── AssemblyInfo.cs
│ └── Default.rd.xml
└── logo/ # Show-specific logo images
Prerequisites:
- Visual Studio 2022 with the "Universal Windows Platform development" workload
- Windows 10 SDK 10.0.22621.0 (installed automatically with the UWP workload)
# Open in Visual Studio:
# File → Open → Project/Solution → TheaterEffectsViewerApp.sln
# Build → Build Solution (Ctrl+Shift+B)
# Debug → Start Debugging (F5)
Package signing is disabled by default. To sideload or deploy, generate your own signing certificate in Visual Studio (Project Properties → Package → Choose Certificate).
Shows are defined in YAML files. At startup, the operator picks a media folder containing a .yaml show file alongside the media assets. The app parses the YAML, resolves media files, and populates the effect list. No recompilation needed to switch shows.
Example show files in shows/:
school-of-miracles.yaml— 34 effects, 7 scenes (children's magic school play)space-story-2024.yaml— 62 effects, 10 scenes (Russian space/winter play)
To create a new show, write a YAML file following the schema in the examples and place it in a folder with the media files.
A children's play about a magical school. This show was used in a live performance with all effects triggered by a single backstage operator.
Each line below represents one effect in the operator's list. Colors match what the operator sees in the app.
Scene 00 — Intro (2 effects)
| Effect | Type | Media | |
|---|---|---|---|
| 🔴 | Initial video | loop | 0 - Initial waiting video (norm).mp4 |
| 🔷 | Clowns | video | 01 - Clowns (norm).mp4 |
Scene 01 — Old Parrot's Home (1 effect)
| Effect | Type | Media | |
|---|---|---|---|
| 🔷 | Old Parrot's Home | video | 02 - Old Parrot_s Home (norm).mp4 |
Scene 02 — Schoolyard (4 effects)
| Effect | Type | Media | |
|---|---|---|---|
| 🔷 | Schoolyard gates | video | 03 - Schoolyard gates (norm).mp4 + BG image |
| 🟦 | Schoolyard BG | background | BG image only |
| 🟡 | Song: SCHOOL OF MAGIC | song | 04 - School of Magic (norm).mp4 |
| 🟦 | Classroom | background | BG image only |
Scene 03 — Lessons (7 effects)
| Effect | Type | Media | |
|---|---|---|---|
| 🟢 | Koralia's lesson | audio | 05 - Korallia_s lesson (-20LUFS-15dB).mp3 |
| 🔷 | Rainbow | video | 05.5 - Rainbow (norm).mp4 |
| 🟢 | Oktopus' lesson | audio | 06 - Oktopus_ lesson (-20LUFS-15dB).mp3 |
| 🟢 | Morion's lesson | audio | 07 - Morion_s lesson (-20LUFS-15dB).mp3 |
| 🟢 | Homework | audio | 08 - Homework (-20LUFS-15dB).mp3 |
| 🟡 | Song: SCHOOL BREAK | song | 9 - School break (norm).mp4 |
| ⚫ | Blackout | blackout | — |
Scene 04 — Old Parrot's Home (1 effect)
| Effect | Type | Media | |
|---|---|---|---|
| 🔷 | Old Parrot's Home | video | 10 - Old Parrot_s Home (norm).mp4 |
Scene 05 — Wizardry Contest (11 effects)
| Effect | Type | Media | |
|---|---|---|---|
| 🔷 | Kikimora's lament | video | 11 - Kikimora_s lament (norm).mp4 + BG image |
| 🟦 | Winter school BG | background | BG image only |
| 🟡 | Song: KIKIMORA | song | 12 - Kikimora_s song (norm).mp4 |
| 🔷 | Wizardry contest | video | 13 - Wizardry Contest (norm).mp4 |
| 🟢 | Jury entrance | audio | 13.5 - Jury entrance (-20LUFS).mp3 |
| 🟡 | Song: YAGA'S SHOW | song | 14 - Yaga_s Show (norm).mp4 |
| 🔷 | Water Show | video | 15 - Water show (norm).mp4 |
| 🔷 | Koschei's Show | video | 16 - Koschei_s show (norm).mp4 |
| 🔷 | Moroz's Show | video | 17 - Moroz_s Show (norm).mp4 |
| 🔷 | Snowflakes + Award Ceremony | video | 18 - Snow Flakes + Award Ceremony (norm).mp4 |
| 🔷 | Moroz wins | video | 21 - Father Frost entrance (-20LUFS).mp3 |
Scene 06 — Finale (8 effects)
| Effect | Type | Media | |
|---|---|---|---|
| 🔷 | Old Parrot call transition | video | 19 - Old Parrot Call Transition (norm).mp4 + BG image |
| 🟦 | Last BG | background | BG image only |
| 🟡 | Song: WITCH RIVER | song | 20 - Witch river (norm).mp4 |
| 🟢 | Father Frost entrance | audio | 21 - Father Frost entrance (-20LUFS).mp3 |
| 🟢 | Phone busy | audio | 22 - Phone Busy SFX (-20LUFS).mp3 |
| 🟡 | Song: THEY SAY | song | 23 - They say - Don_t listen (norm).mp4 |
| 🔴 | Fireworks | loop | 24 - Fireworks (norm).mp4 |
| ⚫ | Blackout | blackout | — |
Category legend: 🔷 video 🟢 audio 🟡 song 🟦 background 🔴 loop ⚫ blackout
MIT


