When I'm programming I like to listen to music, as I find it blocks out distractions and keeps my mind focused. I usually listen to a variety of streaming chillout radio stations using my command line application PyRadio. I was recently reading through the Lua wikipedia page and noticed that VLC media player has support for Lua plugins, and thought that creating a streaming radio plugin would be a great way to learn some Lua, as well as giving me a new way of listening to my music.
Getting up and running
Support for Lua extensions was added to VLC in version 1.1, which is still in beta. You can get the beta version from the VLC nightlies site, or follow this helpful guide on upgrading for Ubuntu users. I followed the guide, and after getting VLC 1.1.5 installed I was keen to try some of the sample extensions, but none of them worked! Running vlc -vvv
from the command line allowed me to see the debug output and track down the problems. I fixed the majority of the issues by simply removing quotes around function references (eg. add_button("OK", "button_clicked")
-> add_button("OK", button_clicked)
).
Documentation
The documentation for writing Lua extensions is definitely lacking. It seems to consist of a single README file and the broken sample extensions. Fortunately it's a fairly simple API, and the Lua documentation itself is fantastic (there's a reference manual, an active community wiki, and even a free book).
The streaming radio extension
After going through the README and sample extensions, and some trial and error, I was able to put together the streaming radio extension shown at the top of this post. I'm really pleased with the results, and I'm actually using it right now as I write this post! The full code listing for the extension is below:
--[[
Streaming Radio Player extension for VLC >= 1.1.0
Authors: Ben Dowling (http://www.coderholic.com)
--]]
stations = {
{ name = "SomaFM: Groove Salad", url = "http://somafm.com/startstream=groovesalad.pls" },
{ name = "Digitally Imported: Chillout", url = "http://listen.di.fm/public3/chillout.pls" },
{ name = "Digitally Imported: Chillout Dreams", url = "http://listen.di.fm/public3/chilloutdreams.pls" },
{ name = "Digitally Imported: Soulful House", url = "http://listen.di.fm/public3/soulfulhouse.pls" },
{ name = "Digitally Imported: Lounge", url = "http://listen.di.fm/public3/lounge.pls" },
{ name = "Monkey Radio Groove", url = "http://groove.monkeyradio.org/"},
{ name = "SKY.FM Jazz", url = "http://www.sky.fm/mp3/jazz.pls"},
{ name = "SKY.FM Smooth Jazz", url = "http://www.sky.fm/mp3/smoothjazz.pls"},
{ name = "SKY.FM Uptempo Smooth Jazz", url = "http://www.sky.fm/mp3/uptemposmoothjazz.pls"},
}
function descriptor()
return { title = "Streaming Radio Player" ;
version = "0.1" ;
author = "Ben Dowling" ;
capabilities = {} }
end
function activate()
dlg = vlc.dialog("Streaming Radio Player")
list = dlg:add_list(1, 3, 4, 1)
button_play = dlg:add_button("Play", click_play, 1, 4, 4, 1)
-- Add the radio stations
for idx, details in ipairs(stations) do
list:add_value(details.name, idx)
end
dlg:show()
end
function click_play()
selection = list:get_selection()
if (not selection) then return 1 end
local sel = nil
for idx, selectedItem in pairs(selection) do
sel = idx
break
end
details = stations[sel]
-- Play the selected radio station
vlc.playlist.clear()
vlc.playlist.add()
vlc.playlist.play()
end
function deactivate()
end
function close()
vlc.deactivate()
end
It's a testament to the power of the VLC extension API how little code is required. Hopefully by the time 1.1 comes out of beta the documentation will have improved, and we'll start to see lots of really useful extensions.
Thoughts on Lua
One of the aims of writing the VLC extension was to learn Lua. It seems very similar to JavaScript, but with fewer bad parts, and some really nice additions. When writing the extension I got some exposure to Lua's table data structure. It initially struck me as similar to PHP's array structure, but I ran into trouble when specifying keys:
-- What I thought would work but didn't
{ "key" = "value" }
-- What does work (if the key doesn't contain spaces)
{ key = "value" }
-- Key with spaces
{ ["a key"] = "value" }
It still seems strange to me, but I'm sure there's a good reason.
If you've had experience with Lua (or you've got some good ideas for another VLC extension!) please let me know your thoughts in the comments.