@@ -285,128 +285,39 @@ mp.add_key_binding(nil, "select-edition", function ()
285285end )
286286
287287mp .add_key_binding (nil , " select-subtitle-line" , function ()
288- local sub = mp .get_property_native (" current-tracks/ sub" )
288+ local lines = mp .get_property_native (" sub-lines " )
289289
290- if sub == nil then
291- show_warning (" No subtitle is loaded ." )
290+ if not lines then
291+ show_warning (" Subtitle lines could not be retrieved ." )
292292 return
293293 end
294294
295- if sub .external and sub [" external-filename" ]:find (" ^edl://" ) then
296- sub [" external-filename" ] = sub [" external-filename" ]:match (' https?://.*' )
297- or sub [" external-filename" ]
298- end
299-
300- local r = mp .command_native ({
301- _name = " subprocess" ,
302- capture_stdout = true ,
303- args = sub .external
304- and {" ffmpeg" , " -loglevel" , " error" , " -i" , sub [" external-filename" ],
305- " -f" , " lrc" , " -map_metadata" , " -1" , " -fflags" , " +bitexact" , " -" }
306- or {" ffmpeg" , " -loglevel" , " error" , " -i" , mp .get_property (" path" ),
307- " -map" , " s:" .. sub [" id" ] - 1 , " -f" , " lrc" , " -map_metadata" ,
308- " -1" , " -fflags" , " +bitexact" , " -" }
309- })
310-
311- if r .error_string == " init" then
312- show_error (" Failed to extract subtitles: ffmpeg not found." )
313- return
314- elseif r .status ~= 0 then
315- show_error (" Failed to extract subtitles." )
316- return
317- end
318-
319- local sub_lines = {}
320- local sub_times = {}
295+ local items = {}
321296 local default_item
322297 local delay = mp .get_property_native (" sub-delay" )
323298 local time_pos = mp .get_property_native (" time-pos" ) - delay
324299 local duration = mp .get_property_native (" duration" , math.huge )
325- local sub_content = {}
326-
327- -- Strip HTML and ASS tags and process subtitles
328- for line in r .stdout :gmatch (" [^\n ]+" ) do
329- -- Clean up tags
330- local sub_line = line :gsub (" <.->" , " " ) -- Strip HTML tags
331- :gsub (" \\ h+" , " " ) -- Replace '\h' tag
332- :gsub (" {[\\ =].-}" , " " ) -- Remove ASS formatting
333- :gsub (" .-]" , " " , 1 ) -- Remove time info prefix
334- :gsub (" ^%s*(.-)%s*$" , " %1" ) -- Strip whitespace
335- :gsub (" ^m%s[mbl%s%-%d%.]+$" , " " ) -- Remove graphics code
336-
337- if sub .codec == " text" or (sub_line ~= " " and sub_line :match (" ^%s+$" ) == nil ) then
338- local sub_time = line :match (" %d+" ) * 60 + line :match (" :([%d%.]*)" )
339- local time_seconds = math.floor (sub_time )
340- sub_content [time_seconds ] = sub_content [time_seconds ] or {}
341- sub_content [time_seconds ][sub_line ] = true
342- end
343- end
344-
345- -- Process all timestamps and content into selectable subtitle list
346- for time_seconds , contents in pairs (sub_content ) do
347- for sub_line in pairs (contents ) do
348- sub_times [# sub_times + 1 ] = time_seconds
349- sub_lines [# sub_lines + 1 ] = format_time (time_seconds , duration ) .. " " .. sub_line
350- end
351- end
352-
353- -- Generate time -> subtitle mapping
354- local time_to_lines = {}
355- for i = 1 , # sub_times do
356- local time = sub_times [i ]
357- local line = sub_lines [i ]
358300
359- if not time_to_lines [time ] then
360- time_to_lines [time ] = {}
361- end
362- table.insert (time_to_lines [time ], line )
363- end
364-
365- -- Sort by timestamp
366- local sorted_sub_times = {}
367- for i = 1 , # sub_times do
368- sorted_sub_times [i ] = sub_times [i ]
369- end
370- table.sort (sorted_sub_times )
371-
372- -- Use a helper table to avoid duplicates
373- local added_times = {}
374-
375- -- Rebuild sub_lines and sub_times based on the sorted timestamps
376- local sorted_sub_lines = {}
377- for _ , sub_time in ipairs (sorted_sub_times ) do
378- -- Iterate over all subtitle content for this timestamp
379- if not added_times [sub_time ] then
380- added_times [sub_time ] = true
381- for _ , line in ipairs (time_to_lines [sub_time ]) do
382- table.insert (sorted_sub_lines , line )
383- end
384- end
385- end
386-
387- -- Use the sorted subtitle list
388- sub_lines = sorted_sub_lines
389- sub_times = sorted_sub_times
301+ for i , line in ipairs (lines ) do
302+ items [i ] = format_time (line .start , duration ) .. " " .. line .text
390303
391- -- Get the default item (last subtitle before current time position)
392- for i , sub_time in ipairs (sub_times ) do
393- if sub_time <= time_pos then
394- default_item = i
304+ if line .start <= time_pos then
305+ default_item = # items
395306 end
396307 end
397308
398309 input .select ({
399310 prompt = " Select a line to seek to:" ,
400- items = sub_lines ,
311+ items = items ,
401312 default_item = default_item ,
402- submit = function (index )
313+ submit = function (i )
403314 -- Add an offset to seek to the correct line while paused without a
404315 -- video track.
405316 if mp .get_property_native (" current-tracks/video/image" ) ~= false then
406317 delay = delay + 0.1
407318 end
408319
409- mp .commandv (" seek" , sub_times [ index ] + delay , " absolute" )
320+ mp .commandv (" seek" , lines [ i ]. start + delay , " absolute" )
410321 end ,
411322 })
412323end )
0 commit comments