MPV: Lua socket (non-blocking)

Step-by-Step descriptions of how to do things.
Post Reply
User avatar
^rooker
Site Admin
Posts: 1481
Joined: Fri Aug 29, 2003 8:39 pm

MPV: Lua socket (non-blocking)

Post by ^rooker »

Here's a rough example for a non-blocking IP (TCP) port listening for incoming connections, without blocking the video playback:
(OS is Xubuntu 20.04, MPV v0.32.0)

Code: Select all

-- Import LuaSocket library
local socket = require("socket")
print("Socket.")

-- Create a TCP socket and bind it to the localhost, on port 12345
local server = assert(socket.bind("127.0.0.1", 12345))
server:settimeout(2);

print("Server.")

function wait_socket()
    print("listening...!")

    -- Start listening for connections
    local client = server:accept()

    if client == nil then
        print("nix")
    else
        -- Handle the client connection
        client:send("Hello from MPV!\n")
        client:close()
    end
end

mp.add_periodic_timer(1, wait_socket)
Known issues:
- Timer continues when trying to quit/exit MPV. Must be killed by Ctrl+C.
Jumping out of an airplane is not a basic instinct. Neither is breathing underwater. But put the two together and you're traveling through space!
User avatar
peter_b
Chatterbox
Posts: 371
Joined: Tue Nov 12, 2013 2:05 am

Re: MPV: Lua socket (non-blocking)

Post by peter_b »

Based on the above example snippet, here's a LUA script for MPV that opens a port and listens for "key=value" commands.
In this example, it takes a "seek=frames" argument to jump to a position in the clip, using the "container-fps" to deduce the position in seconds:

Code: Select all

-- Import LuaSocket library
local socket = require("socket")

-- Create a TCP socket and bind it to the localhost, on port 12345
local server = assert(socket.bind("*", 12345))
server:settimeout(0.5);
local client

function wait_socket()
    -- print("listening")

    -- Start listening for connections
    client = server:accept()
    local msg

    if client == nil then
        -- print("nix")
    else
        -- Handle the client connection
        client:send("Hello from MPV!\n")
        msg = client:receive('*l')
        client:close()
    end

    handle_msg(msg)
end


function handle_msg(msg)
    if msg == nil then
        -- empty message, nothing to do.
        return
    end

   print("handling: " .. msg)

   -- Iterate through key=value commands, and convert them 
   -- to a table in one go:
   t = {}
   for k, v in string.gmatch(msg, "(%w+)=(%w+)") do
       t[k] = v
       print("key: " .. k .. " / value: " .. v)

       if k == 'seek' then
          local fps = mp.get_property_native("container-fps")
          local pos = t['seek'] / fps;
          print("seek: " .. pos)
          mp.commandv("seek", pos, "absolute", "exact")
       end
   end
end


function cleanup(event)
    print("Goodbye!")

    -- Shutdown sockets:
    if client ~= nil then
        client:close()
    end

    if server ~= nil then
        server:close()
    end
end

-- =================================================

mp.add_periodic_timer(0.5, wait_socket)
mp.register_event("shutdown", cleanup)
Post Reply