Skip to content
Merged
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
76 changes: 68 additions & 8 deletions player/lua/select.lua
Original file line number Diff line number Diff line change
Expand Up @@ -292,16 +292,76 @@ mp.add_key_binding(nil, "select-subtitle-line", function ()
local delay = mp.get_property_native("sub-delay")
local time_pos = mp.get_property_native("time-pos") - delay
local duration = mp.get_property_native("duration", math.huge)
local sub_content = {}

-- Strip HTML and ASS tags and process subtitles
for line in r.stdout:gmatch("[^\n]+") do
-- Clean up tags
local sub_line = line:gsub("<.->", "") -- Strip HTML tags
:gsub("\\h+", " ") -- Replace '\h' tag
:gsub("{[\\=].-}", "") -- Remove ASS formatting
:gsub(".-]", "", 1) -- Remove time info prefix
:gsub("^%s*(.-)%s*$", "%1") -- Strip whitespace
:gsub("^m%s[mbl%s%-%d%.]+$", "") -- Remove graphics code

if sub.codec == "subrip" or (sub_line ~= "" and sub_line:match("^%s+$") == nil) then
local sub_time = line:match("%d+") * 60 + line:match(":([%d%.]*)")
local time_seconds = math.floor(sub_time)
sub_content[time_seconds] = sub_content[time_seconds] or {}
sub_content[time_seconds][sub_line] = true
end
end

-- Process all timestamps and content into selectable subtitle list
for time_seconds, contents in pairs(sub_content) do
for sub_line in pairs(contents) do
sub_times[#sub_times + 1] = time_seconds
sub_lines[#sub_lines + 1] = format_time(time_seconds, duration) .. " " .. sub_line
end
end

-- Strip HTML and ASS tags.
for line in r.stdout:gsub("<.->", ""):gsub("{\\.-}", ""):gmatch("[^\n]+") do
-- ffmpeg outputs LRCs with minutes > 60 instead of adding hours.
sub_times[#sub_times + 1] = line:match("%d+") * 60 + line:match(":([%d%.]*)")
sub_lines[#sub_lines + 1] = format_time(sub_times[#sub_times], duration) ..
" " .. line:gsub(".*]", "", 1)
-- Generate time -> subtitle mapping
local time_to_lines = {}
for i = 1, #sub_times do
local time = sub_times[i]
local line = sub_lines[i]

if sub_times[#sub_times] <= time_pos then
default_item = #sub_times
if not time_to_lines[time] then
time_to_lines[time] = {}
end
table.insert(time_to_lines[time], line)
end

-- Sort by timestamp
local sorted_sub_times = {}
for i = 1, #sub_times do
sorted_sub_times[i] = sub_times[i]
end
table.sort(sorted_sub_times)

-- Use a helper table to avoid duplicates
local added_times = {}

-- Rebuild sub_lines and sub_times based on the sorted timestamps
local sorted_sub_lines = {}
for _, sub_time in ipairs(sorted_sub_times) do
-- Iterate over all subtitle content for this timestamp
if not added_times[sub_time] then
Comment thread
dyphire marked this conversation as resolved.
added_times[sub_time] = true
for _, line in ipairs(time_to_lines[sub_time]) do
table.insert(sorted_sub_lines, line)
end
end
end

-- Use the sorted subtitle list
sub_lines = sorted_sub_lines
sub_times = sorted_sub_times

-- Get the default item (last subtitle before current time position)
for i, sub_time in ipairs(sub_times) do
if sub_time <= time_pos then
default_item = i
end
end

Expand Down