@@ -254,23 +254,83 @@ mp.add_key_binding(nil, "select-edition", function ()
254254 })
255255end )
256256
257- local function select_subtitle_line (data )
257+ local function select_subtitle_line (data , codec )
258258 local sub_lines = {}
259259 local sub_times = {}
260260 local default_item
261261 local delay = mp .get_property_native (" sub-delay" )
262262 local time_pos = mp .get_property_native (" time-pos" ) - delay
263263 local duration = mp .get_property_native (" duration" , math.huge )
264+ local sub_content = {}
265+
266+ -- Strip HTML and ASS tags and process subtitles
267+ for line in data :gmatch (" [^\n ]+" ) do
268+ -- Clean up tags
269+ local sub_line = line :gsub (" <.->" , " " ) -- Strip HTML tags
270+ :gsub (" \\ h+" , " " ) -- Replace '\h' tag
271+ :gsub (" {[\\ =].-}" , " " ) -- Remove ASS formatting
272+ :gsub (" .-]" , " " , 1 ) -- Remove time info prefix
273+ :gsub (" ^%s*(.-)%s*$" , " %1" ) -- Strip whitespace
274+ :gsub (" ^m%s[mbl%s%-%d%.]+$" , " " ) -- Remove graphics code
275+
276+ if codec == " subrip" or (sub_line ~= " " and sub_line :match (" ^%s+$" ) == nil ) then
277+ local sub_time = line :match (" %d+" ) * 60 + line :match (" :([%d%.]*)" )
278+ local time_seconds = math.floor (sub_time )
279+ sub_content [time_seconds ] = sub_content [time_seconds ] or {}
280+ sub_content [time_seconds ][sub_line ] = true
281+ end
282+ end
283+
284+ -- Process all timestamps and content into selectable subtitle list
285+ for time_seconds , contents in pairs (sub_content ) do
286+ for sub_line in pairs (contents ) do
287+ sub_times [# sub_times + 1 ] = time_seconds
288+ sub_lines [# sub_lines + 1 ] = format_time (time_seconds , duration ) .. " " .. sub_line
289+ end
290+ end
264291
265- -- Strip HTML and ASS tags.
266- for line in data :gsub (" <.->" , " " ):gsub (" {\\ .-}" , " " ):gmatch (" [^\n ]+" ) do
267- -- ffmpeg outputs LRCs with minutes > 60 instead of adding hours.
268- sub_times [# sub_times + 1 ] = line :match (" %d+" ) * 60 + line :match (" :([%d%.]*)" )
269- sub_lines [# sub_lines + 1 ] = format_time (sub_times [# sub_times ], duration ) ..
270- " " .. line :gsub (" .*]" , " " , 1 )
292+ -- Generate time -> subtitle mapping
293+ local time_to_lines = {}
294+ for i = 1 , # sub_times do
295+ local time = sub_times [i ]
296+ local line = sub_lines [i ]
271297
272- if sub_times [# sub_times ] <= time_pos then
273- default_item = # sub_times
298+ if not time_to_lines [time ] then
299+ time_to_lines [time ] = {}
300+ end
301+ table.insert (time_to_lines [time ], line )
302+ end
303+
304+ -- Sort by timestamp
305+ local sorted_sub_times = {}
306+ for i = 1 , # sub_times do
307+ sorted_sub_times [i ] = sub_times [i ]
308+ end
309+ table.sort (sorted_sub_times )
310+
311+ -- Use a helper table to avoid duplicates
312+ local added_times = {}
313+
314+ -- Rebuild sub_lines and sub_times based on the sorted timestamps
315+ local sorted_sub_lines = {}
316+ for _ , sub_time in ipairs (sorted_sub_times ) do
317+ -- Iterate over all subtitle content for this timestamp
318+ if not added_times [sub_time ] then
319+ added_times [sub_time ] = true
320+ for _ , line in ipairs (time_to_lines [sub_time ]) do
321+ table.insert (sorted_sub_lines , line )
322+ end
323+ end
324+ end
325+
326+ -- Use the sorted subtitle list
327+ sub_lines = sorted_sub_lines
328+ sub_times = sorted_sub_times
329+
330+ -- Get the default item (last subtitle before current time position)
331+ for i , sub_time in ipairs (sub_times ) do
332+ if sub_time <= time_pos then
333+ default_item = i
274334 end
275335 end
276336
@@ -334,7 +394,7 @@ mp.add_key_binding(nil, "select-subtitle-line", function ()
334394 return
335395 end
336396
337- select_subtitle_line (result .stdout )
397+ select_subtitle_line (result .stdout , sub . codec )
338398 end )
339399end )
340400
0 commit comments