UCLA Daily: Slideshow Export (MP4)
The node that turns your cards into a looping MP4
- ucla_data
- video_path
- card_count
UCLASlideshowExport is the end of the line for the UCLA Daily pipeline - the node that takes everything the fetchers gathered and the card nodes rendered, and stitches it into a single looping 1920x1080 MP4 you can point OBS at, drop on a USB stick, or upload to YouTube. Hold time, crossfades, loop count, even a custom filename - it's the "make it a video" button the whole pack has been building toward.
The pack, by Jeffrey A. Brick, was built for a lobby TV at 6401 Wilshire Blvd streaming over OBS → YouTube. This node is the payoff. Everything upstream is about gathering and rendering; this is about presenting.
How it works
It takes the full UCLA_DATA from the pipeline, renders the deep-dive cards (and optionally the summary lobby cards first, via include_lobby_cards), converts each frame from a ComfyUI IMAGE tensor to PNG, and feeds them to ffmpeg to encode the video. The important dependency to know about: ffmpeg must be installed on your system - it's not a pip package, and the node shells out to it. The slideshow uses crossfade transitions (0.8s by default) between cards, with per-card hold time set by hold_seconds (12 by default).
Because the whole graph re-fetches live data on every run (IS_CHANGED is set on the upstream nodes), each export is a fresh video of today's news. The pack also ships a standalone generate_obs.py script that skips the ComfyUI GUI entirely and produces the same MP4 - useful when you just want the video without opening the graph.
The inputs that matter
- ucla_data - required; the pipeline dict from
UCLADailyDataInit+ fetchers. - card_width / card_height - default 1920×1080. Keep it; this is a TV format.
- hold_seconds - 3–60, default 12. How long each card sits on screen.
- fade_seconds - 0–3, default 0.8. Crossfade duration; 0 = hard cut.
- max_cards - 1–100, default 33. Cap on total cards in the video.
- include_lobby_cards - default true; prepend the summary cards before the deep dives.
- loop_count - 1–10, default 1; how many times the full slideshow repeats inside the video.
- show_unofficial_badge, show_qr_code, enrich_descriptions - passed through to the card renderers.
- output_filename - custom name (no extension); blank = auto-timestamped.
Outputs
Two: video_path (STRING - where the MP4 landed) and card_count (INT).
Install
ComfyUI Manager → search UCLA Daily, or:
cd ComfyUI/custom_nodes
git clone https://github.com/jbrick2070/ComfyUI-UCLADaily.git
pip install qrcode pillow requests
Restart ComfyUI. Then install ffmpeg on your system - on Ubuntu/Debian that's sudo apt install ffmpeg; on Windows, put it on your PATH. Without ffmpeg this node has nothing to encode with.
Common issues
The classic failure is a missing or old ffmpeg - the node errors immediately, and the fix is installing or updating it. Long videos (loop_count up, many cards, long hold times) take a while to encode and can look "stuck"; let it finish. And if the MP4 looks like a slideshow of placeholders, check that qrcode and Pillow are installed - the card renderers degrade gracefully, but you don't want degraded cards on a lobby TV.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| ucla_data | UCLA_DATA | UCLA data dict from pipeline. | |
| card_widthopt | INT | 1920800–3840 | — |
| card_heightopt | INT | 1080600–2160 | — |
| hold_secondsopt | INT | 123–60 | Seconds each card is displayed. |
| fade_secondsopt | FLOAT | 0.80–3 | Crossfade duration between cards (0 = hard cut). |
| max_cardsopt | INT | 331–100 | Maximum cards in the slideshow. |
| include_lobby_cardsopt | BOOLEAN | true | Prepend summary lobby cards before deep dive cards. |
| loop_countopt | INT | 11–10 | How many times to repeat the full slideshow in the video. |
| show_unofficial_badgeopt | BOOLEAN | true | — |
| show_qr_codeopt | BOOLEAN | true | — |
| enrich_descriptionsopt | BOOLEAN | true | — |
| output_filenameopt | STRING | Custom filename (without extension). Blank = auto-timestamped. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video_path | STRING | — |
| card_count | INT | — |