feat(youtube_transcript_v2): Add --language/--auto options and unwrap output text
Auto mode prioritizes de/en/tr and falls back to the first available transcript language; a shorter error is shown when the default fetch fails.
This commit is contained in:
@@ -57,6 +57,21 @@ def transcript_to_srt(transcript: list[dict]) -> str:
|
|||||||
return "\n".join(srt_lines)
|
return "\n".join(srt_lines)
|
||||||
|
|
||||||
|
|
||||||
|
PRIORITY_LANGUAGES = ("de", "en", "tr")
|
||||||
|
|
||||||
|
|
||||||
|
def pick_auto_language(transcript_list) -> str:
|
||||||
|
available = {t.language_code: t for t in transcript_list}
|
||||||
|
if not available:
|
||||||
|
raise ValueError("No transcripts available for this video")
|
||||||
|
|
||||||
|
for lang in PRIORITY_LANGUAGES:
|
||||||
|
if lang in available:
|
||||||
|
return lang
|
||||||
|
|
||||||
|
return next(iter(available))
|
||||||
|
|
||||||
|
|
||||||
def parse_args() -> argparse.Namespace:
|
def parse_args() -> argparse.Namespace:
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Fetch YouTube video transcripts",
|
description="Fetch YouTube video transcripts",
|
||||||
@@ -69,6 +84,18 @@ def parse_args() -> argparse.Namespace:
|
|||||||
metavar="FILE_PATH",
|
metavar="FILE_PATH",
|
||||||
help="Save transcript as SRT file to the specified path",
|
help="Save transcript as SRT file to the specified path",
|
||||||
)
|
)
|
||||||
|
lang_group = parser.add_mutually_exclusive_group()
|
||||||
|
lang_group.add_argument(
|
||||||
|
"--language",
|
||||||
|
metavar="LANG",
|
||||||
|
help="Fetch transcript in the given language code (exits with error if unavailable)",
|
||||||
|
)
|
||||||
|
lang_group.add_argument(
|
||||||
|
"--auto",
|
||||||
|
action="store_true",
|
||||||
|
help=f"Auto-pick a language, preferring {', '.join(PRIORITY_LANGUAGES)} in that order, "
|
||||||
|
"then falling back to the first available generated/translated language",
|
||||||
|
)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
@@ -80,14 +107,42 @@ def main() -> None:
|
|||||||
logging.info(f"Fetching transcript for video ID: {video_id}")
|
logging.info(f"Fetching transcript for video ID: {video_id}")
|
||||||
|
|
||||||
ytt_api = YouTubeTranscriptApi()
|
ytt_api = YouTubeTranscriptApi()
|
||||||
transcript = ytt_api.fetch(video_id)
|
|
||||||
|
if args.language:
|
||||||
|
transcript_list = ytt_api.list(video_id)
|
||||||
|
try:
|
||||||
|
chosen = transcript_list.find_transcript([args.language])
|
||||||
|
except Exception:
|
||||||
|
available = ", ".join(sorted(t.language_code for t in transcript_list))
|
||||||
|
logging.error(
|
||||||
|
f"Language '{args.language}' not available. Available languages: {available}"
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
logging.info(f"Using language: {chosen.language_code}")
|
||||||
|
transcript = chosen.fetch()
|
||||||
|
elif args.auto:
|
||||||
|
transcript_list = ytt_api.list(video_id)
|
||||||
|
lang = pick_auto_language(transcript_list)
|
||||||
|
logging.info(f"Auto-selected language: {lang}")
|
||||||
|
transcript = transcript_list.find_transcript([lang]).fetch()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
transcript = ytt_api.fetch(video_id)
|
||||||
|
except Exception:
|
||||||
|
transcript_list = ytt_api.list(video_id)
|
||||||
|
available = ", ".join(sorted(t.language_code for t in transcript_list))
|
||||||
|
logging.error(
|
||||||
|
f"No transcript available in the default language. "
|
||||||
|
f"Available languages: {available}. Use --language or --auto."
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if args.save_srt:
|
if args.save_srt:
|
||||||
srt_content = transcript_to_srt(transcript.to_raw_data())
|
srt_content = transcript_to_srt(transcript.to_raw_data())
|
||||||
args.save_srt.write_text(srt_content)
|
args.save_srt.write_text(srt_content)
|
||||||
logging.info(f"SRT file saved to: {args.save_srt}")
|
logging.info(f"SRT file saved to: {args.save_srt}")
|
||||||
else:
|
else:
|
||||||
text = "\n".join(snippet.text for snippet in transcript)
|
text = " ".join(snippet.text for snippet in transcript)
|
||||||
print(text)
|
print(text)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user