summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorMartin Herkt <lachs0r@srsfckn.biz>2016-11-20 18:15:08 +0100
committerMartin Herkt <lachs0r@srsfckn.biz>2016-11-20 18:15:08 +0100
commit8700700de8a4103724796077034f7f254ad974bc (patch)
tree2fce4dee518a202c45c3f16567db36edc92ed914 /player
parente6b85c91700bee0ddc92e98a30d5021691bd6f65 (diff)
parenteafc273d2c2ae6d247d741202e58ca23dc938cb2 (diff)
downloadmpv-8700700de8a4103724796077034f7f254ad974bc.tar.bz2
mpv-8700700de8a4103724796077034f7f254ad974bc.tar.xz
Merge branch 'master' into release/current
Diffstat (limited to 'player')
-rw-r--r--player/audio.c4
-rw-r--r--player/command.c39
-rw-r--r--player/loadfile.c3
-rw-r--r--player/lua/osc.lua276
-rw-r--r--player/lua/ytdl_hook.lua2
-rw-r--r--player/playloop.c10
-rw-r--r--player/sub.c13
-rw-r--r--player/video.c6
8 files changed, 230 insertions, 123 deletions
diff --git a/player/audio.c b/player/audio.c
index 3f173f140d..5c393f3d3a 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -840,8 +840,8 @@ static int filter_audio(struct MPContext *mpctx, struct mp_audio_buffer *outbuf,
// Attempt to detect jumps in PTS. Even for the lowest sample rates
// and with worst container rounded timestamp, this should be a
// margin more than enough.
- double desync = fabs(mpa->pts - ao_c->pts);
- if (ao_c->pts != MP_NOPTS_VALUE && desync > 0.1) {
+ double desync = mpa->pts - ao_c->pts;
+ if (ao_c->pts != MP_NOPTS_VALUE && fabs(desync) > 0.1) {
MP_WARN(ao_c, "Invalid audio PTS: %f -> %f\n",
ao_c->pts, mpa->pts);
if (desync >= 5)
diff --git a/player/command.c b/player/command.c
index 1fa4695a91..7c1a6f3a6e 100644
--- a/player/command.c
+++ b/player/command.c
@@ -104,6 +104,8 @@ struct command_ctx {
char *cur_ipc;
char *cur_ipc_input;
+
+ int silence_option_deprecations;
};
struct overlay {
@@ -287,10 +289,11 @@ int mp_on_set_option(void *ctx, struct m_config_option *co, void *data, int flag
// OK, is handled separately: playlist
// OK, does not conflict on low level: audio-file, sub-file, external-file
// OK, different value ranges, but happens to work for now: volume, edition
+ // Incompatible: tv-freq
// All the other properties are deprecated in their current form.
static const char *const no_property[] = {
"demuxer", "idle", "length", "audio-samplerate", "audio-channels",
- "audio-format", "fps", "cache", "playlist-pos", "chapter",
+ "audio-format", "fps", "cache", "playlist-pos", "chapter", "tv-freq",
NULL
};
@@ -341,8 +344,13 @@ static int mp_property_generic_option(void *ctx, struct m_property *prop,
MPContext *mpctx = ctx;
const char *optname = prop->name;
int flags = M_SETOPT_RUNTIME;
- struct m_config_option *opt = m_config_get_co(mpctx->mconfig,
- bstr0(optname));
+ struct m_config_option *opt;
+ if (mpctx->command_ctx->silence_option_deprecations) {
+ // This case is specifically for making --reset-on-next-file=all silent.
+ opt = m_config_get_co_raw(mpctx->mconfig, bstr0(optname));
+ } else {
+ opt = m_config_get_co(mpctx->mconfig, bstr0(optname));
+ }
if (!opt)
return M_PROPERTY_UNKNOWN;
@@ -2739,40 +2747,35 @@ static int mp_property_window_scale(void *ctx, struct m_property *prop,
MPContext *mpctx = ctx;
struct vo *vo = mpctx->video_out;
if (!vo)
- return mp_property_generic_option(mpctx, prop, action, arg);
+ goto generic;
struct mp_image_params params = get_video_out_params(mpctx);
int vid_w, vid_h;
mp_image_params_get_dsize(&params, &vid_w, &vid_h);
if (vid_w < 1 || vid_h < 1)
- return M_PROPERTY_UNAVAILABLE;
+ goto generic;
switch (action) {
case M_PROPERTY_SET: {
double scale = *(double *)arg;
int s[2] = {vid_w * scale, vid_h * scale};
- if (s[0] > 0 && s[1] > 0 &&
- vo_control(vo, VOCTRL_SET_UNFS_WINDOW_SIZE, s) > 0)
- {
- mpctx->opts->vo->window_scale = scale;
- return M_PROPERTY_OK;
- }
- return M_PROPERTY_UNAVAILABLE;
+ if (s[0] > 0 && s[1] > 0)
+ vo_control(vo, VOCTRL_SET_UNFS_WINDOW_SIZE, s);
+ goto generic;
}
case M_PROPERTY_GET: {
int s[2];
if (vo_control(vo, VOCTRL_GET_UNFS_WINDOW_SIZE, s) <= 0 ||
s[0] < 1 || s[1] < 1)
- return M_PROPERTY_UNAVAILABLE;
+ goto generic;
double xs = (double)s[0] / vid_w;
double ys = (double)s[1] / vid_h;
*(double *)arg = (xs + ys) / 2;
return M_PROPERTY_OK;
}
- case M_PROPERTY_GET_TYPE:
- return mp_property_generic_option(mpctx, prop, action, arg);
}
- return M_PROPERTY_NOT_IMPLEMENTED;
+generic:
+ return mp_property_generic_option(mpctx, prop, action, arg);
}
static int mp_property_win_minimized(void *ctx, struct m_property *prop,
@@ -4153,7 +4156,9 @@ static int mp_property_do_silent(const char *name, int action, void *val,
struct MPContext *ctx)
{
struct command_ctx *cmd = ctx->command_ctx;
+ cmd->silence_option_deprecations += 1;
int r = m_property_do(ctx->log, cmd->properties, name, action, val, ctx);
+ cmd->silence_option_deprecations -= 1;
if (r == M_PROPERTY_OK && is_property_set(action, val))
mp_notify_property(ctx, (char *)name);
return r;
@@ -5152,7 +5157,7 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
return -1;
// Can't play a removed entry
if (mpctx->playlist->current == e && !mpctx->stop_play)
- mpctx->stop_play = PT_CURRENT_ENTRY;
+ mpctx->stop_play = PT_NEXT_ENTRY;
playlist_remove(mpctx->playlist, e);
mp_notify(mpctx, MP_EVENT_CHANGE_PLAYLIST, NULL);
mp_wakeup_core(mpctx);
diff --git a/player/loadfile.c b/player/loadfile.c
index ec8ddd6004..6ea4479d7a 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -1139,6 +1139,9 @@ reopen_file:
startpos = start;
}
if (startpos != MP_NOPTS_VALUE) {
+ if (!opts->rebase_start_time) {
+ startpos += mpctx->demuxer->start_time;
+ }
queue_seek(mpctx, MPSEEK_ABSOLUTE, startpos, MPSEEK_DEFAULT, 0);
execute_queued_seek(mpctx);
}
diff --git a/player/lua/osc.lua b/player/lua/osc.lua
index ff7d9120ed..643f32faaf 100644
--- a/player/lua/osc.lua
+++ b/player/lua/osc.lua
@@ -12,8 +12,8 @@ local utils = require 'mp.utils'
local user_opts = {
showwindowed = true, -- show OSC when windowed?
showfullscreen = true, -- show OSC when fullscreen?
- scalewindowed = 1.5, -- scaling of the controller when windowed
- scalefullscreen = 1.5, -- scaling of the controller when fullscreen
+ scalewindowed = 1, -- scaling of the controller when windowed
+ scalefullscreen = 1, -- scaling of the controller when fullscreen
scaleforcedwindow = 2, -- scaling when rendered on a forced window
vidscale = true, -- scale the controller with the video?
valign = 0.8, -- vertical alignment, -1 (top) to 1 (bottom)
@@ -25,14 +25,15 @@ local user_opts = {
-- mouse movement. enforced non-negative for the
-- user, but internally negative is "always-on".
fadeduration = 200, -- duration of fade out in ms, 0 = no fade
- deadzonesize = 1, -- size of deadzone
+ deadzonesize = 0.5, -- size of deadzone
minmousemove = 0, -- minimum amount of pixels the mouse has to
-- move between ticks to make the OSC show up
iamaprogrammer = false, -- use native mpv values and disable OSC
-- internal track list management (and some
-- functions that depend on it)
layout = "bottombar",
- seekbarstyle = "bar", -- slider (diamond marker) or bar (fill)
+ seekbarstyle = "bar", -- slider (diamond marker), knob (circle
+ -- marker with guide), or bar (fill)
tooltipborder = 1, -- border of tooltip in bottom/topbar
timetotal = false, -- display total time instead of remaining time?
timems = false, -- display timecodes with milliseconds?
@@ -59,15 +60,20 @@ local osc_param = { -- calculated by osc_init()
local osc_styles = {
bigButtons = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs50\\fnmpv-osd-symbols}",
smallButtonsL = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs19\\fnmpv-osd-symbols}",
- smallButtonsLlabel = "{\\fs20\\fn" .. mp.get_property("options/osd-font") .. "}",
+ smallButtonsLlabel = "{\\fscx105\\fscy105\\fn" .. mp.get_property("options/osd-font") .. "}",
smallButtonsR = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs30\\fnmpv-osd-symbols}",
topButtons = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs12\\fnmpv-osd-symbols}",
elementDown = "{\\1c&H999999}",
timecodes = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs20}",
- vidtitle = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs12}",
- timePos = "{\\blur0\\bord".. user_opts.tooltipborder .."\\1c&HFFFFFF\\3c&H000000\\1a&H00\\3a&H88\\fs20}",
+ vidtitle = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs12\\q2}",
box = "{\\rDefault\\blur0\\bord1\\1c&H000000\\3c&HFFFFFF}",
+
+ topButtonsBar = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs18\\fnmpv-osd-symbols}",
+ smallButtonsBar = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs28\\fnmpv-osd-symbols}",
+ timecodesBar = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs27}",
+ timePosBar = "{\\blur0\\bord".. user_opts.tooltipborder .."\\1c&HFFFFFF\\3c&H000000\\fs30}",
+ vidtitleBar = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs18\\q2}",
}
-- internal states, do not touch
@@ -395,7 +401,8 @@ function prepare_elements()
local foV = slider_lo.border + slider_lo.gap
-- calculate positions of min and max points
- if (slider_lo.stype == "slider") then
+ if (slider_lo.stype == "slider") or
+ (slider_lo.stype == "knob") then
element.slider.min.ele_pos = elem_geo.h / 2
element.slider.max.ele_pos = elem_geo.w - (elem_geo.h / 2)
@@ -557,9 +564,11 @@ function render_elements(master_ass)
local foV = slider_lo.border + slider_lo.gap
local foH = 0
- if (slider_lo.stype == "slider") then
+ if (slider_lo.stype == "slider") or
+ (slider_lo.stype == "knob") then
foH = elem_geo.h / 2
elseif (slider_lo.stype == "bar") then
+ foV = foV + 1
foH = slider_lo.border + slider_lo.gap
end
@@ -575,6 +584,11 @@ function render_elements(master_ass)
elem_ass:line_to(xp+(innerH/2), (innerH/2)+foV)
elem_ass:line_to(xp, (innerH)+foV)
elem_ass:line_to(xp-(innerH/2), (innerH/2)+foV)
+ elseif (slider_lo.stype == "knob") then
+ elem_ass:rect_cw(xp, (9*innerH/20)+foV, elem_geo.w - foH, (11*innerH/20)+foV)
+ elem_ass:rect_cw(foH, (3*innerH/8)+foV, xp, (5*innerH/8)+foV)
+ elem_ass:round_rect_cw(xp - innerH/2, foV, xp + innerH/2,
+ foV + innerH, innerH/2.0)
end
end
@@ -619,6 +633,18 @@ function render_elements(master_ass)
elem_ass:pos(tx, ty)
elem_ass:an(an)
elem_ass:append(slider_lo.tooltip_style)
+
+ --alpha
+ local ar = slider_lo.alpha
+ if not (state.animation == nil) then
+ ar = {}
+ for ai, av in pairs(slider_lo.alpha) do
+ ar[ai] = mult_alpha(av, state.animation)
+ end
+ end
+ elem_ass:append(string.format("{\\1a&H%X&\\2a&H%X&\\3a&H%X&\\4a&H%X&}",
+ ar[1], ar[2], ar[3], ar[4]))
+
elem_ass:append(tooltiplabel)
end
@@ -651,47 +677,44 @@ end
-- Message display
--
+-- pos is 1 based
function limited_list(prop, pos)
- local fs = tonumber(mp.get_property('options/osd-font-size'))
- local max_items = math.ceil(720 / fs)
-
local proplist = mp.get_property_native(prop, {})
local count = #proplist
- if (count == 0) then
+ if count == 0 then
return count, proplist
end
- local min, max = 0, count
- local temp = {}
- if (count > max_items - 1) then
- local extra = math.ceil(max_items / 2) - 1
- min = pos - extra
- max = pos + extra
- if (pos < extra) then
- max = max + math.abs(min)
- min = 0
- end
+
+ local fs = tonumber(mp.get_property('options/osd-font-size'))
+ local max = math.ceil(720 / fs)
+ if max % 2 == 0 then
+ max = max - 1
end
+ local delta = math.ceil(max / 2) - 1
+ local begi = math.max(math.min(pos - delta, count - max + 1), 1)
+ local endi = math.min(begi + max - 1, count)
- for i=min+1, max do
+ local reslist = {}
+ for i=begi, endi do
local item = proplist[i]
- item.current = (i-1 == pos) and true or nil
- table.insert(temp, item)
+ item.current = (i == pos) and true or nil
+ table.insert(reslist, item)
end
- return count, temp
+ return count, reslist
end
function get_playlist()
- local pos = mp.get_property_number('playlist-pos')
+ local pos = mp.get_property_number('playlist-pos', 0) + 1
local count, limlist = limited_list('playlist', pos)
- if (count == 0) then
- return "Empty playlist."
+ if count == 0 then
+ return 'Empty playlist.'
end
- local message = string.format('Playlist: (%d/%d):\n', pos + 1, count)
+ local message = string.format('Playlist [%d/%d]:\n', pos, count)
for i, v in ipairs(limlist) do
local title = v.title
local _, filename = utils.split_path(v.filename)
- if (title == nil) then
+ if title == nil then
title = filename
end
message = string.format('%s %s %s\n', message,
@@ -701,18 +724,18 @@ function get_playlist()
end
function get_chapterlist()
- local pos = mp.get_property_number('chapter')
+ local pos = mp.get_property_number('chapter', 0) + 1
local count, limlist = limited_list('chapter-list', pos)
- if (count == 0) then
- return "No chapters."
+ if count == 0 then
+ return 'No chapters.'
end
- local message = string.format('Chapters: (%d/%d):\n', pos + 1, count)
+ local message = string.format('Chapters [%d/%d]:\n', pos, count)
for i, v in ipairs(limlist) do
local time = mp.format_time(v.time)
local title = v.title
- if (title == nil) then
- title = string.format('Chapter %02d', i + 1)
+ if title == nil then
+ title = string.format('Chapter %02d', i)
end
message = string.format('%s[%s] %s %s\n', message, time,
(v.current and '●' or '○'), title)
@@ -829,6 +852,7 @@ function add_layout(name)
adjust_tooltip = true,
tooltip_style = "",
tooltip_an = 2,
+ alpha = {[1] = 0, [2] = 255, [3] = 88, [4] = 255},
}
elseif (elements[name].type == "box") then
elements[name].layout.box = {radius = 0}
@@ -991,6 +1015,9 @@ layouts["box"] = function ()
lo.style = osc_styles.timecodes
lo.slider.tooltip_style = osc_styles.vidtitle
lo.slider.stype = user_opts["seekbarstyle"]
+ if lo.slider.stype == "knob" then
+ lo.slider.border = 0
+ end
--
-- Timecodes + Cache
@@ -1077,7 +1104,9 @@ layouts["slimbox"] = function ()
lo.style = osc_styles.box
lo.alpha[1] = user_opts.boxalpha
lo.alpha[3] = 0
- lo.box.radius = osc_geo.r
+ if not (user_opts["seekbarstyle"] == "bar") then
+ lo.box.radius = osc_geo.r
+ end
lo = add_layout("seekbar")
@@ -1123,16 +1152,28 @@ end
layouts["bottombar"] = function()
local osc_geo = {
x = -2,
- y = osc_param.playresy - 36 - user_opts.barmargin,
+ y = osc_param.playresy - 54 - user_opts.barmargin,
an = 7,
w = osc_param.playresx + 4,
- h = 38,
+ h = 56,
}
- local padX = 6
- local padY = 2
- local line1 = osc_geo.y + 6 + padY
- local line2 = osc_geo.y + 24 + padY
+ local padX = 9
+ local padY = 3
+ local buttonW = 27
+ local tcW = (state.tc_ms) and 150 or 105
+ local tsW = 90
+ local minW = (buttonW + padX)*3 + (tcW + padX)*4 + (tsW + padX)*2
+
+ if ((osc_param.display_aspect > 0) and (osc_param.playresx < minW)) then
+ osc_param.playresy = minW / osc_param.display_aspect
+ osc_param.playresx = osc_param.playresy * osc_param.display_aspect
+ osc_geo.y = osc_param.playresy - 54 - user_opts.barmargin
+ osc_geo.w = osc_param.playresx + 4
+ end
+
+ local line1 = osc_geo.y + 9 + padY
+ local line2 = osc_geo.y + 36 + padY
osc_param.areas = {}
@@ -1159,77 +1200,82 @@ layouts["bottombar"] = function()
-- Playlist prev/next
geo = { x = osc_geo.x + padX, y = line1,
- an = 4, w = 12, h = 12 - padY }
+ an = 4, w = 18, h = 18 - padY }
lo = add_layout("pl_prev")
lo.geometry = geo
- lo.style = osc_styles.topButtons
+ lo.style = osc_styles.topButtonsBar
geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
lo = add_layout("pl_next")
lo.geometry = geo
- lo.style = osc_styles.topButtons
+ lo.style = osc_styles.topButtonsBar
- -- Title
- geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an,
- w = 1000, h = geo.h }
- lo = add_layout("title")
- lo.geometry = geo
- lo.style = osc_styles.vidtitle
+ local t_l = geo.x + geo.w + padX
-- Cache
geo = { x = osc_geo.x + osc_geo.w - padX, y = geo.y,
- an = 6, w = 100, h = geo.h }
+ an = 6, w = 150, h = geo.h }
lo = add_layout("cache")
lo.geometry = geo
- lo.style = osc_styles.vidtitle
+ lo.style = osc_styles.vidtitleBar
+
+ local t_r = geo.x - geo.w - padX*2
+
+ -- Title
+ geo = { x = t_l, y = geo.y, an = 4,
+ w = t_r - t_l, h = geo.h }
+ lo = add_layout("title")
+ lo.geometry = geo
+ lo.style = osc_styles.vidtitleBar
+ lo.button.maxchars = math.floor(geo.w/7)
-- Playback control buttons
geo = { x = osc_geo.x + padX, y = line2, an = 4,
- w = 18, h = 24 - padY*2}
+ w = buttonW, h = 36 - padY*2}
lo = add_layout("playpause")
lo.geometry = geo
- lo.style = osc_styles.smallButtonsL
+ lo.style = osc_styles.smallButtonsBar
geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
lo = add_layout("ch_prev")
lo.geometry = geo
- lo.style = osc_styles.smallButtonsL
+ lo.style = osc_styles.smallButtonsBar
geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
lo = add_layout("ch_next")
lo.geometry = geo
- lo.style = osc_styles.smallButtonsL
-
+ lo.style = osc_styles.smallButtonsBar
-- Left timecode
- geo = { x = geo.x + geo.w + padX + 100, y = geo.y, an = 6, w = 100, h = geo.h }
+ geo = { x = geo.x + geo.w + padX + tcW, y = geo.y, an = 6,
+ w = tcW, h = geo.h }
lo = add_layout("tc_left")
lo.geometry = geo
- lo.style = osc_styles.timecodes
+ lo.style = osc_styles.timecodesBar
local sb_l = geo.x + padX
-- Track selection buttons
geo = { x = osc_geo.x + osc_geo.w - padX, y = geo.y, an = geo.an,
- w = 60, h = geo.h }
+ w = tsW, h = geo.h }
lo = add_layout("cy_sub")
lo.geometry = geo
- lo.style = osc_styles.smallButtonsL
+ lo.style = osc_styles.smallButtonsBar
geo = { x = geo.x - geo.w - padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
lo = add_layout("cy_audio")
lo.geometry = geo
- lo.style = osc_styles.smallButtonsL
+ lo.style = osc_styles.smallButtonsBar
-- Right timecode
- geo = { x = geo.x - geo.w - padX - 100, y = geo.y, an = 4,
- w = 100, h = geo.h }
+ geo = { x = geo.x - geo.w - padX - tcW, y = geo.y, an = 4,
+ w = tcW, h = geo.h }
lo = add_layout("tc_right")
lo.geometry = geo
- lo.style = osc_styles.timecodes
+ lo.style = osc_styles.timecodesBar
local sb_r = geo.x - padX
@@ -1242,7 +1288,7 @@ layouts["bottombar"] = function()
lo.geometry = geo
lo.layer = 15
- lo.style = osc_styles.timecodes
+ lo.style = osc_styles.timecodesBar
lo.alpha[1] =
math.min(255, user_opts.boxalpha + (255 - user_opts.boxalpha)*0.8)
@@ -1250,7 +1296,7 @@ layouts["bottombar"] = function()
lo.geometry = geo
lo.style = osc_styles.timecodes
lo.slider.border = 0
- lo.slider.tooltip_style = osc_styles.timePos
+ lo.slider.tooltip_style = osc_styles.timePosBar
lo.slider.tooltip_an = 5
lo.slider.stype = user_opts["seekbarstyle"]
end
@@ -1258,16 +1304,28 @@ end
layouts["topbar"] = function()
local osc_geo = {
x = -2,
- y = 36 + user_opts.barmargin,
+ y = 54 + user_opts.barmargin,
an = 1,
w = osc_param.playresx + 4,
- h = 38,
+ h = 56,
}
- local padX = 6
- local padY = 2
- local line1 = osc_geo.y - 24 - padY
- local line2 = osc_geo.y - 6 - padY
+ local padX = 9
+ local padY = 3
+ local buttonW = 27
+ local tcW = (state.tc_ms) and 150 or 105
+ local tsW = 90
+ local minW = (buttonW + padX)*3 + (tcW + padX)*4 + (tsW + padX)*2
+
+ if ((osc_param.display_aspect > 0) and (osc_param.playresx < minW)) then
+ osc_param.playresy = minW / osc_param.display_aspect
+ osc_param.playresx = osc_param.playresy * osc_param.display_aspect
+ osc_geo.y = 54 + user_opts.barmargin
+ osc_geo.w = osc_param.playresx + 4
+ end
+
+ local line1 = osc_geo.y - 36 - padY
+ local line2 = osc_geo.y - 9 - padY
osc_param.areas = {}
@@ -1295,7 +1353,7 @@ layouts["topbar"] = function()
-- Playback control buttons
geo = { x = osc_geo.x + padX, y = line1, an = 4,
- w = 18, h = 24 - padY*2 }
+ w = buttonW, h = 36 - padY*2 }
lo = add_layout("playpause")
lo.geometry = geo
lo.style = osc_styles.smallButtonsL
@@ -1312,8 +1370,8 @@ layouts["topbar"] = function()
-- Left timecode
- geo = { x = geo.x + geo.w + padX + 100, y = geo.y, an = 6,
- w = 100, h = geo.h }
+ geo = { x = geo.x + geo.w + padX + tcW, y = geo.y, an = 6,
+ w = tcW, h = geo.h }
lo = add_layout("tc_left")
lo.geometry = geo
lo.style = osc_styles.timecodes
@@ -1323,7 +1381,7 @@ layouts["topbar"] = function()
-- Track selection buttons
geo = { x = osc_geo.x + osc_geo.w - padX, y = geo.y, an = geo.an,
- w = 60, h = geo.h }
+ w = tsW, h = geo.h }
lo = add_layout("cy_sub")
lo.geometry = geo
lo.style = osc_styles.smallButtonsL
@@ -1335,8 +1393,8 @@ layouts["topbar"] = function()
-- Right timecode
- geo = { x = geo.x - geo.w - padX - 100, y = geo.y, an = 4,
- w = 100, h = geo.h }
+ geo = { x = geo.x - geo.w - padX - tcW, y = geo.y, an = 4,
+ w = tcW, h = geo.h }
lo = add_layout("tc_right")
lo.geometry = geo
lo.style = osc_styles.timecodes
@@ -1359,13 +1417,13 @@ layouts["topbar"] = function()
lo.geometry = geo
lo.style = osc_styles.timecodes
lo.slider.border = 0
- lo.slider.tooltip_style = osc_styles.timePos
+ lo.slider.tooltip_style = osc_styles.timePosBar
lo.slider.stype = user_opts["seekbarstyle"]
lo.slider.tooltip_an = 5
-- Playlist prev/next
- geo = { x = osc_geo.x + padX, y = line2, an = 4, w = 12, h = 12 - padY }
+ geo = { x = osc_geo.x + padX, y = line2, an = 4, w = 18, h = 18 - padY }
lo = add_layout("pl_prev")
lo.geometry = geo
lo.style = osc_styles.topButtons
@@ -1375,19 +1433,24 @@ layouts["topbar"] = function()
lo.geometry = geo
lo.style = osc_styles.topButtons
- -- Title
- geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an,
- w = 1000, h = geo.h }
- lo = add_layout("title")
- lo.geometry = geo
- lo.style = osc_styles.vidtitle
+ local t_l = geo.x + geo.w + padX
-- Cache
- geo = { x = osc_geo.x + osc_geo.w - padX, y = geo.y, an = 6,
- w = 100, h = geo.h }
+ geo = { x = osc_geo.x + osc_geo.w - padX, y = geo.y,
+ an = 6, w = 150, h = geo.h }
lo = add_layout("cache")
lo.geometry = geo
lo.style = osc_styles.vidtitle
+
+ local t_r = geo.x - geo.w - padX*2
+
+ -- Title
+ geo = { x = t_l, y = geo.y, an = 4,
+ w = t_r - t_l, h = geo.h }
+ lo = add_layout("title")
+ lo.geometry = geo
+ lo.style = osc_styles.vidtitle
+ lo.button.maxchars = math.floor(geo.w/7)
end
-- Validate string type user options
@@ -1398,7 +1461,8 @@ function validate_user_opts()
end
if user_opts.seekbarstyle ~= "slider" and
- user_opts.seekbarstyle ~= "bar" then
+ user_opts.seekbarstyle ~= "bar" and
+ user_opts.seekbarstyle ~= "knob" then
msg.warn("Invalid setting \"" .. user_opts.seekbarstyle
.. "\" for seekbarstyle")
user_opts.seekbarstyle = "slider"
@@ -1683,8 +1747,10 @@ function osc_init()
return (mp.get_property_osd("playback-time"))
end
end
- ne.eventresponder["mouse_btn0_up"] =
- function () state.tc_ms = not state.tc_ms end
+ ne.eventresponder["mouse_btn0_up"] = function ()
+ state.tc_ms = not state.tc_ms
+ request_init()
+ end
-- tc_right (total/remaining time)
ne = new_element("tc_right", "button")
@@ -2004,7 +2070,8 @@ function process_event(source, what)
if n == 0 then
--click on background (does not work)
- elseif n > 0 and not (elements[n].eventresponder[source .. "_" .. what] == nil) then
+ elseif n > 0 and not (n > #elements) and
+ not (elements[n].eventresponder[source .. "_" .. what] == nil) then
if mouse_hit(elements[n]) then
elements[n].eventresponder[source .. "_" .. what](elements[n])
@@ -2036,7 +2103,7 @@ function process_event(source, what)
local n = state.active_element
- if not (elements[n].eventresponder == nil) then
+ if not (n > #elements) and not (elements[n].eventresponder == nil) then
if not (elements[n].eventresponder[source] == nil) then
elements[n].eventresponder[source](elements[n])
end
@@ -2127,6 +2194,19 @@ mp.register_event("tracks-changed", request_init)
mp.observe_property("playlist", nil, request_init)
mp.register_script_message("osc-message", show_message)
+mp.register_script_message("osc-chapterlist", function(dur)
+ show_message(get_chapterlist(), dur)
+end)
+mp.register_script_message("osc-playlist", function(dur)
+ show_message(get_playlist(), dur)
+end)
+mp.register_script_message("osc-tracklist", function(dur)
+ local msg = {}
+ for k,v in pairs(nicetypes) do
+ table.insert(msg, get_tracklist(k))
+ end
+ show_message(table.concat(msg, '\n\n'), dur)
+end)
mp.observe_property("fullscreen", "bool",
function(name, val)
diff --git a/player/lua/ytdl_hook.lua b/player/lua/ytdl_hook.lua
index fa97dddc7b..1bae4f398c 100644
--- a/player/lua/ytdl_hook.lua
+++ b/player/lua/ytdl_hook.lua
@@ -84,7 +84,7 @@ local function extract_chapters(data, video_length)
table.insert(ret, {time = time, title = line})
end
end
-
+ table.sort(ret, function(a, b) return a.time < b.time end)
return ret
end
diff --git a/player/playloop.c b/player/playloop.c
index 18a51f33d0..f72994e8a9 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -249,6 +249,8 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek)
bool hr_seek_very_exact = seek.exact == MPSEEK_VERY_EXACT;
double current_time = get_current_time(mpctx);
+ if (current_time == MP_NOPTS_VALUE && seek.type == MPSEEK_RELATIVE)
+ return;
if (current_time == MP_NOPTS_VALUE)
current_time = 0;
double seek_pts = MP_NOPTS_VALUE;
@@ -606,8 +608,8 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
if (mpctx->restart_complete && c.size > 0) {
if (mpctx->paused && mpctx->paused_for_cache) {
- if (!opts->cache_pausing || s.ts_duration >= mpctx->cache_wait_time
- || s.idle)
+ if (!s.underrun && (!opts->cache_pausing || s.idle ||
+ s.ts_duration >= mpctx->cache_wait_time))
{
double elapsed_time = now - mpctx->cache_stop_time;
if (elapsed_time > mpctx->cache_wait_time) {
@@ -906,7 +908,7 @@ int handle_force_window(struct MPContext *mpctx, bool force)
};
if (vo_reconfig(vo, &p) < 0)
goto err;
- vo_control(vo, VOCTRL_RESTORE_SCREENSAVER, NULL);
+ update_screensaver_state(mpctx);
vo_set_paused(vo, true);
vo_redraw(vo);
mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
@@ -1093,7 +1095,7 @@ void run_playloop(struct MPContext *mpctx)
handle_dummy_ticks(mpctx);
update_osd_msg(mpctx);
- if (!mpctx->video_out)
+ if (mpctx->video_status == STATUS_EOF)
update_subtitles(mpctx, mpctx->playback_pts);
handle_eof(mpctx);
diff --git a/player/sub.c b/player/sub.c
index c4a24fe011..747eccef3e 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -112,6 +112,19 @@ static bool update_subtitle(struct MPContext *mpctx, double video_pts,
if (mpctx->current_track[0][STREAM_SUB] == track && !mpctx->video_out)
term_osd_set_subs(mpctx, sub_get_text(dec_sub, video_pts));
+ // Handle displaying subtitles on VO with no video being played. This is
+ // quite differently, because normally subtitles are redrawn on new video
+ // frames, using the video frames' timestamps.
+ if (mpctx->video_out && mpctx->video_status == STATUS_EOF) {
+ if (osd_get_force_video_pts(mpctx->osd) != video_pts) {
+ osd_set_force_video_pts(mpctx->osd, video_pts);
+ osd_query_and_reset_want_redraw(mpctx->osd);
+ vo_redraw(mpctx->video_out);
+ // Force an arbitrary minimum FPS
+ mp_set_timeout(mpctx, 0.1);
+ }
+ }
+
return true;
}
diff --git a/player/video.c b/player/video.c
index ff72f92d8e..847a5b56d9 100644
--- a/player/video.c
+++ b/player/video.c
@@ -729,8 +729,9 @@ static void adjust_sync(struct MPContext *mpctx, double v_pts, double frame_time
double av_delay = a_pts - v_pts;
double change = av_delay * 0.1;
+ double factor = fabs(av_delay) < 0.3 ? 0.1 : 0.4;
double max_change = opts->default_max_pts_correction >= 0 ?
- opts->default_max_pts_correction : frame_time * 0.1;
+ opts->default_max_pts_correction : frame_time * factor;
if (change < -max_change)
change = -max_change;
else if (change > max_change)
@@ -1423,6 +1424,9 @@ void write_video(struct MPContext *mpctx)
mpctx->time_frame -= get_relative_time(mpctx);
update_avsync_before_frame(mpctx);
+ // Enforce timing subtitles to video frames.
+ osd_set_force_video_pts(mpctx->osd, MP_NOPTS_VALUE);
+
if (!update_subtitles(mpctx, mpctx->next_frames[0]->pts)) {
MP_VERBOSE(mpctx, "Video frame delayed due waiting on subtitles.\n");
return;