diff --git a/resources/syncplay.lua b/resources/syncplay.lua
index 41554db..302bb05 100644
--- a/resources/syncplay.lua
+++ b/resources/syncplay.lua
@@ -3,12 +3,49 @@
--[==========================================================================[
Author: Etoh
+ Project: http://syncplay.pl
+
+--[==========================================================================[
+
+ === Commands and response ===
+ = Note: ? is optional response, * is mandatory response; uses \n terminator
+
+ [On connect]
+ >> VLC version
+
+ .
+ ? >> inputstate-change: []
+ ? >> filepath-change: [filepath URI]
+ ? >> file-length: [decimal seconds]
+
+ * >> playstate: []
+ * >> position: []
+
+ get-interface-version
+ * >> interface-version: [sncplay connector version]
+
+ set-position: [decimal seconds]
+ ? >> play-error: no-input
+
+ set-playstate: []
+ ? >> set-playstate-error: no-input
+
+ set-rate: [decimal rate]
+ ? >> set-rate-error: no-input
+
+ display-osd: [placement on screen ], [duration in seconds], [message]
+ ? >> display-osd-error: no-input
+
+ close-vlc
+
+ [Unknown command]
+ * >> [Unknown command]-error: unknown-command
--]==========================================================================]
require "common"
require "host"
-local connectorversion = "0.0.2"
+local connectorversion = "0.0.3"
local port
@@ -18,42 +55,77 @@ local argseperator = ", "
local responsemarker = "-response"
local errormarker = "-error"
+local notificationmarker = "-notification"
local noinput = "no-input"
local notimplemented = "not-implemented"
local unknowncommand = "unknown-command"
+
+local oldfilepath
+local oldinputstate
+local newfilepath
+local newinputstate
-function get_args (argument, argcount)
- local argarray = {}
- local index
- local i
- local argbuffer
-
- argbuffer = argument
+function detectchanges()
- for i = 1, argcount,1 do
- if i == argcount then
- if argbuffer == nil then
- argarray[i] = ""
- else
- argarray[i] = argbuffer
- end
- else
- if string.find(argbuffer, argseperator) then
- index = string.find(argbuffer, argseperator)
- argarray[i] = string.sub(argbuffer, 0, index - 1)
- argbuffer = string.sub(argbuffer, index + string.len(argseperator))
- else
- argarray[i] = ""
- end
- end
-
- end
-
- return argarray
-
+ local notificationbuffer = ""
+
+ if vlc.object.input() then
+ newinputstate = "input"
+ newfilepath = get_filepath()
+
+ if newfilepath ~= oldfilepath then
+ oldfilepath = newfilepath
+ notificationbuffer = notificationbuffer .. "filepath-change"..msgseperator..tostring(newfilepath)..msgterminator
+ notificationbuffer = notificationbuffer .. "file-length-change"..msgseperator..get_var("length")..msgterminator
+ end
+
+ notificationbuffer = notificationbuffer .. "playstate"..msgseperator..tostring(get_play_state())..msgterminator
+ notificationbuffer = notificationbuffer .. "position"..msgseperator..tostring(get_var("time"))..msgterminator
+ else
+ notificationbuffer = notificationbuffer .. "playstate"..msgseperator..noinput..msgterminator
+ notificationbuffer = notificationbuffer .. "position"..msgseperator..noinput..msgterminator
+ newinputstate = noinput
+ end
+
+ if newinputstate ~= oldinputstate then
+ oldinputstate = newinputstate
+ notificationbuffer = "inputstate-change"..msgseperator..tostring(newinputstate)..msgterminator..notificationbuffer
+ end
+
+ return notificationbuffer
end
+function get_args (argument, argcount)
+ local argarray = {}
+ local index
+ local i
+ local argbuffer
+
+ argbuffer = argument
+
+ for i = 1, argcount,1 do
+ if i == argcount then
+ if argbuffer == nil then
+ argarray[i] = ""
+ else
+ argarray[i] = argbuffer
+ end
+ else
+ if string.find(argbuffer, argseperator) then
+ index = string.find(argbuffer, argseperator)
+ argarray[i] = string.sub(argbuffer, 0, index - 1)
+ argbuffer = string.sub(argbuffer, index + string.len(argseperator))
+ else
+ argarray[i] = ""
+ end
+ end
+
+ end
+
+ return argarray
+
+end
port = tonumber(config["port"])
if (port == nil or port < 1) then port = 4123 end
@@ -64,238 +136,209 @@ h = host.host()
-- Bypass any authentication
function on_password( client )
- client:switch_status( host.status.read )
+ client:switch_status( host.status.read )
end
function get_var( vartoget )
- local response
- local errormsg
- local input = vlc.object.input()
-
- if input then
- response = vlc.var.get(input,tostring(vartoget))
- else
- errormsg = noinput
- end
-
- vlc.msg.info("getvar `"..tostring(vartoget).."`: '"..tostring(response).."'")
-
- return response, errormsg
+ local response
+ local errormsg
+ local input = vlc.object.input()
+
+ if input then
+ response = vlc.var.get(input,tostring(vartoget))
+ else
+ errormsg = noinput
+ end
+
+ return response, errormsg
end
function set_var(vartoset, varvalue)
- local errormsg
- local input = vlc.object.input()
-
- if input then
- vlc.var.set(input,tostring(vartoset),tostring(varvalue))
- else
- errormsg = noinput
- end
- vlc.msg.info("setvar: '"..tostring(vartoset).."' = '"..tostring(varvalue).."'")
- return errormsg
+ local errormsg
+ local input = vlc.object.input()
+
+ if input then
+ vlc.var.set(input,tostring(vartoset),tostring(varvalue))
+ else
+ errormsg = noinput
+ end
+
+ return errormsg
end
h:listen( "localhost:"..port)
- --h:listen( "*console" )
-
+-- h:listen( "*console" )
+
function get_play_state()
- local response
- local errormsg
- local input = vlc.object.input()
-
- if input then
- response = vlc.playlist.status()
- else
- errormsg = noinput
- end
-
- vlc.msg.info("get play state: '"..tostring(response).."'")
-
- return response, errormsg
-
+ local response
+ local errormsg
+ local input = vlc.object.input()
+
+ if input then
+ response = vlc.playlist.status()
+ else
+ errormsg = noinput
+ end
+
+ return response, errormsg
+
end
function get_filepath ()
- local response
- local errormsg
- local item
- local input = vlc.object.input()
-
- if input then
- local item = vlc.input.item()
- if item then
- response = vlc.strings.decode_uri(item:uri())
- else
- errormsg = noinput
- end
- else
- errormsg = noinput
- end
-
- return response, errormsg
+ local response
+ local errormsg
+ local item
+ local input = vlc.object.input()
+
+ if input then
+ local item = vlc.input.item()
+ if item then
+ response = vlc.strings.decode_uri(item:uri())
+ else
+ errormsg = noinput
+ end
+ else
+ errormsg = noinput
+ end
+
+ return response, errormsg
+end
+
+function get_filename ()
+ local response
+ local errormsg
+ local input = vlc.object.input()
+
+ if input then
+ local item = vlc.input.item()
+ if item then
+ response = item:name()
+ else
+ errormsg = noinput
+ end
+ else
+ errormsg = noinput
+ end
+
+ return response, errormsg
end
function display_osd ( argument )
- local errormsg
- local osdarray
- local input = vlc.object.input()
- if input then
- osdarray = get_args(argument,3)
- --position, duration, message -> message, , position, duration
- vlc.osd.message(osdarray[3],channel1,osdarray[1],tonumber(osdarray[2]))
- else
- errormsg = noinput
- end
- return errormsg
+ local errormsg
+ local osdarray
+ local input = vlc.object.input()
+ if input then
+ osdarray = get_args(argument,3)
+ --position, duration, message -> message, , position, duration (converted from seconds to microseconds)
+ local osdduration = tonumber(osdarray[2]) * 1000 * 1000
+ vlc.osd.message(osdarray[3],channel1,osdarray[1],osdduration)
+ else
+ errormsg = noinput
+ end
+ return errormsg
end
-
+
function do_command ( command, argument)
+ if command == "." then
+ do return detectchanges() end
+ end
+ local command = tostring(command)
+ local argument = tostring(argument)
+ local errormsg = ""
+ local response = ""
- local command = tostring(command)
- local argument = tostring(argument)
- local errormsg = ""
- local response = ""
+ local input = vlc.object.input()
+
+
- vlc.msg.info("Command: '"..command.."'")
- vlc.msg.info("Argument: '"..argument.."'")
-
- local input = vlc.object.input()
+ if command == "get-interface-version" then response = "interface-version"..msgseperator..connectorversion..msgterminator
+ elseif command == "set-position" then errormsg = set_var("time", tonumber(argument))
+ elseif command == "set-playstate" then errormsg = set_playstate(argument)
+ elseif command == "set-rate" then errormsg = set_var("rate", tonumber(argument))
+ elseif command == "display-osd" then errormsg = display_osd(argument)
+ elseif command == "close-vlc" then misc.quit()
+ else errormsg = unknowncommand
+ end
+
+ if (tostring(errormsg) ~= nil) and (errormsg ~= "") then
+ response = command..errormarker..msgseperator..tostring(errormsg)..msgterminator
+ end
- if command == "get-playstate" then response, errormsg = get_play_state()
- elseif command == "get-time" then response, errormsg = get_var("time")
- elseif command == "get-filename" then response, errormsg = get_var("title")
- elseif command == "get-file-length" then response, errormsg = get_var("length")
- elseif command == "get-filepath" then response, errormsg = get_filepath()
- elseif command == "get-vlc-version" then response = vlc.misc.version()
- elseif command == "get-version" then response = connectorversion
- elseif command == "play" then errormsg = playfile()
- elseif command == "pause" then errormsg = pausefile()
- elseif command == "playpause" then errormsg = playpausefile()
- elseif command == "seek" then errormsg = set_var("time", tonumber(argument))
- elseif command == "set-rate" then errormsg = set_var("rate", tonumber(argument))
- elseif command == "display-osd" then errormsg = display_osd(argument)
- else errormsg = unknowncommand
- end
-
- if (tostring(errormsg) == "" or errormsg == nil) then
- if (tostring(response) == "") then
- response = command..responsemarker..msgterminator
- else
- response = command..responsemarker..msgseperator..tostring(response)..msgterminator
- end
- else
- response = command..errormarker..msgseperator..tostring(errormsg)..msgterminator
- end
-
- vlc.msg.info("Response: '"..tostring(response).."'")
-
- return response
-
+ return response
+
end
-function playfile()
- local errormsg
- local input = vlc.object.input()
- local playstate
- playstate, errormsg = get_play_state()
-
- if playstate == "paused" then
- vlc.playlist.pause()
- end
-
- return errormsg
-end
-
-
-function pausefile()
- local errormsg
- local input = vlc.object.input()
- local playstate
- playstate, errormsg = get_play_state()
-
- if playstate == "playing" then
- vlc.playlist.pause()
- end
-
- return errormsg
-end
-
-function playpausefile()
- local errormsg
- local input = vlc.object.input()
-
- if input then
- vlc.playlist.pause()
- else
- errormsg = noinput
- end
-
- return errormsg
+function set_playstate(argument)
+ local errormsg
+ local input = vlc.object.input()
+ local playstate
+ playstate, errormsg = get_play_state()
+
+ if playstate ~= "playing" then playstate = "paused" end
+ if ((errormsg ~= noinput) and (playstate ~= argument)) then
+ vlc.playlist.pause()
+ end
+
+ return errormsg
end
-- main loop
while not vlc.misc.should_die() do
-- accept new connections and select active clients
- local write, read = h:accept_and_select()
+ 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
+ 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 str = client:recv(1000)
- local responsebuffer
- if not str then break end
-
- local safestr = string.gsub(tostring(str), "\r", "")
-
- if client.inputbuffer == nil then
- client.inputbuffer = ""
- end
-
- client.inputbuffer = client.inputbuffer .. safestr
-
- vlc.msg.info("Str: '" .. safestr.."'")
- vlc.msg.info("Input buffer: '" .. client.inputbuffer.."'")
-
- while string.find(client.inputbuffer, msgterminator) do
- local index = string.find(client.inputbuffer, msgterminator)
- local request = string.sub(client.inputbuffer, 0, index - 1)
- local command
- local argument
- client.inputbuffer = string.sub(client.inputbuffer, index + string.len(msgterminator))
+
+ for _, client in pairs(read) do
+ local str = client:recv(1000)
+ local responsebuffer
+ if not str then break end
+
+
+ local safestr = string.gsub(tostring(str), "\r", "")
+
+ if client.inputbuffer == nil then client.inputbuffer = "" end
+
+ client.inputbuffer = client.inputbuffer .. safestr
+
+ while string.find(client.inputbuffer, msgterminator) do
+ local index = string.find(client.inputbuffer, msgterminator)
+ local request = string.sub(client.inputbuffer, 0, index - 1)
+ local command
+ local argument
+ client.inputbuffer = string.sub(client.inputbuffer, index + string.len(msgterminator))
- if (string.find(request, msgseperator)) then
- index = string.find(request, msgseperator)
- command = string.sub(request, 0, index - 1)
- argument = string.sub(request, index + string.len(msgseperator))
-
- else
- command = request
- end
-
- if (responsebuffer) then
- responsebuffer = responsebuffer .. do_command(command,argument)
- else
- responsebuffer = do_command(command,argument)
- end
+ if (string.find(request, msgseperator)) then
+ index = string.find(request, msgseperator)
+ command = string.sub(request, 0, index - 1)
+ argument = string.sub(request, index + string.len(msgseperator))
+
+ else
+ command = request
+ end
+
+ if (responsebuffer) then
+ responsebuffer = responsebuffer .. do_command(command,argument)
+ else
+ responsebuffer = do_command(command,argument)
+ end
- end
-
- client.buffer = ""
- if (responsebuffer) then
- client:send(responsebuffer)
- end
- client.buffer = ""
+ end
+
+ client.buffer = ""
+ if (responsebuffer) then
+ client:send(responsebuffer)
+ end
+ client.buffer = ""
client:switch_status( host.status.write )
end
-
+
end
-