update reload and add config file
This commit is contained in:
parent
a9b562f8e8
commit
0acea11d35
34
script-opts/reload.conf
Normal file
34
script-opts/reload.conf
Normal file
@ -0,0 +1,34 @@
|
||||
# enable automatic reload on timeout
|
||||
# when paused-for-cache event fired, we will wait
|
||||
# paused_for_cache_timer_timeout sedonds and then reload the video
|
||||
paused_for_cache_timer_enabled=yes
|
||||
|
||||
# checking paused_for_cache property interval in seconds,
|
||||
# can not be less than 0.05 (50 ms)
|
||||
paused_for_cache_timer_interval=1
|
||||
|
||||
# time in seconds to wait until reload
|
||||
paused_for_cache_timer_timeout=10
|
||||
|
||||
# enable automatic reload based on demuxer cache
|
||||
# if demuxer-cache-time property didn't change in demuxer_cache_timer_timeout
|
||||
# time interval, the video will be reloaded as soon as demuxer cache depleated
|
||||
demuxer_cache_timer_enabled=yes
|
||||
|
||||
# checking demuxer-cache-time property interval in seconds,
|
||||
# can not be less than 0.05 (50 ms)
|
||||
demuxer_cache_timer_interval=2
|
||||
|
||||
# if demuxer cache didn't receive any data during demuxer_cache_timer_timeout
|
||||
# we decide that it has no progress and will reload the stream when
|
||||
# paused_for_cache event happens
|
||||
demuxer_cache_timer_timeout=20
|
||||
|
||||
# when the end-of-file is reached, reload the stream to check
|
||||
# if there is more content available.
|
||||
reload_eof_enabled=no
|
||||
|
||||
# keybinding to reload stream from current time position
|
||||
# you can disable keybinding by setting it to empty value
|
||||
# reload_key_binding=
|
||||
reload_key_binding=Ctrl+r
|
@ -57,12 +57,10 @@
|
||||
-- `--msg-level='reload=debug'`. You may also need to add the `--no-msg-color`
|
||||
-- option to make the debug logs visible if you are using a dark colorscheme
|
||||
-- in terminal.
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
local options = require 'mp.options'
|
||||
local utils = require 'mp.utils'
|
||||
|
||||
|
||||
local settings = {
|
||||
paused_for_cache_timer_enabled = true,
|
||||
paused_for_cache_timer_interval = 1,
|
||||
@ -71,7 +69,7 @@ local settings = {
|
||||
demuxer_cache_timer_interval = 2,
|
||||
demuxer_cache_timer_timeout = 20,
|
||||
reload_eof_enabled = false,
|
||||
reload_key_binding = "Ctrl+r",
|
||||
reload_key_binding = "Ctrl+r"
|
||||
}
|
||||
|
||||
-- global state stores properties between reloads
|
||||
@ -99,11 +97,7 @@ local property_keep_open = nil
|
||||
local demuxer_cache = {
|
||||
timer = nil,
|
||||
|
||||
state = {
|
||||
name = 'uninitialized',
|
||||
demuxer_cache_time = 0,
|
||||
in_state_time = 0,
|
||||
},
|
||||
state = { name = 'uninitialized', demuxer_cache_time = 0, in_state_time = 0 },
|
||||
|
||||
events = {
|
||||
continue_fetch = { name = 'continue_fetch', from = 'fetch', to = 'fetch' },
|
||||
@ -112,8 +106,8 @@ local demuxer_cache = {
|
||||
fetch_to_stale = { name = 'fetch_to_stale', from = 'fetch', to = 'stale' },
|
||||
stale_to_fetch = { name = 'stale_to_fetch', from = 'stale', to = 'fetch' },
|
||||
stale_to_stuck = { name = 'stale_to_stuck', from = 'stale', to = 'stuck' },
|
||||
stuck_to_fetch = { name = 'stuck_to_fetch', from = 'stuck', to = 'fetch' },
|
||||
},
|
||||
stuck_to_fetch = { name = 'stuck_to_fetch', from = 'stuck', to = 'fetch' }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -122,7 +116,7 @@ function demuxer_cache.reset_state()
|
||||
demuxer_cache.state = {
|
||||
name = demuxer_cache.events.continue_fetch.to,
|
||||
demuxer_cache_time = 0,
|
||||
in_state_time = 0,
|
||||
in_state_time = 0
|
||||
}
|
||||
end
|
||||
|
||||
@ -145,16 +139,21 @@ end
|
||||
|
||||
function demuxer_cache.transition(event)
|
||||
if demuxer_cache.state.name == event.from then
|
||||
|
||||
-- state setup
|
||||
demuxer_cache.state.demuxer_cache_time = event.demuxer_cache_time
|
||||
|
||||
if event.name == 'continue_fetch' then
|
||||
demuxer_cache.state.in_state_time = demuxer_cache.state.in_state_time + event.interval
|
||||
demuxer_cache.state.in_state_time = demuxer_cache.state
|
||||
.in_state_time +
|
||||
event.interval
|
||||
elseif event.name == 'continue_stale' then
|
||||
demuxer_cache.state.in_state_time = demuxer_cache.state.in_state_time + event.interval
|
||||
demuxer_cache.state.in_state_time = demuxer_cache.state
|
||||
.in_state_time +
|
||||
event.interval
|
||||
elseif event.name == 'continue_stuck' then
|
||||
demuxer_cache.state.in_state_time = demuxer_cache.state.in_state_time + event.interval
|
||||
demuxer_cache.state.in_state_time = demuxer_cache.state
|
||||
.in_state_time +
|
||||
event.interval
|
||||
elseif event.name == 'fetch_to_stale' then
|
||||
demuxer_cache.state.in_state_time = 0
|
||||
elseif event.name == 'stale_to_fetch' then
|
||||
@ -168,33 +167,32 @@ function demuxer_cache.transition(event)
|
||||
-- state transition
|
||||
demuxer_cache.state.name = event.to
|
||||
|
||||
msg.debug('demuxer_cache.transition', event.name, utils.to_string(demuxer_cache.state))
|
||||
msg.debug('demuxer_cache.transition', event.name,
|
||||
utils.to_string(demuxer_cache.state))
|
||||
else
|
||||
msg.error(
|
||||
'demuxer_cache.transition',
|
||||
'illegal transition', event.name,
|
||||
msg.error('demuxer_cache.transition', 'illegal transition', event.name,
|
||||
'from state', demuxer_cache.state.name)
|
||||
end
|
||||
end
|
||||
|
||||
function demuxer_cache.initialize(demuxer_cache_timer_interval)
|
||||
demuxer_cache.reset_state()
|
||||
demuxer_cache.timer = mp.add_periodic_timer(
|
||||
demuxer_cache_timer_interval,
|
||||
demuxer_cache.timer = mp.add_periodic_timer(demuxer_cache_timer_interval,
|
||||
function()
|
||||
demuxer_cache.demuxer_cache_timer_tick(
|
||||
mp.get_property_native('demuxer-cache-time'),
|
||||
demuxer_cache_timer_interval)
|
||||
end
|
||||
)
|
||||
end)
|
||||
end
|
||||
|
||||
-- If there is no progress of demuxer_cache_time in
|
||||
-- settings.demuxer_cache_timer_timeout time interval switch state to
|
||||
-- 'stuck' and switch back to 'fetch' as soon as any progress is made
|
||||
function demuxer_cache.demuxer_cache_timer_tick(demuxer_cache_time, demuxer_cache_timer_interval)
|
||||
function demuxer_cache.demuxer_cache_timer_tick(demuxer_cache_time,
|
||||
demuxer_cache_timer_interval)
|
||||
local event = nil
|
||||
local cache_has_progress = demuxer_cache.has_progress_since(demuxer_cache_time)
|
||||
local cache_has_progress = demuxer_cache.has_progress_since(
|
||||
demuxer_cache_time)
|
||||
|
||||
-- I miss pattern matching so much
|
||||
if demuxer_cache.is_state_fetch() then
|
||||
@ -206,7 +204,8 @@ function demuxer_cache.demuxer_cache_timer_tick(demuxer_cache_time, demuxer_cach
|
||||
elseif demuxer_cache.is_state_stale() then
|
||||
if cache_has_progress then
|
||||
event = demuxer_cache.events.stale_to_fetch
|
||||
elseif demuxer_cache.state.in_state_time < settings.demuxer_cache_timer_timeout then
|
||||
elseif demuxer_cache.state.in_state_time <
|
||||
settings.demuxer_cache_timer_timeout then
|
||||
event = demuxer_cache.events.continue_stale
|
||||
else
|
||||
event = demuxer_cache.events.stale_to_stuck
|
||||
@ -224,11 +223,7 @@ function demuxer_cache.demuxer_cache_timer_tick(demuxer_cache_time, demuxer_cach
|
||||
demuxer_cache.transition(event)
|
||||
end
|
||||
|
||||
|
||||
local paused_for_cache = {
|
||||
timer = nil,
|
||||
time = 0,
|
||||
}
|
||||
local paused_for_cache = { timer = nil, time = 0 }
|
||||
|
||||
function paused_for_cache.reset_timer()
|
||||
msg.debug('paused_for_cache.reset_timer', paused_for_cache.time)
|
||||
@ -242,8 +237,7 @@ end
|
||||
function paused_for_cache.start_timer(interval_seconds, timeout_seconds)
|
||||
msg.debug('paused_for_cache.start_timer', paused_for_cache.time)
|
||||
if not paused_for_cache.timer then
|
||||
paused_for_cache.timer = mp.add_periodic_timer(
|
||||
interval_seconds,
|
||||
paused_for_cache.timer = mp.add_periodic_timer(interval_seconds,
|
||||
function()
|
||||
paused_for_cache.time = paused_for_cache.time + interval_seconds
|
||||
if paused_for_cache.time >= timeout_seconds then
|
||||
@ -251,14 +245,12 @@ function paused_for_cache.start_timer(interval_seconds, timeout_seconds)
|
||||
reload_resume()
|
||||
end
|
||||
msg.debug('paused_for_cache', 'tick', paused_for_cache.time)
|
||||
end
|
||||
)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function paused_for_cache.handler(property, is_paused)
|
||||
if is_paused then
|
||||
|
||||
if demuxer_cache.is_state_stuck() then
|
||||
msg.info("demuxer cache has no progress")
|
||||
-- reset demuxer state to avoid immediate reload if
|
||||
@ -267,8 +259,7 @@ function paused_for_cache.handler(property, is_paused)
|
||||
reload_resume()
|
||||
end
|
||||
|
||||
paused_for_cache.start_timer(
|
||||
settings.paused_for_cache_timer_interval,
|
||||
paused_for_cache.start_timer(settings.paused_for_cache_timer_interval,
|
||||
settings.paused_for_cache_timer_timeout)
|
||||
else
|
||||
paused_for_cache.reset_timer()
|
||||
@ -285,8 +276,15 @@ function reload(path, time_pos)
|
||||
if time_pos == nil then
|
||||
mp.commandv("loadfile", path, "replace")
|
||||
else
|
||||
local success = mp.commandv("loadfile", path, "replace", -1,
|
||||
"start=+" .. time_pos)
|
||||
-- fallback to old syntax of loadfile for compatibility
|
||||
if success == nil then
|
||||
msg.warn(
|
||||
"old loadfile syntax detected. falling back to using old syntax. update mpv to remove this warning")
|
||||
mp.commandv("loadfile", path, "replace", "start=+" .. time_pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function reload_resume()
|
||||
@ -297,7 +295,7 @@ function reload_resume()
|
||||
local playlist_count = mp.get_property_number("playlist/count")
|
||||
local playlist_pos = mp.get_property_number("playlist-pos")
|
||||
local playlist = {}
|
||||
for i = 0, playlist_count-1 do
|
||||
for i = 0, playlist_count - 1 do
|
||||
playlist[i] = mp.get_property("playlist/" .. i .. "/filename")
|
||||
end
|
||||
-- Tries to determine live stream vs. pre-recordered VOD. VOD has non-zero
|
||||
@ -319,12 +317,12 @@ function reload_resume()
|
||||
msg.info("reloading stream")
|
||||
reload(path, nil)
|
||||
end
|
||||
msg.info("file ", playlist_pos+1, "of", playlist_count, "in playlist")
|
||||
for i = 0, playlist_pos-1 do
|
||||
msg.info("file", playlist_pos + 1, "of", playlist_count, "in playlist")
|
||||
for i = 0, playlist_pos - 1 do
|
||||
mp.commandv("loadfile", playlist[i], "append")
|
||||
end
|
||||
mp.commandv("playlist-move", 0, playlist_pos+1)
|
||||
for i = playlist_pos+1, playlist_count-1 do
|
||||
mp.commandv("playlist-move", 0, playlist_pos + 1)
|
||||
for i = playlist_pos + 1, playlist_count - 1 do
|
||||
mp.commandv("loadfile", playlist[i], "append")
|
||||
end
|
||||
end
|
||||
@ -334,15 +332,14 @@ function reload_eof(property, eof_reached)
|
||||
local time_pos = mp.get_property_number("time-pos")
|
||||
local duration = mp.get_property_number("duration")
|
||||
|
||||
if eof_reached and math.floor(time_pos) == math.floor(duration) then
|
||||
if eof_reached and round(time_pos) == round(duration) then
|
||||
msg.debug("property_time_pos", property_time_pos, "time_pos", time_pos)
|
||||
|
||||
-- Check that playback time_pos made progress after the last reload. When
|
||||
-- eof is reached we try to reload video, in case there is more content
|
||||
-- available. If time_pos stayed the same after reload, it means that vidkk
|
||||
-- to avoid infinite reload loop when playback ended
|
||||
-- math.floor function rounds time_pos to a second, to avoid inane reloads
|
||||
if math.floor(property_time_pos) == math.floor(time_pos) then
|
||||
-- eof is reached we try to reload the video, in case there is more content
|
||||
-- available. If time_pos stayed the same after reload, it means that the
|
||||
-- video length stayed the same, and we can end the playback.
|
||||
if round(property_time_pos) == round(time_pos) then
|
||||
msg.info("eof reached, playback ended")
|
||||
mp.set_property("keep-open", property_keep_open)
|
||||
else
|
||||
@ -364,7 +361,7 @@ function on_file_loaded(event)
|
||||
seekable = mp.get_property("seekable"),
|
||||
pause = mp.get_property("pause"),
|
||||
paused_for_cache = mp.get_property("paused-for-cache"),
|
||||
cache_buffering_state = mp.get_property("cache-buffering-state"),
|
||||
cache_buffering_state = mp.get_property("cache-buffering-state")
|
||||
}
|
||||
msg.debug("debug_info", utils.to_string(debug_info))
|
||||
|
||||
@ -380,12 +377,16 @@ function on_file_loaded(event)
|
||||
mp.commandv("keypress", 'SPACE')
|
||||
end
|
||||
|
||||
-- Round positive numbers.
|
||||
function round(num) return math.floor(num + 0.5) end
|
||||
|
||||
-- main
|
||||
|
||||
read_settings()
|
||||
|
||||
if settings.reload_key_binding ~= "" then
|
||||
mp.add_key_binding(settings.reload_key_binding, "reload_resume", reload_resume)
|
||||
mp.add_key_binding(settings.reload_key_binding, "reload_resume",
|
||||
reload_resume)
|
||||
end
|
||||
|
||||
if settings.paused_for_cache_timer_enabled then
|
||||
@ -398,10 +399,7 @@ end
|
||||
|
||||
if settings.reload_eof_enabled then
|
||||
-- vo-configured == video output created && its configuration went ok
|
||||
mp.observe_property(
|
||||
"vo-configured",
|
||||
"bool",
|
||||
function(name, vo_configured)
|
||||
mp.observe_property("vo-configured", "bool", function(name, vo_configured)
|
||||
msg.debug(name, vo_configured)
|
||||
if vo_configured then
|
||||
property_path = mp.get_property("path")
|
||||
@ -409,10 +407,10 @@ if settings.reload_eof_enabled then
|
||||
mp.set_property("keep-open", "yes")
|
||||
mp.set_property("keep-open-pause", "no")
|
||||
end
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
mp.observe_property("eof-reached", "bool", reload_eof)
|
||||
end
|
||||
|
||||
mp.register_event("file-loaded", on_file_loaded)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user