diff options
| author | navewindre <boneyaard@gmail.com> | 2025-04-05 03:00:29 +0200 |
|---|---|---|
| committer | navewindre <boneyaard@gmail.com> | 2025-04-05 03:00:29 +0200 |
| commit | d6c4365b8de32b621ac46074a9b69908b95686c0 (patch) | |
| tree | 495cb5b1aa7e68ab6ec07fa5fb09904a8c7e47e7 /config/mpv/scripts/subs2srs/subtitles/secondary_sid.lua | |
| parent | b24463f3d045783b8f4e72926054d53b908e150f (diff) | |
a
Diffstat (limited to 'config/mpv/scripts/subs2srs/subtitles/secondary_sid.lua')
| -rw-r--r-- | config/mpv/scripts/subs2srs/subtitles/secondary_sid.lua | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/config/mpv/scripts/subs2srs/subtitles/secondary_sid.lua b/config/mpv/scripts/subs2srs/subtitles/secondary_sid.lua new file mode 100644 index 0000000..21576e8 --- /dev/null +++ b/config/mpv/scripts/subs2srs/subtitles/secondary_sid.lua @@ -0,0 +1,196 @@ +--[[ +Copyright: Ren Tatsumoto and contributors +License: GNU GPL, version 3 or later; http://www.gnu.org/licenses/gpl.html + +This module automatically finds and sets secondary sid if it's not already set. +Secondary sid will be shown when mouse is moved to the top part of the mpv window. +]] + +local mp = require('mp') +local h = require('helpers') + +local self = { + visibility = 'auto', + visibility_states = { auto = true, never = true, always = true, }, +} + +local function is_accepted_language(sub_lang) + -- for missing keys compares nil to true + return self.accepted_languages[sub_lang] == true +end + +local function is_selected_language(track, active_track) + return track.id == mp.get_property_native('sid') or (active_track and active_track.lang == track.lang) +end + +local function is_full(track) + return h.str_contains(track.title, 'full') +end + +local function is_garbage(track) + for _, keyword in pairs({ 'song', 'sign', 'caption', 'commentary' }) do + if h.str_contains(track.title, keyword) then + return true + end + end + return false +end + +local function prioritize_full_subs(tracks_list) + return table.sort(tracks_list, function(first, second) + return (is_full(first) and not is_full(second)) or (is_garbage(second) and not is_garbage(first)) + end) +end + +local function find_best_secondary_sid() + local active_track = h.get_active_track('sub') + local sub_tracks = h.get_loaded_tracks('sub') + prioritize_full_subs(sub_tracks) + for _, track in ipairs(sub_tracks) do + if is_accepted_language(track.lang) and not is_selected_language(track, active_track) then + return track.id + end + end + return nil +end + +local function window_height() + return mp.get_property_native('osd-dimensions/h') +end + +local function get_accepted_sub_langs() + local languages = {} + for lang in self.config.secondary_sub_lang:gmatch('[a-zA-Z-]+') do + languages[lang] = true + end + return languages +end + +local function on_mouse_move(_, state) + -- state = {x=int,y=int, hover=true|false, } + if mp.get_property_native('secondary-sid') and self.visibility == 'auto' and state ~= nil then + mp.set_property_bool( + 'secondary-sub-visibility', + state.hover and (state.y / window_height()) < self.config.secondary_sub_area + ) + end +end + +local function on_file_loaded() + -- If secondary sid is not already set, try to find and set it. + local secondary_sid = mp.get_property_native('secondary-sid') + if secondary_sid == false and self.config.secondary_sub_auto_load == true then + secondary_sid = find_best_secondary_sid() + if secondary_sid ~= nil then + mp.set_property_native('secondary-sid', secondary_sid) + end + end +end + +local function update_visibility() + mp.set_property_bool('secondary-sub-visibility', self.visibility == 'always') +end + +local function init(config) + self.config = config + self.visibility = config.secondary_sub_visibility + self.accepted_languages = get_accepted_sub_langs() + mp.register_event('file-loaded', on_file_loaded) + if config.secondary_sub_area > 0 then + mp.observe_property('mouse-pos', 'native', on_mouse_move) + end + update_visibility() +end + +local function change_visibility() + while true do + self.visibility = next(self.visibility_states, self.visibility) + if self.visibility ~= nil then + break + end + end + update_visibility() + h.notify("Secondary sid visibility: " .. self.visibility) +end + +local function compare_by_preference_then_id(track1, track2) + if is_accepted_language(track1.lang) and not is_accepted_language(track2.lang) then + return true + elseif not is_accepted_language(track1.lang) and is_accepted_language(track2.lang) then + return false + else + return (track1.id < track2.id) + end +end + +local function split_before_after(previous_tracks, next_tracks, all_tracks, current_track_id) + -- works like take_while() and drop_while() combined + local prev = true + for _, track in ipairs(all_tracks) do + if prev == true and track.id == current_track_id then + prev = false + end + if track.id ~= current_track_id then + if prev then + table.insert(previous_tracks, track) + else + table.insert(next_tracks, track) + end + end + end +end + +local function not_primary_sid(track) + return mp.get_property_native('sid') ~= track.id +end + +local function find_new_secondary_sub(direction) + local subtitle_tracks = h.filter(h.get_loaded_tracks('sub'), not_primary_sid) + table.sort(subtitle_tracks, compare_by_preference_then_id) + + local secondary_sid = mp.get_property_native('secondary-sid') + local new_secondary_sub = { id = false, title = "removed" } + + if #subtitle_tracks > 0 then + if not secondary_sid then + new_secondary_sub = (direction == 'prev') and subtitle_tracks[#subtitle_tracks] or subtitle_tracks[1] + else + local previous_tracks = {} + local next_tracks = {} + split_before_after(previous_tracks, next_tracks, subtitle_tracks, secondary_sid) + if direction == 'prev' and #previous_tracks > 0 then + new_secondary_sub = previous_tracks[#previous_tracks] + elseif direction == 'next' and #next_tracks > 0 then + new_secondary_sub = next_tracks[1] + end + end + end + return new_secondary_sub +end + +local function switch_secondary_sid(direction) + local new_secondary_sub = find_new_secondary_sub(direction) + + mp.set_property_native('secondary-sid', new_secondary_sub.id) + if new_secondary_sub.id == false then + h.notify("Removed secondary sid.") + else + h.notify(string.format( + "Secondary #%d: %s (%s)", + new_secondary_sub.id, + new_secondary_sub.title or "No title", + new_secondary_sub.lang or "Unknown" + )) + end +end + +return { + init = init, + change_visibility = change_visibility, + select_previous = function() + switch_secondary_sid('prev') + end, + select_next = function() + switch_secondary_sid('next') + end, +} |
