--[==========================================================================[
rc.lua: remote control module for VLC
--[==========================================================================[
- Copyright (C) 2007 the VideoLAN team
+ Copyright (C) 2007-2009 the VideoLAN team
$Id$
Authors: Antoine Cellerier <dionoea at videolan dot org>
Remote control interface for VLC
This is a modules/control/rc.c look alike (with a bunch of new features)
-
+
Use on local term:
vlc -I luarc
Use on tcp connection:
vlc -I luarc --lua-config "rc={host='localhost:4212'}"
Use on multiple hosts (term + 2 tcp ports):
vlc -I luarc --lua-config "rc={hosts={'*console','localhost:4212','localhost:5678'}}"
-
+
Note:
-I luarc is an alias for -I lua --lua-intf rc
if config[k] then
if type(env[k]) == type(config[k]) then
env[k] = config[k]
- vlc.msg.dbg("set environement variable `"..k.."' to "..tonumber(env[k]))
+ vlc.msg.dbg("set environement variable `"..k.."' to "..tostring(env[k]))
else
vlc.msg.err("environement variable `"..k.."' should be of type "..type(env[k])..". config value will be discarded.")
end
end
function add(name,client,arg)
+ -- TODO: par single and double quotes properly
local f
if name == "enqueue" then
f = vlc.playlist.enqueue
end
function input_info(name,client)
- local categories = vlc.input_info()
+ local categories = vlc.input.info()
for cat, infos in pairs(categories) do
client:append("+----[ "..cat.." ]")
client:append("|")
client:append("+----[ end of stream info ]")
end
+function stats(name,client)
+ local stats_tab = vlc.input.stats()
+
+ client:append("+----[ begin of statistical info")
+ client:append("+-[Incoming]")
+ client:append("| input bytes read : "..string.format("%8.0f kB",stats_tab["read_bytes"]/1000))
+ client:append("| input bitrate : "..string.format("%6.0f bB/s",stats_tab["input_bitrate"]*8000))
+ client:append("| demux bytes read : "..string.format("%8.0f kB",stats_tab["demux_read_bytes"]/1000))
+ client:append("| demux bitrate : "..string.format("%6.0f kB/s",stats_tab["demux_bitrate"]*8000))
+ client:append("| demux corrupted : "..string.format("%5i",stats_tab["demux_corrupted"]))
+ client:append("| discontinuities : "..string.format("%5i",stats_tab["demux_discontinuity"]))
+ client:append("|")
+ client:append("+-[Video Decoding]")
+ client:append("| video decoded : "..string.format("%5i",stats_tab["decoded_video"]))
+ client:append("| frames displayed : "..string.format("%5i",stats_tab["displayed_pictures"]))
+ client:append("| frames lost : "..string.format("%5i",stats_tab["lost_pictures"]))
+ client:append("|")
+ client:append("+-[Audio Decoding]")
+ client:append("| audio decoded : "..string.format("%5i",stats_tab["decoded_audio"]))
+ client:append("| buffers played : "..string.format("%5i",stats_tab["played_abuffers"]))
+ client:append("| buffers lost : "..string.format("%5i",stats_tab["lost_abuffers"]))
+ client:append("|")
+ client:append("+-[Streaming]")
+ client:append("| packets sent : "..string.format("%5i",stats_tab["sent_packets"]))
+ client:append("| bytes sent : "..string.format("%8.0f kB",stats_tab["sent_bytes"]/1000))
+ client:append("| sending bitrate : "..string.format("%6.0f kb/s",stats_tab["send_bitrate"]*8000))
+ client:append("+----[ end of statistical info ]")
+end
+
function playlist_status(name,client)
local a,b,c = vlc.playlist.status()
client:append( "( new input: " .. tostring(a) .. " )" )
return function(discard,client,...) client:append(start..tostring(foo(...))..stop) end
end
-function get_time(var,client)
- return function()
+function get_time(var)
+ return function(name,client)
local input = vlc.object.input()
client:append(math.floor(vlc.var.get( input, var )))
end
else
local item = vlc.var.get( input, var )
-- Todo: add item name conversion
- client:apped(item)
+ client:append(item)
end
end
function titlechap_offset(client,offset)
function rate(name,client)
local input = vlc.object.input()
if name == "normal" then
- vlc.var.set(input,"rate",1000) -- FIXME: INPUT_RATE_DEFAULT
+ vlc.var.set(input,"rate",1)
else
vlc.var.set(input,"rate-"..name,nil)
end
end
+function frame(name,client)
+ vlc.var.trigger_callback(vlc.object.input(),"frame-next");
+end
+
function listvalue(obj,var)
return function(client,value)
local o = vlc.object.find(nil,obj,"anywhere")
{ "faster"; { func = rate; help = "faster playing of stream" } };
{ "slower"; { func = rate; help = "slower playing of stream" } };
{ "normal"; { func = rate; help = "normal playing of stream" } };
+ { "frame"; { func = frame; help = "play frame by frame" } };
{ "fullscreen"; { func = skip2(vlc.video.fullscreen); args = "[on|off]"; help = "toggle fullscreen"; aliases = { "f", "F" } } };
{ "info"; { func = input_info; help = "information about the current stream" } };
+ { "stats"; { func = stats; help = "show statistical information" } };
{ "get_time"; { func = get_time("time"); help = "seconds elapsed since stream's beginning" } };
{ "is_playing"; { func = is_playing; help = "1 if a stream plays, 0 otherwise" } };
{ "get_title"; { func = ret_print(vlc.input.get_title); help = "the title of the current stream" } };
end
end
list = list..")"
- if count ~= 0 then
+ if count ~= 0 and env.welcome then
env.welcome = env.welcome .. "\r\nWarning: "..count.." functions are still unimplemented "..list.."."
end
end
return vlcerr
end
+function call_object_command(cmd,client,arg)
+ local var, val = split_input(arg)
+ local ok, vlcmsg, vlcerr, vlcerrmsg = pcall( vlc.var.command, cmd, var, val )
+ if not ok then
+ client:append("Error in `"..cmd.." "..var.." "..val.."' ".. vlcmsg) -- when pcall fails the 2nd arg is the error message
+ end
+ if vlcmsg ~= "" then
+ client:append(vlcmsg)
+ end
+ return vlcerr
+end
+
--[[ Setup host ]]
require("host")
h = host.host()
client:switch_status(host.status.write)
if commands[cmd] then
call_command(cmd,client,arg)
+ elseif string.sub(cmd,0,1)=='@'
+ and call_object_command(string.sub(cmd,2,#cmd),client,arg) == 0 then
+ --
+ elseif client.type == host.client_type.stdio
+ and call_libvlc_command(cmd,client,arg) == 0 then
+ --
else
- if client.type == host.client_type.stdio
- and call_libvlc_command(cmd,client,arg) == 0 then
- else
- local choices = {}
- if client.env.autocompletion ~= 0 then
- for v,_ in common.pairs_sorted(commands) do
- if string.sub(v,0,#cmd)==cmd then
- table.insert(choices, v)
- end
+ local choices = {}
+ if client.env.autocompletion ~= 0 then
+ for v,_ in common.pairs_sorted(commands) do
+ if string.sub(v,0,#cmd)==cmd then
+ table.insert(choices, v)
end
end
- if #choices == 1 and client.env.autoalias ~= 0 then
- -- client:append("Aliasing to \""..choices[1].."\".")
- cmd = choices[1]
- call_command(cmd,client,arg)
- else
- client:append("Unknown command `"..cmd.."'. Type `help' for help.")
- if #choices ~= 0 then
- client:append("Possible choices are:")
- local cols = math.floor(client.env.width/(client.env.colwidth+1))
- local fmt = "%-"..client.env.colwidth.."s"
- for i = 1, #choices do
- choices[i] = string.format(fmt,choices[i])
- end
- for i = 1, #choices, cols do
- local j = i + cols - 1
- if j > #choices then j = #choices end
- client:append(" "..table.concat(choices," ",i,j))
- end
+ end
+ if #choices == 1 and client.env.autoalias ~= 0 then
+ -- client:append("Aliasing to \""..choices[1].."\".")
+ cmd = choices[1]
+ call_command(cmd,client,arg)
+ else
+ client:append("Unknown command `"..cmd.."'. Type `help' for help.")
+ if #choices ~= 0 then
+ client:append("Possible choices are:")
+ local cols = math.floor(client.env.width/(client.env.colwidth+1))
+ local fmt = "%-"..client.env.colwidth.."s"
+ for i = 1, #choices do
+ choices[i] = string.format(fmt,choices[i])
+ end
+ for i = 1, #choices, cols do
+ local j = i + cols - 1
+ if j > #choices then j = #choices end
+ client:append(" "..table.concat(choices," ",i,j))
end
end
end