DEV Community

Cover image for 700,000 people watched a VLC redesign. I built the player.
Nirmal Joseph Ukken
Nirmal Joseph Ukken

Posted on

700,000 people watched a VLC redesign. I built the player.

A VLC redesign video went up on YouTube, and I caught it the day after it was released. It already had about half a million views and around 2,000 comments, and the comments kept asking the same thing: Is this real? Can I actually use it? Will VLC ever look like this?

It's now past 700,000 views, and the answer to those comments is still no. It's a design concept, not an app.

Seeing that much demand, I thought: why not try building it myself? Within two days I had a working media player on my PC, set as my default app, with installers for Windows, Linux and macOS.

This is the story of Pylon: where the idea came from, how it's built, what broke along the way, and what I learned shipping a desktop app.

GitHub logo nirmaljosephukken / pylon-player

A calmer, redesigned interface for the VLC engine on Windows. Hover-only controls, drag-to-sync subtitle timeline, per-show presets, library and queue. Based on Juxtopposed's VLC redesign.

Pylon

A calmer, redesigned interface for the VLC engine, for Windows, Linux and (experimentally) macOS.

Download: Windows · Linux · macOS (experimental) · All releases
You also need VLC installed. See Install.

Pylon puts a new interface on top of libVLC, the engine inside VLC media player. VLC still does all the playback, decoding, subtitles and streaming, so Pylon plays everything VLC plays. The interface is built around the way people actually watch: quiet bars that get out of the way, a thick seek bar, subtitle timing you can see, per-show presets, and a library and queue you can reach without leaving the video.

Beta. Tested on Windows 10/11 and Ubuntu; the macOS build hasn't been tried on a real Mac yet. Bug reports are very welcome.

Pylon playing a video

Library, queue and settings sidebar

Credit

The interface follows the VLC redesign concept by Juxtopposed:

It started with a YouTube video

Juxtopposed published a redesign concept for VLC media player. VLC is the player everyone has installed and nobody calls beautiful. The redesign kept everything that makes VLC great and rethought how it feels to watch something: quieter controls, a seek bar you can actually hit, subtitle timing you can see, and settings that don't throw a dialog over your video.

The design was shared on Figma Community under a Creative Commons licence. But it was a concept, not an app, and judging by the comments, I wasn't the only one who wanted to use it, every day, on their own files.

Skin or wrapper?

My first thought was a VLC skin. VLC does support skins, but they can only rearrange and restyle VLC's existing controls. The ideas I liked most (a subtitle timeline, a settings sidebar, a real queue, a home page with "continue watching") need new behaviour, not just new pixels.

So I went the other way: a new app with VLC's engine inside it. VLC ships its playback engine as a library, libVLC. Pylon is a new interface on top of that library. VLC still does all the decoding, subtitles and streaming, so Pylon plays everything VLC plays.

The stack:

  • Python for the app
  • Qt for Python (PySide6) for the interface
  • python-vlc to talk to libVLC
  • VLC 3.0, installed separately, for the actual playback

What it looks like

Pylon playing a video, with quiet bars along the top and bottom

The features I built from the concept, plus a few of my own:

  • Quiet bars. The top and bottom bars float over the video, appear when you move the mouse, and disappear when you stop. They work in fullscreen too. H hides everything.
  • A thick seek bar with hover time, bookmark ticks and chapter marks.
  • Cone volume. A volume control shaped like a traffic cone lying on its side. Click, drag or scroll, up to 125%.
  • A settings sidebar (Ctrl+T) with Subtitles, Audio, Video, Playback and Bookmarks tabs, so nothing covers the video.
  • A subtitle timeline. You can see where subtitle lines fall around the playhead and drag them until they line up with the speech.
  • Per-show presets. Save subtitle timing, look, tracks and speed once, and every episode in that folder uses them.
  • Subtitles in bulk. Add subtitles to a whole season at once. Files are matched by episode number (S01E02, 1x02, E02).
  • A real queue and library. Playing an episode queues the rest of the folder, so the next one just plays.
  • On-screen hints. Every key you press shows what it did, and every shortcut can be changed.

Library, queue and settings sidebar open next to the video

The interesting problems

1. Drawing on top of a video you don't own

libVLC draws video straight into a native window, using the window handle you give it:

player = instance.media_player_new()
player.set_hwnd(int(video_widget.winId()))      # Windows
# player.set_xwindow(...) on Linux, set_nsobject(...) on macOS
Enter fullscreen mode Exit fullscreen mode

That's fast, but it means Qt can't paint over that area. Any button you put "on top" of the video simply isn't visible. The fix was to make the top and bottom bars their own small frameless, translucent windows that float above the video and follow the main window around. It sounds hacky, but it's how you get controls that fade over the picture.

2. The player froze, and then it didn't play at all

libVLC reports events (playing, paused, ended, length changed) from its own thread. My first version called back into VLC from inside those event handlers, and every so often playback froze. The rule I ended up with: event handlers only emit a Qt signal, nothing else. The GUI thread then asks the player for the real values.

# runs on a VLC thread: never touch the player here
em.event_attach(vlc.EventType.MediaPlayerPlaying,
                lambda e: self.state_changed.emit("playing"))

# and connect it so Qt delivers it on the GUI thread
engine.state_changed.connect(self.on_state, Qt.QueuedConnection)
Enter fullscreen mode Exit fullscreen mode

Qt.QueuedConnection turned out to matter. stop() fires its "stopped" event on the calling thread, so a direct connection could re-enter the player while it was still stopping, and the app locked up.

Then, on my actual Windows PC, nothing played at all. The clock sat at 0:00. A small diagnostic script showed play() returning -1. The cause was a single character: Qt gives you paths with forward slashes (D:/Movies/file.mkv), and VLC on Windows wanted backslashes. One os.path.normpath() later, it played.

3. Making it the default player on Windows

I wanted to double-click a video and have it open in Pylon. Windows lists apps in Default apps by their .exe, and Pylon was a Python script, so it showed up as "Python" or not at all.

The fix was a tiny launcher, Pylon.exe, written in C. It finds the bundled Python next to it and starts the app with the file you clicked. It's about 90 KB and has Pylon's own icon, so Windows treats Pylon like any other app. The installer then registers Pylon under "Open with" for 34 video and audio types. Windows doesn't let apps make themselves the default, so the last click is still yours.

4. One-click installers

Asking people to install Python, then pip packages, then run a script, loses most of them. So each download now carries its own Python and Qt:

Download
Windows 10/11 Pylon-Setup.exe, a per-user installer (no admin needed)
Linux an AppImage: chmod +x, then run
macOS (experimental) a zipped .app

Qt is big, so I trimmed it to the modules Pylon actually imports (Core, Gui, Widgets, Svg, Network) by reading each library's import table. That keeps the Windows installer around 22 MB.

VLC is never bundled. You install VLC yourself and Pylon finds it. That keeps the licensing simple and means you get VLC's own updates.

5. The bug my first real user found

Version 1.1.0 worked on my test setups, then didn't find VLC on my own PC. The reason: when you pick a folder with the installer's Browse button, the installer adds \Pylon to the end. My VLC was at E:\Softwares\VLC, Pylon ended up in E:\Softwares\Pylon-1.1\Pylon, and Pylon only looked one folder up.

Version 1.1.1 now looks in a few folders above itself as well as the usual places, setup saves the VLC location it finds, and if you point Pylon at VLC by hand it starts using it immediately instead of asking for a restart. Small fix, but it's exactly the kind of thing you only find by installing your own app like a stranger would.

The name

It started as "Cone Player", after VLC's traffic-cone logo. That was too close to VLC's trademark, so I renamed it Pylon: another word for a traffic cone, and a nod to where it came from without borrowing anything.

Doing it properly: credit and licences

Because this builds on other people's work, I tried to get the boring parts right:

  • The design is credited to Juxtopposed in the README and in the app's About box. The Figma file is under CC BY 4.0, which allows adaptations with credit. No files or artwork from it are included; the interface is rebuilt in code.
  • VLC and VideoLAN: Pylon says clearly that it isn't affiliated with or endorsed by VideoLAN, and it doesn't use the VLC name or cone logo as its own.
  • The code is MIT licensed. The bundled Python, Qt for Python and python-vlc keep their own licences (PSF, LGPLv3, LGPL 2.1+), and those licence texts ship with every download.

How I built it

I built Pylon with Claude (Anthropic's AI) as my pair programmer. My part was the product side: deciding what to build from the concept, testing every version on my own Windows PC, finding what broke, and deciding what "good" looked like. Claude wrote most of the code, the installers and the documentation with me, one problem at a time.

What surprised me most is how much of shipping software isn't the main feature. Getting a video on screen was the easy part. The rest was paths, threads, file associations, installers, licences and an installer that adds \Pylon to your folder.

What's next

Not built yet from the original concept: thumbnails while seeking, a waveform seek bar, music sorted by artist and album, and casting. The macOS build also still needs someone with a real Mac to try it.

Try it

To everyone in those comments asking "can I actually use this?": now you can. I'd love to hear what you think, especially which feature you'd want next. And if you haven't seen Juxtopposed's video, go watch it. None of this exists without it.

Top comments (0)