You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.2 KiB
143 lines
4.2 KiB
--[[
|
|
$Id$
|
|
|
|
Copyright © 2010 VideoLAN and AUTHORS
|
|
|
|
Authors: Julien 'Lta' BALLET <contact at lta dot io>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
--]]
|
|
local config = {}
|
|
config["base_url"] = "http://api.icast.io"
|
|
config["api_base_url"] = config.base_url.."/1"
|
|
|
|
local json = nil
|
|
local roots = nil
|
|
|
|
function json_init()
|
|
if json ~= nil then return false end
|
|
|
|
vlc.msg.dbg("JSON parser lazy initialization")
|
|
json = require ("dkjson")
|
|
|
|
-- Use vlc.stream to grab a remote json file, place it in a string,
|
|
-- decode it and return the decoded data.
|
|
json["parse_url"] = function(url)
|
|
local stream = vlc.stream(url)
|
|
local string = ""
|
|
local line = ""
|
|
|
|
repeat
|
|
line = stream:readline()
|
|
string = string..line
|
|
until line ~= nil
|
|
|
|
--print(string)
|
|
return json.decode(string)
|
|
end
|
|
end
|
|
|
|
-- VLC SD mandatory method, return the name and capabilities of this SD.
|
|
function descriptor()
|
|
return { title = "iCast Stream Directory", capabilities = {"search"} }
|
|
end
|
|
|
|
-- Utility function to replace nils by an empty string, borrowed from icecast.lua
|
|
function dropnil(s)
|
|
if s == nil then return "" else return s end
|
|
end
|
|
|
|
function roots_init()
|
|
if roots ~= nil then return nil end
|
|
|
|
roots = {
|
|
locals = vlc.sd.add_node({title="Local Streams"}),
|
|
cats = vlc.sd.add_node({title="Categories"}),
|
|
search = nil
|
|
}
|
|
end
|
|
|
|
-- Add this station to the discovered service list.
|
|
function station_add(node, station)
|
|
if station.streams == nil or station.streams[1] == nil then
|
|
return nil
|
|
end
|
|
|
|
item = node:add_subitem({
|
|
title = station.name,
|
|
path = station.streams[1]["uri"],
|
|
meta = {
|
|
["Listing Source"] = "icast.io",
|
|
["Listing Type"] = "radio",
|
|
["Icecast Bitrate"] = dropnil(station.streams[1].bitrate)
|
|
}
|
|
})
|
|
|
|
if station.slogan then
|
|
item:set_name(station.name..": "..station.slogan)
|
|
end
|
|
if station.genre_list then
|
|
item:set_genre(table.concat(station.genre_list, ", "))
|
|
end
|
|
if station.language then
|
|
item:set_language(station.language)
|
|
end
|
|
if station.logo.medium then
|
|
item:set_arturl(config.base_url..station.logo.medium)
|
|
end
|
|
end
|
|
|
|
-- Get an url to iCast's API, parse the returned stations and add them
|
|
-- to the list of discovered medias.
|
|
function stations_fetch(node, url)
|
|
json_init()
|
|
vlc.msg.info("Fetching stations from API ("..url..")")
|
|
|
|
local result = json.parse_url(config.api_base_url..url)
|
|
|
|
if result.stations == nil then
|
|
return nil
|
|
end
|
|
|
|
for _, station in ipairs(result.stations) do
|
|
station_add(node, station)
|
|
end
|
|
end
|
|
|
|
-- VLC SD API - Search entry point
|
|
function search(query)
|
|
if roots.search then vlc.sd.remove_node(roots.search) end
|
|
|
|
roots.search = vlc.sd.add_node({title="Search Results"})
|
|
|
|
stations_fetch(roots.search, "/stations/search.json?q="..query.."*")
|
|
end
|
|
|
|
-- VLC SD API - Main listing entry point
|
|
function main()
|
|
roots_init()
|
|
|
|
stations_fetch(roots.locals, "/stations/local.json")
|
|
|
|
vlc.msg.dbg("Fetching list of genre from API (/genres.json)")
|
|
local result = json.parse_url(config.api_base_url.."/genres.json")
|
|
for genre, sub_genres in pairs(result.genres) do
|
|
local node = roots.cats:add_subnode({title=genre})
|
|
for _, sub_genre in ipairs(sub_genres) do
|
|
local sub_node = node:add_subnode({title=sub_genre})
|
|
stations_fetch(sub_node, "/stations/genre/"..sub_genre..".json")
|
|
end
|
|
end
|
|
end
|
|
|