mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
28.23k stars 2.9k forks source link

[term] Show chapter remaining time? #11922

Closed 097115 closed 1 year ago

097115 commented 1 year ago

When playing, for example, an audiobook in the terminal (with --no-audio-display), is it possible somehow to display a remaining time for the chapter alongside the total played / remaninig time?

I know --term-playing-msg exists, and I can also calculate the remaining time for the chapter like this, probably:

    local time = mp.get_property_native("time-pos")
    local chap = mp.get_property_native("chapter") + 1 + 1
    local chaps = mp.get_property_native("chapter-list")
    mp.msg.info("Chapter time remaining, seconds: " .. chaps[chap].time - time)

But can I by some means glue those two together?

Would be grateful for any hint, thanks :)

guidocella commented 1 year ago

Update term-playing-msg with mp.add_periodic_timer.

097115 commented 1 year ago

@guidocella Thanks for the reply!

You mean inside a lua script calculate a variable containing chapterremaining time, make it update with a timer, and from the command line call --term-playing-msg='${this_variable'}? Or am I missing something?

guidocella commented 1 year ago

Use mp.add_period_timer to continously set term-playing-msg to the remaining time.

097115 commented 1 year ago

Aha! Thanks again, @guidocella :)

So, I did something like this:

timer = mp.add_periodic_timer(1, function()
    if mp.get_property_native("chapters") > 1 then
        local time = mp.get_property_native("time-pos")
        local chap = mp.get_property_native("chapter") + 1 + 1
        local chaps = mp.get_property_native("chapter-list")
        -- disp_time() is my local helper function defined above
        -- to convert total seconds to HH:MM:SS format
        local chap_remaining_time = disp_time(chaps[chap].time - time)
        -- mp.msg.info(chap_remaining_time) -- just in case, this works, just always prints on a new line (as expected)
        mp.set_property("term-playing-msg", chap_remaining_time)
    end
end)

But it doesn't seem to show anything? I probably should toggle it somehow?

guidocella commented 1 year ago

mp.get_property_native("chapters") > 1 compares a number with a table. # is the operator for getting tables' length in Lua.

097115 commented 1 year ago

@guidocella

It's not this :)

As I noted in the code, mp.msg.info(chap_remaining_time) successfully bypasses this guard and does print out the remaining time. I can even remove this if...end for the sake of the experiment, and mp.set_property("term-playing-msg", chap_remaining_time) still doesn't show up :(

097115 commented 1 year ago

@guidocella

It's somewhat weird that if remove timer, if my whole script is just one line:

mp.set_property("term-playing-msg", "Test message")

Then it does show up. However, if wrapped in timer

timer = mp.add_periodic_timer(3, function()
    mp.set_property("term-playing-msg", "Test message")
end)

Then it doesn't. What may be the culprit, what do you think?

guidocella commented 1 year ago

Sorry, you need to set term-status-msg. term-playing-msg is only played after starting playback.

097115 commented 1 year ago

@guidocella

Oh, missed that, too. Thanks a lot! it works :)

mrfragger commented 9 months ago

@guidocella

Oh, missed that, too. Thanks a lot! it works :)

anyway to get this to display with a hotkey in the GUI?

I use audiobooks all the time and finally found a sleeptimer that works 15m, 30m, 45m, 60m. Some audiobook apps have ability to set sleep timer for at end of chapter. Don't think we'd ever get there but at least get close if we knew remaining chapter time. I've search like crazy but this terminal solution is only thing close to what I'm looking for.

when I start I get the if mp.get_property_native("chapters") > 1 then which is attempting to compare number to nil error message

I'm really at a loss trying to get this to work. Any hints?

local utils = require 'mp.utils'
local msg = require 'mp.msg'

function disp_time(time)
    local hours = math.floor(time/3600)
    local minutes = math.floor((time % 3600)/60)
    local seconds = math.floor(time % 60)

    return string.format("%02d:%02d:%02d", hours, minutes, seconds)
end

timer = mp.add_periodic_timer(1, function()
    if mp.get_property_native("chapters") > 1 then
        local time = mp.get_property_native("time-pos")
        local chap = mp.get_property_native("chapter") + 1 + 1
        local chaps = mp.get_property_native("chapter-list")
        -- disp_time() is my local helper function defined above
        -- to convert total seconds to HH:MM:SS format
        local chap_remaining_time = disp_time(chaps[chap].time - time)
        mp.osd_message(string.format("Chapter remaining time: %s", chap_remaining_time),5)
      --  mp.set_property("script-message-to", chap_remaining_time)
    end
end)
mp.add_key_binding('Ctrl+Meta+z', 'chap_remaining_time', timer)
guidocella commented 9 months ago

https://mpv.io/manual/master/#lua-scripting-mp-add-periodic-timer(seconds,-fn-[,-disabled]) has an example for disabling a timer. You get the count of chapters with local chapters = mp.get_property_native("chapters") and #chapters.

mrfragger commented 9 months ago

thanks for the input. I ended up with this..lowest seems to set every two seconds. I think every ten seconds which is this example is just fine.

local utils = require 'mp.utils'
local msg = require 'mp.msg'

function disp_time(time)
    local hours = math.floor(time/3600)
    local minutes = math.floor((time % 3600)/60)
    local seconds = math.floor(time % 60)

    return string.format("%02d:%02d:%02d", hours, minutes, seconds)
end

timer = mp.add_periodic_timer(10, function()
    if mp.get_property_native("chapters")  > 0 then
        local time = mp.get_property_native("time-pos")
        local chap = mp.get_property_native("chapter") + 1 + 1
        local chaps = mp.get_property_native("chapter-list")
        local chap_remaining_time = disp_time(chaps[chap].time - time) 
        timenow = os.date('%I:%M:%S',os.time())
        finishwhen = os.date('%I:%M:%S',os.time()+mp.get_property("time-remaining"))
        mp.osd_message(string.format("-%s", chap_remaining_time.." "..timenow.." "..finishwhen),10)
    end
end)
Mehvix commented 2 months ago

I found that "time-remaining" doesn't account for the playback speed. This can be resolved by diving by mp.get_property_number("speed")