dotfiles

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README

commit 28d86e611eed711924b90f5bf04137db744c8cea
parent c190f8f0c6009cff37d1b356bcb8d737cd77fa38
Author: Pablo Cárdenas <pablo.cardenas@imca.edu.pe>
Date:   Thu, 30 Apr 2026 14:06:10 -0300

mpv: added more plugins

Diffstat:
A.config/mpv/scripts/deepl.lua | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M.config/mpv/scripts/simple.lua | 204+++++++++++++++++++++++++++++--------------------------------------------------
A.config/mpv/scripts/vtt.lua | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 221 insertions(+), 130 deletions(-)

diff --git a/.config/mpv/scripts/deepl.lua b/.config/mpv/scripts/deepl.lua @@ -0,0 +1,69 @@ +http_request = require("http.request") +json = require("dkjson") + +DEEPL_API_KEY = os.getenv("DEEPL_API_KEY") +overlay = mp.create_osd_overlay("ass-events") +overlay.z = 10 + +function show_translation_deepl() + local sub_text = mp.get_property('sub-text') + if sub_text and sub_text ~= "" then + local translated_text = translate_deepl(sub_text) + -- local translated_text = sub_text + local lines = {} + + for line in translated_text:gmatch("[^\r\n]+") do + table.insert(lines, 1, '{\\an2}{\\1c&H00FFFF&}' .. line .. '') + end + for line in sub_text:gmatch("[^\r\n]+") do + table.insert(lines, 1, "{\\an2}\u{2000}") + end + table.insert(lines, 1, "") + + overlay.data = table.concat(lines, "\n") + overlay:update() + else + print("No text to show") + end + +end + + +function translate_deepl(source_text) + local req = http_request.new_from_uri('https://api-free.deepl.com/v2/translate') + req.headers:upsert(":method", "POST") + req.headers:upsert("content-type", "application/json") + req.headers:upsert("authorization", "DeepL-Auth-Key " .. DEEPL_API_KEY) + + req:set_body(json.encode({ + text = { source_text }, + target_lang = "EN", + source_lang = "PT" + })) + + local headers, stream = req:go() + if not headers then + error("Request failed") + end + + body = json.decode(stream:get_body_as_string()) + translated_text = json.encode(body["translations"][1]["text"]) + + return translated_text +end + +function sub_ab_loop() + local a = mp.get_property("sub-start") + local b = mp.get_property("sub-end") + local delay = mp.get_property_native("sub-delay") + if a == nil or b == nil then return; end + mp.set_property("ab-loop-a", a+delay-0.1) + mp.set_property("ab-loop-b", b+delay) +end + +mp.add_key_binding('F5', 'sub_ab_loop', sub_ab_loop) +mp.add_key_binding('C', 'show-translation-deepl', show_translation_deepl) +mp.observe_property('sub-end', 'number', function (_, sub_end) + overlay:remove() +end) + diff --git a/.config/mpv/scripts/simple.lua b/.config/mpv/scripts/simple.lua @@ -1,155 +1,99 @@ -http_request = require("http.request") -json = require("dkjson") +-- overlay = mp.create_osd_overlay("ass-events") +-- overlay.z = 10 -DEEPL_API_KEY = os.getenv("DEEPL_API_KEY") +-- nosub_start = nil +-- nosub_end = nil +-- sub_duration = 0.0 +-- last_sub_text = "" -overlay = mp.create_osd_overlay("ass-events") -overlay.z = 10 +-- function on_time_pos(name, time_pos) +-- if time_pos == nil or nosub_start == nil or nosub_end == nil then +-- return +-- end -nosub_start = nil -nosub_end = nil -sub_duration = 0.0 -last_sub_text = "" +-- local duration = nosub_end - nosub_start -function on_time_pos(name, time_pos) - if time_pos == nil or nosub_start == nil or nosub_end == nil then - return - end +-- if nosub_start == nil or nosub_end == nil or time_pos >= nosub_end or time_pos <= nosub_start then +-- mp.set_property('speed', 1) +-- return +-- end - local duration = nosub_end - nosub_start +-- local slope = 0.5 +-- local base_speed = 1 +-- local max_speed = 4 - if nosub_start == nil or nosub_end == nil or time_pos >= nosub_end or time_pos <= nosub_start then - mp.set_property('speed', 1) - return - end +-- local h = max_speed - base_speed +-- local x = duration / 2 - math.abs(time_pos - (nosub_start + nosub_end) / 2) +-- local speed = math.min(max_speed, slope * x + base_speed) - local slope = 0.5 - local base_speed = 1 - local max_speed = 4 +-- mp.set_property('speed', speed) - local h = max_speed - base_speed - local x = duration / 2 - math.abs(time_pos - (nosub_start + nosub_end) / 2) - local speed = math.min(max_speed, slope * x + base_speed) +-- if speed > 2 then +-- mp.osd_message(string.format("Speed %.1f", speed)) +-- end +-- end - mp.set_property('speed', speed) +-- function get_next_sub_start() +-- local sub_visibility = mp.get_property_bool('sub-visibility') +-- local sub_delay = mp.get_property_number('sub-delay') - if speed > 2 then - mp.osd_message(string.format("Speed %.1f", speed)) - end -end +-- mp.set_property_bool('sub-visibility', false) +-- mp.commandv('sub-step', 1) -function get_next_sub_start() - local sub_visibility = mp.get_property_bool('sub-visibility') - local sub_delay = mp.get_property_number('sub-delay') +-- local next_sub_start = mp.get_property_number('sub-start') - mp.set_property_bool('sub-visibility', false) - mp.commandv('sub-step', 1) +-- mp.set_property_number('sub-delay', sub_delay) +-- mp.set_property_bool('sub-visibility', sub_visibility) - local next_sub_start = mp.get_property_number('sub-start') +-- return next_sub_start +-- end - mp.set_property_number('sub-delay', sub_delay) - mp.set_property_bool('sub-visibility', sub_visibility) +-- function on_playback_restart() +-- local time_pos = mp.get_property_number('time-pos') +-- local sub_speed = mp.get_property_number('sub-speed', 1) +-- local sub_delay = mp.get_property_number('sub-delay') - return next_sub_start -end +-- local nextsub_start = get_next_sub_start() -function on_playback_restart() - local time_pos = mp.get_property_number('time-pos') - local sub_speed = mp.get_property_number('sub-speed', 1) - local sub_delay = mp.get_property_number('sub-delay') +-- nosub_start = time_pos +-- nosub_end = nextsub_start * sub_speed + sub_delay +-- end - local nextsub_start = get_next_sub_start() +-- function on_sub_end(_, sub_end) +-- overlay:remove() +-- if sub_end == nil then +-- -- mp.set_property("pause", "yes") +-- -- mp.osd_message("Repeat", sub_duration) - nosub_start = time_pos - nosub_end = nextsub_start * sub_speed + sub_delay -end +-- -- local lines = {} -function on_sub_end(_, sub_end) - overlay:remove() - if sub_end == nil then - -- mp.set_property("pause", "yes") - -- mp.osd_message("Repeat", sub_duration) +-- -- for line in last_sub_text:gmatch("[^\r\n]+") do +-- -- table.insert(lines, 1, '{\\an2}{\\1c&HFFFF00&}' .. line .. '') +-- -- end - -- local lines = {} +-- -- overlay.data = table.concat(lines, "\n") +-- -- overlay:update() - -- for line in last_sub_text:gmatch("[^\r\n]+") do - -- table.insert(lines, 1, '{\\an2}{\\1c&HFFFF00&}' .. line .. '') - -- end +-- -- mp.add_timeout(sub_duration, function() +-- -- mp.osd_message("") +-- -- mp.set_property("pause", "no") +-- -- overlay:remove() +-- -- end) +-- else +-- last_sub_text = mp.get_property('sub-text') +-- local sub_start = mp.get_property_number('sub-start') +-- local sub_speed = mp.get_property_number('sub-speed', 1) +-- local sub_delay = mp.get_property_number('sub-delay') - -- overlay.data = table.concat(lines, "\n") - -- overlay:update() +-- sub_duration = (sub_end - sub_start) * sub_speed - -- mp.add_timeout(sub_duration, function() - -- mp.osd_message("") - -- mp.set_property("pause", "no") - -- overlay:remove() - -- end) - else - last_sub_text = mp.get_property('sub-text') - local sub_start = mp.get_property_number('sub-start') - local sub_speed = mp.get_property_number('sub-speed', 1) - local sub_delay = mp.get_property_number('sub-delay') +-- local nextsub_start = get_next_sub_start() - sub_duration = (sub_end - sub_start) * sub_speed +-- nosub_start = sub_end * sub_speed + sub_delay +-- nosub_end = nextsub_start * sub_speed + sub_delay +-- end +-- end - local nextsub_start = get_next_sub_start() - - nosub_start = sub_end * sub_speed + sub_delay - nosub_end = nextsub_start * sub_speed + sub_delay - end -end - - - -function show_translation_deepl() - local sub_text = mp.get_property('sub-text') - if sub_text and sub_text ~= "" then - local translated_text = translate_deepl(sub_text) - -- local translated_text = sub_text - local lines = {} - - for line in translated_text:gmatch("[^\r\n]+") do - table.insert(lines, 1, '{\\an2}{\\1c&H00FFFF&}' .. line .. '') - end - for line in sub_text:gmatch("[^\r\n]+") do - table.insert(lines, 1, "{\\an2}\u{2000}") - end - table.insert(lines, 1, "") - - overlay.data = table.concat(lines, "\n") - overlay:update() - else - print("No text to show") - end - -end - - -function translate_deepl(source_text) - local req = http_request.new_from_uri('https://api-free.deepl.com/v2/translate') - req.headers:upsert(":method", "POST") - req.headers:upsert("content-type", "application/json") - req.headers:upsert("authorization", "DeepL-Auth-Key " .. DEEPL_API_KEY) - - req:set_body(json.encode({ - text = { source_text }, - target_lang = "ES", - source_lang = "EN" - })) - - local headers, stream = req:go() - if not headers then - error("Request failed") - end - - body = json.decode(stream:get_body_as_string()) - translated_text = json.encode(body["translations"][1]["text"]) - - return translated_text -end - - -mp.observe_property('sub-end', 'number', on_sub_end) -mp.observe_property('time-pos', 'number', on_time_pos) -mp.register_event("playback-restart", on_playback_restart) -mp.add_key_binding('C', 'show-translation-deepl', show_translation_deepl) +-- mp.observe_property('sub-end', 'number', on_sub_end) +-- mp.observe_property('time-pos', 'number', on_time_pos) +-- mp.register_event("playback-restart", on_playback_restart) diff --git a/.config/mpv/scripts/vtt.lua b/.config/mpv/scripts/vtt.lua @@ -0,0 +1,78 @@ +local mp = require 'mp' + +mp.register_event("file-loaded", function() + local tracks = mp.get_property_native("track-list") + + for _, t in ipairs(tracks) do + if t["type"] == "sub" and t.external and t["external-filename"]:match("%.vtt$") then + local f = io.open((t["external-filename"]), "r") + local path_new = os.tmpname() .. ".srt" + local file_new = io.open(path_new, 'w') + local path_sentences = os.tmpname() .. ".srt" + local file_sentences = io.open(path_sentences, 'w') + + local str_start + local str_end + local index = 1 + local index_sentence = 1 + local i_line = 0 + local sentence = {} + local previous_timestamp_sentence = "00:00:00.000" + for line in f:lines() do + if i_line % 8 == 4 then + str_start, str_end = line:match("(%d%d:%d%d:%d%d%.%d+)%s+-->%s+(%d%d:%d%d:%d%d%.%d+)") + end + if i_line % 8 == 6 then + -- remove <c> tags + line = line:gsub("</?c>", "") + + -- prepend start time + line = " " .. line .. "<" .. str_end .. ">" + + local previous_timestamp = str_start + for content, timestamp in line:gmatch("([^<]*)<(%d%d:%d%d:%d%d%.%d+)>") do + local word = content:gsub("&gt;", ">"):gsub("&nbsp;", " ") + + file_new:write(index, '\n') + file_new:write(previous_timestamp .. " --> " .. timestamp, '\n') + file_new:write(word, '\n') + file_new:write('\n') + + if word:sub(1, 3) == " >>" then + file_sentences:write(index_sentence, '\n') + file_sentences:write(previous_timestamp_sentence .. " --> " .. previous_timestamp, '\n') + file_sentences:write(table.concat(sentence), '\n') + file_sentences:write('\n') + index_sentence = index_sentence + 1 + previous_timestamp_sentence = previous_timestamp + sentence = {} + end + + table.insert(sentence, word) + + if word:sub(-1) == "." or word:sub(-1) == "?" or word:sub(-1) == ":" or word:sub(-2) == ".\"" or word:sub(-2) == "?\"" then + file_sentences:write(index_sentence, '\n') + file_sentences:write(previous_timestamp_sentence .. " --> " .. timestamp, '\n') + file_sentences:write(table.concat(sentence), '\n') + file_sentences:write('\n') + index_sentence = index_sentence + 1 + previous_timestamp_sentence = timestamp + sentence = {} + end + + previous_timestamp = timestamp + index = index + 1 + end + end + i_line = i_line + 1 + end + file_new:close() + + mp.commandv("sub-add", path_new, "select") + mp.commandv("sub-add", path_sentences, "select") + mp.msg.info("Loaded converted VTT → SRT") + end + end +end) + +-- vim: sts=4 sw=4 et