Fix subtitle positioning and show existing langs without re-downloading
- Strip yt-dlp's align:start position:0% cue settings from VTT files after both video download and subtitle-only download so CSS ::cue centers them - CC chip now shows already-downloaded langs (e.g. 'CC: en') directly from disk with a '+' button to add more — no YouTube call needed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -384,6 +384,25 @@ def fetch_channel_links(channel_id: str) -> list[str]:
|
||||
return list(channel_ids)
|
||||
|
||||
|
||||
def _strip_vtt_cue_settings(video_id: str) -> None:
|
||||
"""Remove position/align/line cue settings from yt-dlp VTT files.
|
||||
|
||||
yt-dlp embeds 'align:start position:0%' in every cue header which pins
|
||||
subtitles to the bottom-left. Stripping them lets CSS ::cue center them.
|
||||
"""
|
||||
for vtt in Path(settings.download_path).glob(f"{video_id}.*.vtt"):
|
||||
try:
|
||||
text = vtt.read_text(encoding="utf-8", errors="replace")
|
||||
cleaned = re.sub(
|
||||
r'(\d{1,2}:\d{2}:\d{2}\.\d{3} --> \d{1,2}:\d{2}:\d{2}\.\d{3})[^\n]*',
|
||||
r'\1',
|
||||
text,
|
||||
)
|
||||
vtt.write_text(cleaned, encoding="utf-8")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def download_subs_only(video_id: str, subtitle_langs: str) -> bool:
|
||||
"""Download subtitle files only (no video) for an already-downloaded video."""
|
||||
url = f"https://www.youtube.com/watch?v={video_id}"
|
||||
@@ -397,6 +416,8 @@ def download_subs_only(video_id: str, subtitle_langs: str) -> bool:
|
||||
"-o", output_template,
|
||||
*_cookie_args(),
|
||||
], timeout=60)
|
||||
if code == 0:
|
||||
_strip_vtt_cue_settings(video_id)
|
||||
return code == 0
|
||||
|
||||
|
||||
@@ -721,6 +742,7 @@ def start_download(
|
||||
|
||||
process.wait()
|
||||
if process.returncode == 0:
|
||||
_strip_vtt_cue_settings(video_id)
|
||||
resolution = detect_resolution(file_path) if file_path else None
|
||||
on_complete(download_id, file_path, resolution)
|
||||
else:
|
||||
|
||||
@@ -995,15 +995,18 @@ export default function Watch() {
|
||||
)}
|
||||
|
||||
{(() => {
|
||||
// Subs already on disk → show indicator (player CC button handles the rest)
|
||||
// Subs already on disk → show langs + "+" to add more
|
||||
if (subtitleFiles.length > 0 && !subsRequested) return (
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="px-3 py-1.5 rounded-full bg-zinc-800 text-zinc-400 text-xs font-mono">
|
||||
CC: {subtitleFiles.map(s => s.lang).join(", ")}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => setSubsRequested(true)}
|
||||
className="flex items-center gap-1 px-3 py-1.5 rounded-full bg-zinc-800 text-zinc-400 text-xs hover:bg-zinc-700 transition-colors"
|
||||
title="Subtitles loaded — click to add more languages"
|
||||
>
|
||||
CC ✓
|
||||
</button>
|
||||
className="px-2.5 py-1.5 rounded-full text-xs bg-zinc-800 text-zinc-500 hover:bg-zinc-700 transition-colors"
|
||||
title="Add subtitle language"
|
||||
>+</button>
|
||||
</div>
|
||||
);
|
||||
// Not yet asked → show CC chip
|
||||
if (!subsRequested) return (
|
||||
|
||||
Reference in New Issue
Block a user