2018-05-10 13:26:56 +00:00
|
|
|
-- Test script for some command API details.
|
|
|
|
|
|
|
|
local utils = require("mp.utils")
|
|
|
|
|
|
|
|
function join(sep, arr, count)
|
|
|
|
local r = ""
|
|
|
|
if count == nil then
|
|
|
|
count = #arr
|
|
|
|
end
|
|
|
|
for i = 1, count do
|
|
|
|
if i > 1 then
|
|
|
|
r = r .. sep
|
|
|
|
end
|
|
|
|
r = r .. utils.to_string(arr[i])
|
|
|
|
end
|
|
|
|
return r
|
|
|
|
end
|
|
|
|
|
|
|
|
mp.observe_property("vo-configured", "bool", function(_, v)
|
|
|
|
if v ~= true then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
print("async expand-text")
|
|
|
|
mp.command_native_async({"expand-text", "hello ${path}!"},
|
|
|
|
function(res, val, err)
|
|
|
|
print("done async expand-text: " .. join(" ", {res, val, err}))
|
|
|
|
end)
|
|
|
|
|
|
|
|
-- make screenshot writing very slow
|
|
|
|
mp.set_property("screenshot-format", "png")
|
|
|
|
mp.set_property("screenshot-png-compression", "9")
|
|
|
|
|
|
|
|
timer = mp.add_periodic_timer(0.1, function() print("I'm alive") end)
|
|
|
|
timer:resume()
|
|
|
|
|
|
|
|
print("Slow screenshot command...")
|
2024-05-12 00:10:09 +00:00
|
|
|
res = mp.command_native({"screenshot"})
|
2018-05-10 13:26:56 +00:00
|
|
|
print("done, res: " .. utils.to_string(res))
|
|
|
|
|
|
|
|
print("Slow screenshot async command...")
|
2024-05-12 00:10:09 +00:00
|
|
|
res = mp.command_native_async({"screenshot"}, function(res)
|
2018-05-10 13:26:56 +00:00
|
|
|
print("done (async), res: " .. utils.to_string(res))
|
|
|
|
timer:kill()
|
|
|
|
end)
|
|
|
|
print("done (sending), res: " .. utils.to_string(res))
|
|
|
|
|
|
|
|
print("Broken screenshot async command...")
|
|
|
|
mp.command_native_async({"screenshot-to-file", "/nonexistent/bogus.png"},
|
|
|
|
function(res, val, err)
|
|
|
|
print("done err scr.: " .. join(" ", {res, val, err}))
|
|
|
|
end)
|
2018-05-12 13:14:07 +00:00
|
|
|
|
|
|
|
mp.command_native_async({name = "subprocess", args = {"sh", "-c", "echo hi && sleep 10s"}, capture_stdout = true},
|
|
|
|
function(res, val, err)
|
|
|
|
print("done subprocess: " .. join(" ", {res, val, err}))
|
|
|
|
end)
|
2018-05-12 16:48:35 +00:00
|
|
|
|
|
|
|
local x = mp.command_native_async({name = "subprocess", args = {"sleep", "inf"}},
|
|
|
|
function(res, val, err)
|
|
|
|
print("done sleep inf subprocess: " .. join(" ", {res, val, err}))
|
|
|
|
end)
|
|
|
|
mp.add_timeout(15, function()
|
|
|
|
print("aborting sleep inf subprocess after timeout")
|
|
|
|
mp.abort_async_command(x)
|
|
|
|
end)
|
2018-05-13 11:48:47 +00:00
|
|
|
|
player: make various commands for managing external tracks abortable
Until now, they could be aborted only by ending playback, and calling
mpv_abort_async_command didn't do anything.
This requires furthering the mess how playback abort is done. The main
reason why mp_cancel exists at all is to avoid that a "frozen" demuxer
(blocked on network I/O or whatever) cannot freeze the core. The core
should always get its way. Previously, there was a single mp_cancel
handle, that could be signaled, and all demuxers would unfreeze. With
external files, we might want to abort loading of a certain external
file, which automatically means they need a separate mp_cancel. So give
every demuxer its own mp_cancel, and "slave" it to whatever parent
mp_cancel handles aborting.
Since the mpv demuxer API conflates creating the demuxer and reading the
file headers, mp_cancel strictly need to be created before the demuxer
is created (or we couldn't abort loading). Although we give every
demuxer its own mp_cancel (as "enforced" by cancel_and_free_demuxer),
it's still rather messy to create/destroy it along with the demuxer.
2018-05-18 19:38:17 +00:00
|
|
|
-- (assuming this "freezes")
|
|
|
|
local y = mp.command_native_async({name = "sub-add", url = "-"},
|
|
|
|
function(res, val, err)
|
|
|
|
print("done sub-add stdin: " .. join(" ", {res, val, err}))
|
|
|
|
end)
|
|
|
|
mp.add_timeout(20, function()
|
|
|
|
print("aborting sub-add stdin after timeout")
|
|
|
|
mp.abort_async_command(y)
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
2020-08-16 00:54:44 +00:00
|
|
|
mp.command_native_async({name = "subprocess", args = {"wc", "-c"},
|
|
|
|
stdin_data = "hello", capture_stdout = true},
|
2024-05-12 00:10:09 +00:00
|
|
|
function(_, val)
|
2020-08-16 00:54:44 +00:00
|
|
|
print("Should be '5': " .. val.stdout)
|
|
|
|
end)
|
|
|
|
-- blocking stdin by default
|
|
|
|
mp.command_native_async({name = "subprocess", args = {"cat"},
|
|
|
|
capture_stdout = true},
|
2024-05-12 00:10:09 +00:00
|
|
|
function(_, val)
|
2020-08-16 00:54:44 +00:00
|
|
|
print("Should be 0: " .. #val.stdout)
|
|
|
|
end)
|
|
|
|
-- stdin + detached
|
|
|
|
mp.command_native_async({name = "subprocess",
|
|
|
|
args = {"bash", "-c", "(sleep 5s ; cat)"},
|
|
|
|
stdin_data = "this should appear after 5s.\n",
|
|
|
|
detach = true},
|
2024-05-12 00:10:09 +00:00
|
|
|
function(_, val)
|
2020-08-16 00:54:44 +00:00
|
|
|
print("5s test: " .. val.status)
|
|
|
|
end)
|
player: make various commands for managing external tracks abortable
Until now, they could be aborted only by ending playback, and calling
mpv_abort_async_command didn't do anything.
This requires furthering the mess how playback abort is done. The main
reason why mp_cancel exists at all is to avoid that a "frozen" demuxer
(blocked on network I/O or whatever) cannot freeze the core. The core
should always get its way. Previously, there was a single mp_cancel
handle, that could be signaled, and all demuxers would unfreeze. With
external files, we might want to abort loading of a certain external
file, which automatically means they need a separate mp_cancel. So give
every demuxer its own mp_cancel, and "slave" it to whatever parent
mp_cancel handles aborting.
Since the mpv demuxer API conflates creating the demuxer and reading the
file headers, mp_cancel strictly need to be created before the demuxer
is created (or we couldn't abort loading). Although we give every
demuxer its own mp_cancel (as "enforced" by cancel_and_free_demuxer),
it's still rather messy to create/destroy it along with the demuxer.
2018-05-18 19:38:17 +00:00
|
|
|
|
2018-05-13 11:48:47 +00:00
|
|
|
-- This should get killed on script exit.
|
|
|
|
mp.command_native_async({name = "subprocess", playback_only = false,
|
|
|
|
args = {"sleep", "inf"}}, function()end)
|
|
|
|
|
|
|
|
-- Runs detached; should be killed on player exit (forces timeout)
|
|
|
|
mp.command_native({_flags={"async"}, name = "subprocess",
|
|
|
|
playback_only = false, args = {"sleep", "inf"}})
|
|
|
|
end)
|
|
|
|
|
2019-10-04 14:30:48 +00:00
|
|
|
function freeze_test(playback_only)
|
2018-05-13 11:48:47 +00:00
|
|
|
-- This "freezes" the script, should be killed via timeout.
|
2019-10-04 14:30:48 +00:00
|
|
|
counter = counter and counter + 1 or 0
|
|
|
|
print("freeze! " .. counter)
|
|
|
|
local x = mp.command_native({name = "subprocess",
|
|
|
|
playback_only = playback_only,
|
2018-05-13 11:48:47 +00:00
|
|
|
args = {"sleep", "inf"}})
|
|
|
|
print("done, killed=" .. utils.to_string(x.killed_by_us))
|
2019-10-04 14:30:48 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
mp.register_event("shutdown", function()
|
|
|
|
freeze_test(false)
|
|
|
|
end)
|
|
|
|
|
|
|
|
mp.register_event("idle", function()
|
|
|
|
freeze_test(true)
|
2018-05-10 13:26:56 +00:00
|
|
|
end)
|