Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/RELEASE/subs2srs.conf
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,24 @@ ffmpeg_audio_args=-af loudnorm=I=-16:TP=-1.5:LRA=11:dual_mono=true
mpv_audio_args=--af-append=loudnorm=I=-16:TP=-1.5:LRA=11:dual_mono=true
#mpv_audio_args=
#mpv_audio_args=--af-append=silenceremove=1:0:-50dB


##
## Custom Sub Filter
## Place a `subs2srs_sub_filter.lua` file
## in the `~/.config/mpv/subs2srs_sub_filter` directory.
## The custom script must return a table
## that includes either of a `preprocess` or a `trim` function (or both).
##
## - `preprocess(text)`: Executes before trimming/cleaning.
## - `trim(text)`: Replaces the built-in trimming logic.
##

# Enable custom sub preprocessing by default (yes, no)
custom_sub_filter_enabled=no

# Notification prefix for toggle
custom_sub_filter_notification=Custom Sub Filter

# Use a custom trim instead of the built in one (yes, no)
use_custom_trim=no
32 changes: 32 additions & 0 deletions helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -369,4 +369,36 @@ this.deep_copy = function(obj, seen)
return setmetatable(res, getmetatable(obj))
end

this.maybe_require = function(module_name)
-- ~/.config/mpv/scripts/ and the mpvacious dir
local parent, child = utils.split_path(mp.get_script_directory())
-- ~/.config/mpv/ and "scripts"
parent, child = utils.split_path(parent:gsub("/$", ""))
-- ~/.config/mpv/subs2srs_sub_filter
local external_scripts_path = utils.join_path(parent, "subs2srs_sub_filter")

local search_template = external_scripts_path .. "/?.lua;"
local module_path = package.searchpath(module_name, search_template)

if not module_path then
return nil
end

local original_package_path = package.path
package.path = search_template .. package.path

local ok, loaded_module = pcall(require, module_name)

package.path = original_package_path

if not ok then
error(string.format("Failed to load module '%s' from '%s'. Error: %s",
module_name,
module_path,
tostring(loaded_module)))
end

return loaded_module
end

return this
10 changes: 8 additions & 2 deletions subs2srs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ local config = {
use_forvo = "yes", -- 'yes', 'no', 'always'
vocab_field = "VocabKanji", -- target word field
vocab_audio_field = "VocabAudio", -- target word audio

-- Custom Sub Filter
custom_sub_filter_enabled = false, -- True to enable custom sub preprocessing be default
custom_sub_filter_notification = "Custom Sub Filter", -- Notification prefix for toggle
use_custom_trim = false -- True to use a custom trim instead of the built in one
}

-- Defines config profiles
Expand Down Expand Up @@ -296,15 +301,15 @@ end)()

local function prepare_for_exporting(sub_text)
if not h.is_empty(sub_text) then
sub_text = h.trim(sub_text)
sub_text = subs_observer.clipboard_prepare(sub_text)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this unintentional?

Copy link
Contributor Author

@NamelessAssassin NamelessAssassin Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dId his because I think the text exported to the card should be the same as what is prepared for clipboard.
Could this cause any issues?

sub_text = h.escape_special_characters(sub_text)
end
return sub_text
end

local function construct_note_fields(sub_text, secondary_text, snapshot_filename, audio_filename)
local ret = {
[config.sentence_field] = subs_observer.maybe_remove_all_spaces(prepare_for_exporting(sub_text)),
[config.sentence_field] = prepare_for_exporting(sub_text),
}
if not h.is_empty(config.secondary_field) then
ret[config.secondary_field] = prepare_for_exporting(secondary_text)
Expand Down Expand Up @@ -821,6 +826,7 @@ local main = (function()
mp.add_key_binding("Ctrl+C", "mpvacious-copy-secondary-sub-to-clipboard", subs_observer.copy_current_secondary_to_clipboard)
mp.add_key_binding("Ctrl+t", "mpvacious-autocopy-toggle", subs_observer.toggle_autocopy)
mp.add_key_binding("Ctrl+g", "mpvacious-animated-snapshot-toggle", encoder.snapshot.toggle_animation)
mp.add_key_binding("", "mpvacious-toggle-custom-sub-filter", subs_observer.toggle_custom_sub_filter)

-- Secondary subtitles
mp.add_key_binding("Ctrl+v", "mpvacious-secondary-sid-toggle", secondary_sid.change_visibility)
Expand Down
50 changes: 49 additions & 1 deletion subtitles/observer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ local Subtitle = require('subtitles.subtitle')
local mp = require('mp')
local platform = require('platform.init')
local switch = require('utils.switch')
local custom_sub_filter = h.maybe_require('subs2srs_sub_filter')

local self = {}

Expand All @@ -22,6 +23,7 @@ local all_secondary_dialogs = sub_list.new()
local user_timings = timings.new()

local append_dialogue = false
local custom_sub_filter_enabled = false
local autoclip_enabled = false
local autoclip_method = {}

Expand Down Expand Up @@ -153,6 +155,25 @@ local function copy_subtitle(subtitle_id)
self.copy_to_clipboard("copy-on-demand", mp.get_property(subtitle_id))
end

------------------------------------------------------------
-- custom sub filter method

local function apply_custom_sub_filter(text)
local trim_func = h.trim

if custom_sub_filter then
if custom_sub_filter_enabled and custom_sub_filter.preprocess then
text = custom_sub_filter.preprocess(text)
end

if self.config.use_custom_trim and custom_sub_filter.trim then
trim_func = custom_sub_filter.trim
end
end

return text, trim_func
end

------------------------------------------------------------
-- public

Expand All @@ -166,8 +187,11 @@ self.copy_to_clipboard = function(_, text)
end

self.clipboard_prepare = function(text)
local trim_func
text, trim_func = apply_custom_sub_filter(text)

if self.config.clipboard_trim_enabled then
text = h.trim(text)
text = trim_func(text)
else
text = h.remove_newlines(text)
end
Expand Down Expand Up @@ -332,6 +356,28 @@ self.next_autoclip_method = function()
notify_autocopy()
end

local function notify_custom_sub_filter(state)
if not (custom_sub_filter and custom_sub_filter.preprocess) then
return
end

local prefix = self.config.custom_sub_filter_notification

local state_text
if state then
state_text = "ON"
else
state_text = "OFF"
end

h.notify(string.format("%s: %s", prefix, state_text))
end

self.toggle_custom_sub_filter = function()
custom_sub_filter_enabled = not custom_sub_filter_enabled
notify_custom_sub_filter(custom_sub_filter_enabled)
end

self.init = function(menu, config)
self.menu = menu
self.config = config
Expand All @@ -341,6 +387,8 @@ self.init = function(menu, config)
autoclip_enabled = self.config.autoclip
autoclip_method.set(self.config.autoclip_method)

custom_sub_filter_enabled = config.custom_sub_filter_enabled

mp.observe_property("sub-text", "string", handle_primary_sub)
mp.observe_property("secondary-sub-text", "string", handle_secondary_sub)
end
Expand Down