mpv2oboeru

mpv helpers to create flashcards from movies and TV shows
git clone anongit@rnpnr.xyz:mpv2oboeru.git
Log | Files | Refs | Feed | README | LICENSE

Commit: c5bed79009f0f6f01a8f91208a77f7c5df841018
Parent: 68d0466ba3cbcd222be5ca99bbc316d2c52331a6
Author: Ren Tatsumoto
Date:   Sat,  5 Sep 2020 19:22:56 +0300

add a menu for advanced timing monipulations

Diffstat:
MREADME.md | 57+++++++++++++++++++++++++++++++++++++++++++--------------
Msubs2srs.lua | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 185 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md @@ -95,30 +95,56 @@ Key bindings are configured in ```~/.config/mpv/input.conf```. This step is not necessary. ``` Ctrl+e script-binding anki-export-note +Ctrl+h script-binding sub-rewind +a script-binding mpvacious-menu-open +``` +These additional bindings aren't enabled by default but can be accesesed via thqe menu (`a`). +``` Ctrl+s script-binding set-starting-line Ctrl+r script-binding reset-timings Ctrl+t script-binding toggle-sub-autocopy -Ctrl+h script-binding sub-rewind ``` ## Usage -* `Ctrl+t` - **T**oggles the `autoclip` option. -When enabled, you can use it in combination with -[Yomichan](https://foosoft.net/projects/yomichan/)'s clipboard monitor. -`Yomichan Search` is activated by pressing `Alt+Insert` in your web browser. -* `Ctrl+e` - **E**xports a card with the currently visible subtitle line on the front. -* `Ctrl+s` - Sets the **s**tarting line. -It is supposed to be used when a sentence spans multiple subtitle lines. -After pressing `Ctrl+s`, wait for the next line(s) to appear -and then press `Ctrl+e` to set the **e**nding line and create the card. -* `Ctrl+r` - If you pressed `Ctrl+s` but changed your mind, -it **r**esets the starting line. -* `Ctrl+h` - Seeks to the starting point of the currently visible subtitle. +### Global bindings +* `Ctrl+e` - **E**xport a card with the currently visible subtitle line on the front. +Use this when your subs are perfectly timed and the target sentence doesn't span multiple subs. +* `Ctrl+h` - Seek to the start of the currently visible subtitle. Use it if you missed something. +### Menu options +* `a` - Open `advanced menu` with a list of all available keybindings. + +Let's say your subs are still perfectly timed, +but the sentence you want to add is split between multiple subs. +We need to combine the lines before making a card. +* `c` - Set timings to the current sub and remember the corresponding line. +It does nothing if there's no subs on screen. + +Then seek or continue watching until the next line that you want to combine appears on screen. +Press `Ctrl+e` to make the card. +* `r` - Forget all previously saved timings and associated dialogs. + +If subs are badly timed, first of all, you could try to retime them. +[ffsubsync](https://github.com/smacke/ffsubsync) is a program that will do it for you. +Another option would be to shift timings using key bindings provided by mpv. + +* `z` and `shift+z` - Adjust subtitle delay. + +If above fails, you have to manually set timings. +* `s` - Set the start time. +* `e` - Set the end time. + +### How do I add definitions to the card I just made After the card is created, you can find it by typing ```tag:subs2srs added:1``` in the Anki Browser. Then use [qolibri](https://aur.archlinux.org/packages/qolibri/) or similar software to add definitions to the card. -## Additional mpv key bindings +Pressing `t` in the `advanced menu` toggles the `autoclip` option. +Now as subtitles appear on the screen, they will be immidiately copied to the clipboard. +You can use it in combination with +[Yomichan](https://foosoft.net/projects/yomichan/) clipboard monitor. +`Yomichan Search` is activated by pressing `Alt+Insert` in your web browser. + +### Additional mpv key bindings I recommend adding these lines to your ```~/.config/mpv/input.conf``` for smoother experience. ``` @@ -145,6 +171,9 @@ X sub-step 1 x sub-step -1 ``` ## Hacking +If you want to modify this script +or make an entirely new one from scratch, +these links may help. * https://mpv.io/manual/master/#lua-scripting * https://github.com/mpv-player/mpv/blob/master/player/lua/defaults.lua * https://github.com/SenneH/mpv2anki diff --git a/subs2srs.lua b/subs2srs.lua @@ -27,11 +27,13 @@ local config = { sentence_field = "SentKanji", audio_field = "SentAudio", image_field = "Image", + menu_font_size = 24, } local utils = require('mp.utils') local msg = require('mp.msg') local mpopt = require('mp.options') +local overlay = mp.create_osd_overlay('ass-events') mpopt.read_options(config, "subs2srs") @@ -40,9 +42,11 @@ local subs local clip_autocopy local ffmpeg local ankiconnect +local menu -- classes local Subtitle +local OSD ------------------------------------------------------------ -- utility functions @@ -259,6 +263,7 @@ local function sub_rewind() end local function export_to_anki(gui) + menu.close() local sub = subs.get() subs.clear() @@ -278,6 +283,12 @@ local function export_to_anki(gui) end end +local function menu_aware_message(message, duration) + if menu.active == false then + mp.osd_message(message, duration) + end +end + ------------------------------------------------------------ -- ffmpeg helper @@ -508,6 +519,7 @@ subs.append = function() if sub ~= nil and not table.contains(subs.list, sub) then table.insert(subs.list, sub) + menu.update() end end @@ -517,6 +529,7 @@ subs.set_timing = function(position) if is_emptytable(subs.list) then mp.observe_property("sub-text", "string", subs.append) end + menu.update() end subs.set_starting_line = function() @@ -525,11 +538,11 @@ subs.set_starting_line = function() local current_sub = subs.get_current() if current_sub ~= nil then - local starting_point = human_readable_time(current_sub['start']) - mp.osd_message("Starting point is set to " .. starting_point, 2) mp.observe_property("sub-text", "string", subs.append) + local starting_point = human_readable_time(current_sub['start']) + menu_aware_message("Starting point is set to " .. starting_point, 2) else - mp.osd_message("There's no visible subtitle.", 2) + menu_aware_message("There's no visible subtitle.", 2) end end @@ -544,7 +557,8 @@ end subs.reset_timings = function() subs.clear() - mp.osd_message("Timings have been reset.", 2) + menu_aware_message("Timings have been reset.", 2) + menu.update() end ------------------------------------------------------------ @@ -554,12 +568,12 @@ clip_autocopy = {} clip_autocopy.enable = function() mp.observe_property("sub-text", "string", set_clipboard) - mp.osd_message("Clipboard autocopy is enabled.", 1) + menu_aware_message("Clipboard autocopy is enabled.", 1) end clip_autocopy.disable = function() mp.unobserve_property(set_clipboard) - mp.osd_message("Clipboard autocopy is disabled.", 1) + menu_aware_message("Clipboard autocopy is disabled.", 1) end clip_autocopy.toggle = function() @@ -570,6 +584,15 @@ clip_autocopy.toggle = function() clip_autocopy.enable() config.autoclip = true end + menu.update() +end + +clip_autocopy.enabled = function() + if config.autoclip == true then + return 'yes' + else + return 'no' + end end ------------------------------------------------------------ @@ -597,6 +620,115 @@ Subtitle.__lt = function (lhs, rhs) end ------------------------------------------------------------ +-- main menu + +menu = {} + +menu.active = false + +menu.keybinds = { + { key = 's', fn = function() subs.set_timing('start') end }, + { key = 'e', fn = function() subs.set_timing('end') end }, + { key = 'c', fn = function() subs.set_starting_line() end }, + { key = 'r', fn = function() subs.reset_timings() end }, + { key = 'g', fn = function() export_to_anki(true) end }, + { key = 't', fn = function() clip_autocopy.toggle() end }, + { key = 'a', fn = function() menu.close() end }, + { key = 'ESC', fn = function() menu.close() end }, +} + +menu.update = function() + if menu.active == false then + return + end + + table.sort(subs.list) + local osd = OSD:new():size(config.menu_font_size) + osd:bold('mpvacious: advanced options'):newline() + osd:newline() + + osd:bold('Start time: '):append(human_readable_time(subs.get_timing('start'))):newline() + osd:bold('End time: '):append(human_readable_time(subs.get_timing('end'))):newline() + osd:bold('Clipboard autocopy: '):append(clip_autocopy.enabled()):newline() + osd:newline() + + osd:bold('Menu bindings:'):newline() + osd:tab():bold('c: '):append('Set timings to the current sub'):newline() + osd:tab():bold('s: '):append('Set start time to current position'):newline() + osd:tab():bold('e: '):append('Set end time to current position'):newline() + osd:tab():bold('r: '):append('Reset timings'):newline() + osd:tab():bold('g: '):append('Export note using the `Add Cards` dialog'):newline() + osd:tab():bold('t: '):append('Toggle clipboard autocopy'):newline() + osd:tab():bold('ESC: '):append('Close'):newline() + osd:newline() + + osd:bold('Global bindings:'):newline() + osd:tab():bold('ctrl+e: '):append('Export note'):newline() + osd:tab():bold('ctrl+h: '):append('Seek to the start of the line'):newline() + osd:draw() +end + +menu.open = function() + if menu.active == true then + return + end + + for _, val in pairs(menu.keybinds) do + mp.add_key_binding(val.key, val.key, val.fn) + end + menu.active = true + menu.update() +end + +menu.close = function() + if menu.active == false then + return + end + + for _, val in pairs(menu.keybinds) do + mp.remove_key_binding(val.key) + end + overlay:remove() + menu.active = false +end + +------------------------------------------------------------ +-- Helper class for styling OSD messages + +OSD = {} +OSD.__index = OSD + +function OSD:new() + return setmetatable({text=''}, self) +end + +function OSD:append(s) + self.text = self.text .. s + return self +end + +function OSD:bold(s) + return self:append('{\\b1}' .. s .. '{\\b0}') +end + +function OSD:newline() + return self:append('\\N') +end + +function OSD:tab() + return self:append('\\h\\h\\h\\h') +end + +function OSD:size(size) + return self:append('{\\fs' .. size .. '}') +end + +function OSD:draw() + overlay.data = self.text + overlay:update() +end + +------------------------------------------------------------ -- main if config.autoclip == true then clip_autocopy.enable() end @@ -604,7 +736,8 @@ if config.autoclip == true then clip_autocopy.enable() end check_config_sanity() ankiconnect.create_deck_if_doesnt_exist(config.deck_name) mp.add_key_binding("ctrl+e", "anki-export-note", export_to_anki) -mp.add_key_binding("ctrl+s", "set-starting-line", subs.set_starting_line) -mp.add_key_binding("ctrl+r", "reset-timings", subs.reset_timings) -mp.add_key_binding("ctrl+t", "toggle-sub-autocopy", clip_autocopy.toggle) mp.add_key_binding("ctrl+h", "sub-rewind", sub_rewind) +mp.add_key_binding('a', 'mpvacious-menu-open', menu.open) -- a for advanced +mp.add_key_binding(null, "set-starting-line", subs.set_starting_line) +mp.add_key_binding(null, "reset-timings", subs.reset_timings) +mp.add_key_binding(null, "toggle-sub-autocopy", clip_autocopy.toggle)