fltkhs-media-player
is a simple demo app showing how to use FLTKHS to create a Haskell native gui app that can embed movies using libVLC. It is very much a little friendly competition to the movie monad project which builds a similar app in GTK+ using GStreamer. Below I compare the two projects, the underlying toolkits and the Haskell bindings.
Currently the app works well on Linux and Windows. On OSX it compiles and pops up the GUI but there is no video output. Even when it works please expect pre-alpha quality, I didn’t know anything about VLC before starting this so it may well hiccup or even segfault.
On Linux first install VLC from your package manager which should provide the necessary VLC libraries and plugins. Once that’s done, clone this repo and:
> stack build --flag fltkhs:bundled > stack exec fltkhs-media-player-exe
The Windows install of VLC does not distribute the libraries so the process is a little more involved but I’ve hidden it away in shell scripts. First install 7-Zip and an MSYS and Stack environment , then clone this repo and:
> sh win64-build.sh > sh win64-run.sh
The shell script will first download a Win64 VLC archive, unpack it locally and use it provide header files and build/runtime libraries.
On OSX the app compiles and runs but video doesn’t work at all. If you try to open a file it does nothing and spits out an error to the console about not being able to make a video output device. This is a VLC issue and I have no idea how to fix this. But if you want to try it out, install wget:
> brew install wget
clone this repo and:
> sh osx-build.sh > sh osx-run.sh
The shell script downloads and locally unpacks the latest OSX dmg which contains the necessary libraries and plugins. This way you don’t have to install VLC just to try out the app.
First off here’s how movie monad is better:
- It looks nicer. GTK+ just has nicer widgets and themeability. FLTKHS apps can look good, all of the necessary knobs are there, but the user has to make the effort and default look isn’t great.
- It has a little more functionality, an About window and way to change the resolution of the movie. I didn’t bother with an About window because I didn’t see a need for it just for comparison, it’s pretty easy to add. The second feature I’m sure is quite possible with VLC but I just didn’t have time to figure it out, which brings me to …
- GTK+ and thus GTK2HS interops seamlessly with GStreamer. With VLC no good Haskell bindings exist so I had to write my own for just the parts I cared about. Writing the bindings was easy but as a complete newbie to VLC figuring out which parts of the API I needed was royal pain. I ended up stealing a lot from the flvlc project but nice bindings a la GTK+/GStreamer would have removed heaps of complexity.
And here’s where I think FLTKHS shines:
- Ease of installation, hands down. No need for
gtk2hs-buildtools
,gobject
bindings,X11
on OSX, or evenGTK+
, the bundled build handles it all for you and gives you a mostly statically linked app with as few runtime dependencies as possible. - Creating custom widgets. Even though FLTKHS doesn’t come with a way of hooking up to VLC, I was able to override the
show
method in the underlying toolkit to directly in Haskell without having to dip into C. With the current GTK bindings I’m not even sure overriding core functionality is possible. FLTKHS is just a much more flexible binding. - Like movie monad this app also uses a GUI builder to layout the main screen. I think it’s better because it doesn’t have to load the Glade file, use strings to pull out the variables from an XML file and a builder to construct the objects at runtime. Instead the FLUID/Haskell integration straight up produces Haskell code inside a standard Haskell function at build time so in your app you just import the module and just use it. If there’s mistakes the compiler catches it. And all this is completely transparent to the user. The only downside is if there are type errors they point to the produced Haskell file which is located somwhere deep in your
.stack-work
’s directory so that can be confusing .