diff --git a/session/ambience_options.md b/session/ambience_options.md index 50572ee..f50e104 100644 --- a/session/ambience_options.md +++ b/session/ambience_options.md @@ -32,6 +32,9 @@ python3 tools/music-fetch.py tavern --replace # Preview without downloading python3 tools/music-fetch.py tavern --dry-run + +# Allow tracks longer than 10 minutes +python3 tools/music-fetch.py tavern --allow-long-songs ``` Sources are recorded in `session/ambience_sources.md` so tracks can be @@ -45,7 +48,7 @@ re-downloaded without keeping audio files in git. | calm | calm_01.ogg | | combat | combat_01.ogg | | dungeon | dungeon_01.ogg, dungeon_02.ogg | -| forest | forest_01.ogg, forest_02.ogg | +| forest | forest_01.ogg | | tavern | tavern_01.ogg | | tension | tension_01.ogg | | town | town_01.ogg | diff --git a/session/ambience_sources.md b/session/ambience_sources.md index 681358f..60989df 100644 --- a/session/ambience_sources.md +++ b/session/ambience_sources.md @@ -5,3 +5,12 @@ re-downloaded without keeping the audio files in git. | File | Ambience | Source | |------|----------|--------| +| calm_01.ogg | calm | https://www.youtube.com/watch?v=7Vc4-FDGBxo | +| combat_01.ogg | combat | https://www.youtube.com/watch?v=zUkuSkXJf_s | +| dungeon_01.ogg | dungeon | https://www.youtube.com/watch?v=Xh9maYRrU4s | +| dungeon_02.ogg | dungeon | https://www.youtube.com/watch?v=MtFKomQfLUg | +| forest_01.ogg | forest | https://www.youtube.com/watch?v=HbefWLz9jwA | +| tavern_01.ogg | tavern | https://www.youtube.com/watch?v=GQzKGrCwFtk | +| tension_01.ogg | tension | https://www.youtube.com/watch?v=KoxxBeH7J3Q | +| town_01.ogg | town | https://www.youtube.com/watch?v=c0zfiRLVpKU | +| wilds_01.ogg | wilds | https://www.youtube.com/watch?v=UXkcbVKxs9k | diff --git a/tools/music-fetch.py b/tools/music-fetch.py index a884280..e84b520 100755 --- a/tools/music-fetch.py +++ b/tools/music-fetch.py @@ -13,6 +13,7 @@ Usage: python3 tools/music-fetch.py tavern --url "https://youtu.be/..." python3 tools/music-fetch.py tavern --replace python3 tools/music-fetch.py tavern --dry-run + python3 tools/music-fetch.py tavern --allow-long-songs """ import argparse @@ -79,9 +80,13 @@ def make_stem(ambience, existing_files): # ── YouTube search / info ───────────────────────────────── def search_videos(query, max_results=20): YoutubeDL = _import_ytdlp() - ydl = YoutubeDL({"quiet": True, "no_warnings": True}) - info = ydl.extract_info(f"ytsearch{max_results}:{query}", download=False) - return info.get("entries", []) + ydl = YoutubeDL({"quiet": True, "no_warnings": True, "ignoreerrors": True}) + try: + info = ydl.extract_info(f"ytsearch{max_results}:{query}", download=False) + except Exception: + return [] + entries = info.get("entries", []) if info else [] + return [e for e in entries if e is not None] def get_video_info(url): @@ -272,6 +277,8 @@ def main(): help="Show what would be fetched without downloading") parser.add_argument("--max-results", type=int, default=20, help="Number of search results to consider (default: 20)") + parser.add_argument("--allow-long-songs", action="store_true", + help="Allow tracks longer than 10 minutes") args = parser.parse_args() name = args.ambience.strip().lower() @@ -310,6 +317,20 @@ def main(): print("No results found.") sys.exit(1) source_desc = f"top {len(candidates)} results for \"{query}\"" + # Filter to short tracks (< 10 min) unless --allow-long-songs + if not args.allow_long_songs: + short = [v for v in candidates if v.get("duration") is not None and v["duration"] <= 660] + if not short: + # Retry with a shorter-focused query + short_query = f"10 minutes {query}" + print(f" no short tracks found, retrying with: \"{short_query}\"") + candidates = search_videos(short_query, args.max_results) + short = [v for v in candidates if v.get("duration") is not None and v["duration"] <= 660] + if short: + candidates = short + if not candidates: + print("All results were longer than 10 minutes. Use --allow-long-songs to include them.") + sys.exit(1) # Pick randomly from the pool video = random.choice(candidates) candidates = [video]