VLC Media Player Costume — BOM & Build Plan
Keep plan-b-diagram.png in the same folder as this file so the diagram shows in the preview.
Concept: a chest plate — one board carrying the Raspberry Pi, a slim power bank, and the 7" touchscreen screwed over the top of both — worn on riveted elastic like a chest guard, auto-booting into a maximized, looping, muted VLC window. Bought foam cone hat on top. This is the v2 design, from Anthony's suggestion; the original bolted-sandwich version is preserved in vlc-costume-build-plan-v1.md.
Design rules
- One board, everything on it. Pi, bank, and display all mount to a single plate; the fragile connections live inside the 30 mm gap under the display and never see strain.
- No cable outside the module. The only cable runs from the bank to the Pi, inside the gap.
- Plug in = costume on. Everything autostarts. Read-only filesystem, so yanking power at 2 a.m. is harmless.
- Nothing touches you but foam. The body side is a flat 6 mm pad; all the electronics face outward, under the display.
Platform: Raspberry Pi 4
2 GB is plenty; 4 GB is fine if that's what you have. Budget ~7–8 W with the display playing video. It runs from any USB-C bank that can do 5 V/3 A, and it decodes H.264 in hardware, so 720p playback is nearly free.
Bill of materials
Prices are rough USD; check current pricing.
The one constraint that drives everything: the bank must be slim. The gap under the display is 30 mm. A flat 10,000 mAh bank about 15 mm thick fits with room for air; a fat 20,000 mAh cylinder does not. Buy the bank first and design the bay around it. Two slim 10,000s (swap at halftime, ~40-second reboot) beat one thick 20,000 here.
| Item | Spec / notes | Qty | Est. |
|---|---|---|---|
| Raspberry Pi 4 Model B, 2 GB | Same as Plan A | 1 | $45 |
| Raspberry Pi Touch Display 2, 7" | Includes DSI cables, the GPIO power lead, and M2.5 screws | 1 | $60 |
| microSD card | 32 GB, A1/A2 class | 1 | $10 |
| Stick-on heatsink kit for Pi 4 | Fit before mounting the Pi | 1 | $5 |
| Right-angle USB-C to USB-C cable | 15–30 cm, rated 3 A. Buy two — one is the spare | 2 | $16 |
| USB-C inline power meter | Optional but worth it for the runtime measurement | 1 | $15 |
| EVA foam, 10 mm | Floor-tile 4-pack: the perimeter wall, plus cone material | 1 pack | $15 |
| Black gaffer tape, 2" | Edge finishing on the board and foam wall | 1 | $12 |
| Thin foam tape, 1–2 mm | Cushion strip on top of the foam wall | 1 roll | $4 |
| Contact cement (or hot glue) | Foam to board, foam to foam | — | own |
| Board | 3 mm plywood or hardboard, ~240 × 180 mm, corners rounded. Ply, not PVC foam board — rivets under elastic tension need material with real tear strength | 1 | $8 |
| Slim power bank | 10,000 mAh, 15 mm thick or less, USB-C 5 V/3 A. Buy two if you want halftime swaps | 1–2 | $25 ea |
| 2" heavy knit elastic | ~2.5 m. The wide, stiff waistband kind, not lingerie elastic | 1 | $10 |
| Pop rivets, 1/8" (3.2 mm), ~10 mm grip | Aluminum, with 3.2 mm × 10 mm backup washers for BOTH sides — the washers are what stop the elastic tearing through | ~20 + washers | $8 |
| Pop rivet tool | Basic hand riveter, if you don't already have one | 1 | $15 |
| M2.5 screws ~35–40 mm + 30 mm spacers | 4 of each; nylon or aluminum standoff spacers. These hold the display over the bay | 4 | $8 |
| M2.5 screws ~12 mm + 5 mm spacers + nuts | 4 of each, to mount the Pi flat on the board | 4 | $4 |
| 6 mm EVA sheet | Body-side pad (a 10 mm floor tile split or doubled craft foam is fine) | 1 | $4 |
| Adhesive velcro | Bank retention in the bay | 1 strip | $4 |
| 1" elastic offcut | Keeper strap across the bay opening | — | — |
No bezel, no pocket wall, no webbing, no buckles, no tri-glides, no pouch. Total buying everything new: ~$250–275 (a second slim bank adds $25). Already own a Pi, bank, and SD card: ~$150.
Content
| Item | Spec / notes | Qty | Est. |
|---|---|---|---|
| Video clips | 1–3 minutes each, 30–45 minutes in total. Any format; you convert them in Phase 1. Trailers, short films, your own footage, or public-domain material from the Internet Archive / Prelinger collections | 15–20 | free |
Tools
- Hobby knife and cutting mat
- Steel rule, plus calipers or a ruler
- Drill with 3 mm and 4 mm bits
- #1 Phillips screwdriver
- Hot glue gun
- Pop rivet tool
- Lighter and a nail (heat it to melt rivet holes in the elastic)
- microSD card reader
- A computer with Raspberry Pi Imager and ffmpeg (Phase 1 walks through installing both)
- Optional: an SSH app on your phone (Termius, Blink)
- Optional: a laser cutter or 3D printer for a cleaner plate and bezel
Key dimensions
- Board: ~240 × 180 mm, 3 mm plywood, corners rounded.
- Display outline 120 × 189.5 mm; viewing area 88 × 155.5 mm; its four threaded mounting bosses sit in a 58 × 49 mm cluster.
- The gap under the display is 30 mm: Pi with heatsinks ~20 mm tall, bank 15 mm or less.
- Weight on the chest: board + display + Pi + bank ≈ 650–700 g, all carried by the elastic — which is why the fitting step matters.
Phase 0Decide and order (do this week)
- Buy the bank first. The whole plate is designed around it: flat, 10,000 mAh, 15 mm thick or less, USB-C 5 V/3 A output. Buy two for halftime swaps.
- If your Pi 4 is an older one, check the revision:
grep Revision /proc/cpuinfo. A code ending in3111(a03111 / b03111 / c03111) is a 2019 rev 1.1 board, which won't power up from e-marked USB-C cables. Buy a USB-A to USB-C cable instead of C-to-C. - Order everything, including two cables. Lead time is nothing; the build is a weekend plus a soak test.
Phase 1Bench bring-up (software)~3 hours, plus conversion time
Do this on a proper Pi wall supply with a USB keyboard and mouse plugged into the Pi. Don't enable the read-only filesystem until Phase 6.
Four terminal basics, and that's all you need:
- Open a terminal on the Pi: click the black terminal icon in the top bar, or press Ctrl+Alt+T. Type a command, press Enter. Paste with Ctrl+Shift+V.
sudoin front of a command means "do this as administrator." It may ask for your password; nothing appears while you type it, which is normal.nanois a text editor that runs inside the terminal. Type or paste your text, press Ctrl+O then Enter to save, then Ctrl+X to exit.- Wherever you see
katiein a path, use your own username (the one you set in Imager). Not sure? Typewhoami.
Step 1 — Flash the card. On your computer, install Raspberry Pi Imager from raspberrypi.com/software and insert the microSD card. In Imager: Choose Device → Raspberry Pi 4. Choose OS → Raspberry Pi OS (64-bit). Choose Storage → your card. Next → Edit Settings. General tab: hostname vlc; a username and password; your home Wi-Fi name and password; your time zone. Services tab: Enable SSH, "Use password authentication". Save → Yes → Yes. Wait for "Write successful", then take the card out.
Step 2 — Stick the heatsinks on the Pi before it goes on the display.
Step 3 — Build the display slab.
- Use the 15-way to 15-way DSI cable (the 22-way one in the box is for Pi 5; set it aside).
- Seat it in the display's DSI connector and the Pi's, contacts oriented as shown in the display's leaflet, latches closed. Wrong-way ribbon is the number one cause of a black screen.
- GPIO power lead: red → 5 V (pin 2 or 4), black → GND (pin 6).
- Bolt the Pi to the display's standoffs with the included M2.5 screws.
- Put a dot of hot glue over the lead's header connector so it can't walk off the pins.
Step 4 — First boot. Card into the Pi, keyboard and mouse into the USB ports, wall supply in. The display is auto-detected; you'll see the desktop in about a minute. Open a terminal and run sudo apt update && sudo apt full-upgrade -y (10–20 minutes), then sudo reboot.
Step 5 — Rotate to landscape. Menu (raspberry icon, top left) → Preferences → Screen Configuration → right-click the DSI-1 box → Orientation → Right or Left → Apply. Either direction works in this build — the Pi mounts separately on the board, so you'll place it to suit in Phase 3. Touch input rotates with it.
Step 6 — Screen blanking off. Run sudo raspi-config (a blue text menu: arrow keys to move, Enter to select, Tab to reach Finish) → Display Options → Screen Blanking → No → Finish.
Step 7 — Taskbar. Right-click the panel → Panel Preferences → turn on auto-hide if your panel version has it. If it doesn't, leave it: a desktop taskbar above the VLC window still reads as real.
Step 8 — Optional: phone hotspot + SSH. The finished costume has no keyboard, so this is the only way to get a terminal into the Pi at the party (check temperature, restart VLC, dim the backlight) without plugging anything in. Turn on your hotspot, join it from the network tray icon so it's saved, then test from your phone: ssh katie@vlc.local (your username). Skip it if you'd rather keep things simple — once the filesystem is read-only in Phase 6, unplug/replug is a perfectly safe reboot.
Step 9 — Choose your clips. Target 15–20 clips, 1–3 minutes each, 30–45 minutes in total. Why those numbers: a clip has to be short enough that the seek bar visibly moves and the filename changes often, but long enough that it doesn't look like a GIF restarting; two minutes is the sweet spot. 30–45 minutes of material means even the friends who sit next to you all night won't notice the loop. Trailers and short films are ideal raw material, and the Internet Archive's public-domain and Prelinger collections are a deep well. Put every clip in one folder on your computer's Desktop named clips, and rename each file to its joke name now — VLC shows the filename in the title bar and flashes it at the start of each clip. Use letters, numbers, spaces, and hyphens only. Any video format is fine at this stage.
Step 10 — Install ffmpeg on your computer (one time; it's the converter). Mac: open Terminal and run brew install ffmpeg (no Homebrew yet? Paste the one-line installer from brew.sh first). Windows: open PowerShell and run winget install Gyan.FFmpeg, then close and reopen PowerShell. Check: ffmpeg -version should print a version number.
Step 11 — Convert one clip as a test. Every clip gets shrunk to 1280×720 (the panel's size) with the audio stripped out. In the terminal, go into the folder with cd ~/Desktop/clips, then make an output folder next to it with mkdir ../ready. Now run this one line, with your clip's name in both places:
ffmpeg -y -i "My Clip.mp4" -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -crf 22 -pix_fmt yuv420p -an "../ready/My Clip.mp4"Play the new file in ready: it should be silent and 1280×720. To use only part of a long video, add -ss 00:01:30 -t 00:02:00 right after ffmpeg -y (start at 1:30, keep 2 minutes).
Step 12 — Convert everything. Still in the clips folder, run one of these. It converts every file in the folder, roughly 1–2 minutes per clip on a laptop, so go make coffee.
Mac / Linux:
for f in *; do ffmpeg -y -i "$f" -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -crf 22 -pix_fmt yuv420p -an "../ready/${f%.*}.mp4"; doneWindows PowerShell:
Get-ChildItem -File | ForEach-Object { ffmpeg -y -i $_.FullName -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -crf 22 -pix_fmt yuv420p -an "../ready/$($_.BaseName).mp4" }When it finishes, ready should hold one .mp4 per clip, roughly 30–60 MB each.
Step 13 — Copy the clips to the Pi. A USB stick is the easy way: copy the ready folder onto it. On the Pi, open the file manager (folder icon in the top bar); in your home folder right-click → New Folder → name it videos. Plug the stick in, choose "Open in File Manager", select all the .mp4 files, and drag them into videos. (Alternative from a Mac/Linux terminal, one time only: scp -r ready katie@vlc.local:videos — this creates the videos folder for you.)
Step 14 — Make the playlist. In a Pi terminal: ls ~/videos/*.mp4 > ~/videos/playlist.m3u and then cat ~/videos/playlist.m3u. You should see every clip listed with its full path, one per line. If the list is empty, the files aren't in videos or don't end in lowercase .mp4.
Step 15 — First VLC run by hand. Menu → Sound & Video → VLC Media Player. Dismiss the privacy/network policy dialog (if you skip this, it'll pop up on the party boot). Then Tools → Preferences:
- Interface: uncheck "Resize interface to video size"; set "Continue playback?" to Never.
- Audio: uncheck "Enable audio".
- Click Save.
Then Media → Open File → Home → videos → playlist.m3u (switch the file-type dropdown to All Files if you don't see it) → Open. Click the loop button in the bottom controls (two arrows forming a circle) once so it highlights. Maximize the window with the maximize button — not fullscreen; you want the title bar and controls visible. Let it play for a minute, then press Ctrl+Q to quit cleanly so VLC saves the window state.
Step 16 — Autostart. In a terminal: mkdir -p ~/.config/labwc and then nano ~/.config/labwc/autostart. Paste this single line (your username, not katie), save, exit:
vlc --loop --random --no-audio --no-qt-video-autoresize /home/katie/videos/playlist.m3u &What it means: --loop repeat forever, --random shuffle the order on every boot, --no-audio mute, --no-qt-video-autoresize keep the window size, & let the desktop finish loading. (Older Bookworm images still on Wayfire: put vlc = vlc --loop --random --no-audio --no-qt-video-autoresize /home/katie/videos/playlist.m3u under [autostart] in ~/.config/wayfire.ini.)
Step 17 — Reboot and verify. sudo reboot. Within about 40 seconds VLC should appear maximized, silent, playing a random clip. If it comes up un-maximized: nano ~/.config/labwc/rc.xml. If the file is empty, paste all of this; if it already has text, paste only the <windowRules>…</windowRules> part on the lines just above the final </labwc_config>. Save, exit, sudo reboot.
<?xml version="1.0"?>
<labwc_config>
<windowRules>
<windowRule identifier="vlc">
<action name="Maximize"/>
</windowRule>
</windowRules>
</labwc_config>Step 18 — Cursor. Unplug the mouse and keyboard when you're done. With no pointer device the desktop won't draw a cursor, and the touchscreen does everything you need.
Step 19 — Optional: dim the backlight for battery and glare. cat /sys/class/backlight/*/max_brightness prints the maximum (often 255). Then sudo crontab -e (the first time, it asks which editor — press 1 for nano), go to the bottom, add this line (adjust 150 to taste), save, exit:
@reboot sleep 15; for b in /sys/class/backlight/*; do echo 150 > $b/brightness; donePhase 2Power validation~1 hour plus a soak
- Charge the bank fully.
- Chain it: bank USB-C → inline meter → right-angle cable → Pi. Boot with VLC playing.
- Watch the top-right corner for the lightning-bolt / low-voltage warning. If it appears: use the bank's USB-C port (not USB-A), a shorter or better cable, or a better bank.
- Read steady-state watts after 5 minutes. Runtime ≈ (mAh × 3.7 ÷ 1000 × 0.8) ÷ watts. Example: 20,000 mAh → 59 Wh usable → ~7 h at 8 W.
- Soak 30+ minutes. The bank must stay on with no reboots or flicker. Then wiggle the cable at the Pi's port: if the screen so much as blinks, that connector gets the double strain relief in Phase 4 (it should anyway).
- One full-length run before Halloween while you do something else. Write down the real runtime.
Phase 3Build the plate2–3 hours
- Dry-fit first, drill second. Lay the board flat. Place the display face-down, mark where its four threaded mounting bosses land on the board. Set the Pi next to that footprint and check the display's stock DSI ribbon reaches the Pi's connector with slack — move the Pi until it does, then trace it. Place the bank on the other side (bank on the left, Pi on the right matches the sketch), USB-C port facing the board's left edge. Trace it. Nothing overlaps the four boss positions.
- Drill the board: four M2.5 holes at the boss marks (display screws), four at the Pi's corners, and 3.2 mm holes for the strap anchors — two per anchor point, ~15 mm apart: two at each top corner, two at each mid-side, two at each bottom corner.
- Mount the Pi: heatsinks on first, then M2.5 × 12 screws from the back of the board, through 5 mm spacers, through the Pi's corner holes, nuts on top. Snug only.
- Mount the bank: velcro on the board under its traced spot, port toward the left edge. Rivet the 1" elastic keeper across the bay opening (one rivet each side) so the bank slides in under it and can be pulled out for a swap.
- Cable up: right-angle USB-C from the bank's port to the Pi. Loop the slack once and zip-tie it to a small hole drilled in the board. Connect the display's DSI ribbon and GPIO power lead to the Pi now, before the display goes on — dot of hot glue on the GPIO header connector.
- Foam perimeter wall: three 10 mm EVA layers glued into a 30 mm wall following the display's outline on the board — but leave the left side fully open (that's the battery bay) and cut a 40 mm notch in the top and bottom runs (vents). Run a strip of 1 mm foam tape along the wall's top face.
- Display on: lower the display onto the wall, screen up, ribbon inside. From the back of the board: M2.5 screw → board → 30 mm spacer → into the display's threaded boss. The bosses are shallow, so don't bottom the screws out — if a screw stops early, add a washer under its head rather than forcing it. Snug all four evenly.
- Pad the back: set all the strap rivets first (step B4.3), then contact-cement the 6 mm EVA pad over the whole body side, covering the rivet backs. Gaffer-tape the board edges.
Phase 4Elastic harness~1.5 hours
- Geometry (same as Plan A's): each shoulder band runs from a top-corner anchor, over that shoulder, crosses the other band on your back, and comes around your side to the opposite bottom-corner anchor. The waist band runs from mid-side anchor, around your back, to the other mid-side anchor.
- Fit before riveting — this is the step you can't undo. Cut the three pieces long. Safety-pin them to the board at the anchor points, put it on over the clothes you'll actually wear, and shorten each piece until the plate sits with its top edge just under your collarbones, snug enough that a jumping jack doesn't bounce it, loose enough to breathe and to pull on over your head. Elastic under load should sit at roughly 10–15% stretch. Mark every length, take it off, and only then rivet.
- Riveting: fold each elastic end over twice (three layers), melt or punch two 3.2 mm holes matching the anchor's hole pair, and rivet through washer → elastic → board → washer. Two rivets per anchor, exactly as the man said.
- Wear test per Phase 5 below, with two additions: check for bounce when walking fast (if it bounces, the waist band is too loose), and after 30 minutes of playback put your hand on the display glass and the board back — warm is fine, hot means the vent notches are blocked.
Phase 5Wear test~1 hour
- Boot it, put it on, and walk around for 20–30 minutes: stairs, sitting down, bending over, a doorway hug.
- Check: bounce when you walk fast (the waist elastic was riveted too loose), strap dig-in (pad the shoulders), heat (feel the display glass and the board back after 30 minutes; if you set up SSH,
vcgencmd measure_temp— under 70 °C is fine, throttling starts at 80), and that clothing isn't blocking the vent gaps. - Check the bank stays put in its bay through a jump, and that the keeper strap is easy to work one-handed.
- Fix, then repeat once. Then leave it alone — the last thing to change before the party is the thing that will fail.
Phase 6Lockdown15 minutes
Do this last, after every software tweak, because the next step makes the card read-only.
sudo raspi-config→ Performance Options → Overlay File System → enable, and write-protect the boot partition when asked. Reboot.- Verify VLC still autostarts. From now on, cutting power at any time cannot corrupt the card. To change anything later: raspi-config → disable overlay → reboot → change → re-enable.
- Boot-from-cold test: unplug, wait 5 seconds, plug in. Time it. That's your party reboot procedure.
Battery swap at the party
Reach under your left arm, pull the keeper strap, unplug the cable at the bank, slide it out, slide the charged one in, plug in. The Pi reboots into VLC on its own in about 40 seconds. Practice it once at home in the dark.
Halloween checklist
- ☐ Both slim banks charged to 100%; spare cable in a pocket; swap practiced once in the dark
- ☐ Two-minute power-on test at home before leaving, hat on, slab on
- ☐ If you set up SSH: hotspot on, SSH app ready. Either way, unplug/replug is a safe reboot once the filesystem is read-only
- ☐ Pocket kit: #1 Phillips, three zip ties, a strip of gaffer tape
- ☐ Leave the mouse at home — the touchscreen is the interface. Let people pause you.
Troubleshooting
| Symptom | Likely cause → fix |
|---|---|
| Black screen, Pi boots | DSI ribbon backwards or unseated; power lead on the wrong pins; wrong cable for your Pi model |
| Lightning bolt / low-voltage warning | Bank's USB-A port instead of USB-C; thin or long cable; weak bank |
| Pi 4 won't power up on C-to-C cable | Rev 1.1 board → USB-A to C cable |
| VLC opens but not maximized | Add the labwc window rule (Phase 1, step 13) |
| Window shrinks to the video's size on each clip | "Resize interface to video size" is still on |
| A dialog covers the video at boot | Privacy dialog or "Continue playback?" wasn't dismissed/disabled before lockdown |
| Cursor on screen | A pointer device is plugged in |
| Bank turns itself off | Rare at this draw — almost always a cable blip → redo strain relief; try the other cable |
| Pi runs hot / stutters | Blocked vent notches; no heatsink; drop backlight; check vcgencmd measure_temp |
| Touch is mapped wrong after rotation | Screen Configuration → Touchscreens → assign to DSI-1 |
| Changes don't persist | Overlay filesystem is enabled — disable, change, re-enable |
playlist.m3u is empty | Files aren't in ~/videos, or don't end in lowercase .mp4 |
| VLC plays one clip and stops | The autostart line is missing --loop (or, testing by hand, the loop button is off) |
| A clip has sound or the wrong size | It skipped conversion — every file in videos must come from the ready folder |
| Plate bounces when you walk | The waist elastic was riveted with too little stretch — drill out those two rivets and re-rivet that band shorter |
| Module runs hot | Vent notches blocked or bay covered — open the airflow, check vcgencmd measure_temp |