A stripped console-only Lua CLI for use with shell scripts
Posted: 05 Mar 2015 06:22
Consider this to be part of the VLC documentation (which is extremely lacking).
Feedback would be welcome. The copyright notice is adapted from host.lua.
Feedback would be welcome. The copyright notice is adapted from host.lua.
Code: Select all
--[==========================================================================[
shell.lua: A stripped console-only CLI for use with shell scripts
--[==========================================================================[
Copyright (C) 2015 nokangaroo nokangaroo@NOSPAM.aon.at
Work in progress
Based on host.lua and cli.lua
host.lua author: Antoine Cellerier <dionoea at videolan dot org>
cli.lua authors: Antoine Cellerier <dionoea at videolan dot org>
Pierre Ynard
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.
--]==========================================================================]
running = true
function quit()
vlc.misc.quit()
running = false
end
--Begin user-defined functions
--[[The input buffer is split into the global table "val"; val[0] is the
function itself, val[1] ... val[n] is a variable number of arguments. There is
no error handling (yet), and you cannot type commands at the commandline; this
interface is designed to take machine-generated input from a fifo.
Test this interface with:
luac5.1 <this file>
mkdir -p $HOME/.local/share/vlc/lua/intf
mv luac.out $HOME/.local/share/vlc/lua/intf/shell.luac
mkfifo fifo
exec 3<> fifo
vlc <&3 -I "luaintf{intf=shell}" /path/to/media
#Command example:
echo set_var input time 123.456 > fifo
...
]]
-- sample functions for testing (add whatever you need):
function set_time() --e.g. set_time 123.456
local val = val[1]
local input = vlc.object.input()
local check = (vlc.var.get(input,"length") - val)
if val and check > 0 then
vlc.var.set(input,"time",val)
end
end
function set_var() --e.g. set_var input chapter 1
local obj = val[1]
local var = val[2]
local value = val[3] --float or int depending on var
--it really should work like this:
--local string = string.format("%s%s(),\"%s\"","vlc\.object\.",obj,var)
local o
if obj == "input" then
o = vlc.object.input()
elseif obj == "aout" then
o = vlc.object.aout()
elseif obj == "vout" then
o = vlc.object.vout()
end
vlc.var.set(o,var,value)
end
--write variables to file
--[[for importing variables in shell scripts use something like this:
get_var() {
local i
cat /dev/null > $TMP
for i in "$@"; do
echo "write_var input $i $TMP" > $FIFO
done
eval `cat $TMP`
}
]]
function write_var() --e.g. write_var input title <path>
local obj = val[1]
local var = val[2]
local path = val[3]
local o
if obj == "input" then
o = vlc.object.input()
elseif obj == "aout" then
o = vlc.object.aout()
elseif obj == "vout" then
o = vlc.object.vout()
end
local value = vlc.var.get(o,var)
local file = io.open(tostring(path), "a+")
file:write(tostring(var) .. '=' .. tostring(value) .. '\n')
file:close()
end
--atrack and strack
--[[The listvalue function in cli.lua is bogus because elementary streams can
change on DVDs when switching back and forth between titlesets. The order of
tracks in the track list remains constant though; so we need to grep for the
matching track and then set audio-es or spu-es to the value in the 1st column.]]
function track() --e.g. track audio-es 3 or track spu-es 5
local var = val[1]
local value = val[2]
local o = vlc.object.input()
local v,l = vlc.var.get_list(o,var)
local val
for i,val in ipairs(v) do
local str = tostring(val)..tostring(l[i])
local str1 = string.format("Track %s", tostring(value))
if string.match(str,str1) then
local t = string.match(str,"^%d+")
vlc.var.set(o,var,t)
break
end
end
end
--End user-defined functions
--Utility: split buffer at word boundaries
--Add stuff to the regex in string.gmatch if needed
function split_input(str)
local j = 0
val = {}
for i in string.gmatch(str,"[%w_/-]+") do --local i not needed
val[j] = i
--num_args = j
j = j+1
end
end
--???????????????????????????????????????
--Can someone explain what these are for?
--function on_read(client)
--end
--function on_write(client)
--end
--???????????????????????????????????????
require "host"
h = host.host()
-- Bypass any authentication
function on_password(client)
client:switch_status(host.status.read)
end
h.status_callbacks[host.status.password] = on_password
--h.status_callbacks[host.status.read] = on_read
--h.status_callbacks[host.status.write] = on_write
h:listen("*console")
-- The main loop (cribbed from cli.lua and host.lua)
while running do
-- accept new connections and select active clients
local write,read = h:accept_and_select()
-- handle clients in write mode
for _, client in pairs(write) do
client:send()
client.buffer = ""
client:switch_status(host.status.read)
end
-- handle clients in read mode
for _, client in pairs(read) do
local input = client:recv(1000) --[[this seems to be the number of bytes
received. If so, could probably be less for a pure console interface]]
if not input then break end
client.cmds = input .. '\n'
client.buffer = client.cmds
client:switch_status(host.status.write)
split_input(client.buffer)
_G[val[0]]()
end
end