Signed-off-by: mbrucedogs <mbrucedogs@gmail.com>

This commit is contained in:
mbrucedogs 2025-07-28 08:09:47 -05:00
parent 613b64601a
commit c864af7794
3 changed files with 967 additions and 95 deletions

View File

@ -1,81 +0,0 @@
# Changelog
## [v3.4.1] - 2025-01-27
### 🐛 Bug Fixes
- **Fixed --limit parameter behavior**: The `--limit` parameter now correctly applies to the scanning phase, not just the download execution. When using `--limit N`, only the first N songs are scanned against channels, significantly reducing processing time for large songlists.
- **Fixed --limit logging accuracy**: The logging messages now accurately reflect the number of songs that will actually be processed when using `--limit`, rather than showing counts for all songs in the songlist.
- **Resolved import conflicts**: Fixed inconsistencies between different `extract_artist_title` implementations across modules.
### ✨ Enhancements
- **Enhanced fuzzy matching**: Improved `extract_artist_title` function in `fuzzy_matcher.py` to handle multiple video title formats:
- `"Artist - Title"` format: "38 Special - Hold On Loosely"
- `"Title Karaoke | Artist Karaoke Version"` format: "Hold On Loosely Karaoke | 38 Special Karaoke Version"
- `"Title Artist KARAOKE"` format: "Hold On Loosely 38 Special KARAOKE"
- **Consolidated parsing logic**: Removed duplicate `extract_artist_title` implementations and centralized all parsing logic in `fuzzy_matcher.py`
- **Better matching accuracy**: Reduced false negatives for songs with non-standard title formats commonly found on YouTube karaoke channels
### 🔧 Code Quality
- **Eliminated code duplication**: Removed duplicate `extract_artist_title` functions from `id3_utils.py` and `download_planner.py`
- **Single source of truth**: All modules now import `extract_artist_title` from `fuzzy_matcher.py` for consistent behavior
- **Enhanced documentation**: Added comprehensive docstrings and examples to the `extract_artist_title` function
- **Improved maintainability**: Changes to parsing logic now only need to be made in one place
### 📚 Documentation
- **Updated PRD.md**: Added section documenting recent bug fixes and improvements
- **Updated README.md**: Enhanced feature descriptions and added recent improvements section
- **Enhanced code comments**: Added explanatory comments for the --limit fix and import changes
### 🧪 Testing
- **Verified functionality**: Successfully tested the enhanced fuzzy matching with real-world examples
- **Confirmed performance improvements**: Validated that the --limit parameter now works as expected
---
## [v3.4.0] - 2025-01-XX
### ✨ New Features
- **Parallel downloads**: Enable concurrent downloads with `--parallel --workers N` for significantly faster batch downloads (3-5x speedup)
- **Thread-safe operations**: All tracking, caching, and progress operations are thread-safe
- **Automatic retry mechanism**: Failed downloads are automatically retried with reduced concurrency
### 🔧 Improvements
- **New parallel downloader module**: `parallel_downloader.py` provides thread-safe concurrent download management
- **Configurable concurrency**: Use `--parallel` to enable parallel downloads with 3 workers by default, or `--parallel --workers N` for custom worker count (1-10)
- **Real-time progress tracking**: Shows active downloads, completion status, and overall progress
- **Backward compatibility**: Sequential downloads remain the default when `--parallel` is not used
- **Integrated with all modes**: Works with both songlist-across-channels and latest-per-channel download modes
---
## [v3.3.0] - 2025-01-XX
### ✨ New Features
- **Centralized file operations**: `file_utils.py` provides single source of truth for filename handling and file validation
- **Centralized song validation**: `song_validator.py` provides unified logic for checking if songs should be downloaded
- **Enhanced configuration management**: Structured configuration with dataclasses, type safety, and validation
### 🔧 Improvements
- **Eliminated code duplication**: ~150 lines of duplicate code removed across modules
- **Enhanced type safety**: Comprehensive type hints across all new modules
- **Better error handling**: Consistent patterns via centralized utilities
- **Improved maintainability**: Changes to file operations or song validation only require updates in one place
---
## [v3.2.0] - 2025-01-XX
### ✨ New Features
- **Download plan pre-scan**: Before downloading, the tool scans all channels for songlist matches, builds a download plan, and prints stats
- **Latest-per-channel plan**: Download the latest N videos from each channel, with a per-channel plan and robust resume
- **Fast mode with early exit**: When a limit is set, scans channels and songs in order, downloads immediately when a match is found
- **Deduplication across channels**: Tracks unique song keys to ensure the same song is not downloaded from multiple channels
- **Fuzzy matching**: Uses string similarity algorithms to find approximate matches between songlist entries and video titles
- **Default channel file**: Automatically uses data/channels.txt as the default channel list for songlist modes
### 🔧 Improvements
- **Centralized yt-dlp command generation**: Standardized command building and execution across all download operations
- **Enhanced error handling**: Structured exception hierarchy with consistent error messages and formatting
- **Abstracted download pipeline**: Reusable download → verify → tag → track process for consistent processing
- **Optimized scanning algorithm**: High-performance channel scanning with O(n×m) complexity and pre-processed lookups
- **Robust interruption handling**: Progress is saved after each download, preventing re-downloads if the process is interrupted

View File

@ -7038,5 +7038,933 @@
"channel": "songlist",
"marked_at": "2025-07-27T08:04:45.697565",
"reason": "already_on_server"
},
"papa roach_last resort": {
"artist": "Papa Roach",
"title": "Last Resort (Karaoke Version)",
"video_title": "Papa Roach - Last Resort (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.702616",
"reason": "already_on_server"
},
"lewis capaldi_survive": {
"artist": "Lewis Capaldi",
"title": "Survive (Karaoke Version)",
"video_title": "Lewis Capaldi - Survive (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.739703",
"reason": "already_on_server"
},
"the janedear girls_good girls gone bad": {
"artist": "the JaneDear girls",
"title": "Good Girls Gone Bad (Karaoke Version)",
"video_title": "the JaneDear girls - Good Girls Gone Bad (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.759014",
"reason": "already_on_server"
},
"justin bieber_flatline": {
"artist": "Justin Bieber",
"title": "Flatline (Karaoke Version)",
"video_title": "Justin Bieber - Flatline (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.772249",
"reason": "already_on_server"
},
"one direction_another world": {
"artist": "One Direction",
"title": "Another World (Karaoke Version)",
"video_title": "One Direction - Another World (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.792544",
"reason": "already_on_server"
},
"spin the wheel_your song requests week 8": {
"artist": "Spin The Wheel",
"title": "Your Song Requests Week 8",
"video_title": "Spin The Wheel - Your Song Requests Week 8",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.811032",
"reason": "already_on_server"
},
"d4vd, hyunjin_always love": {
"artist": "d4vd, Hyunjin",
"title": "Always Love (Karaoke Version)",
"video_title": "d4vd, Hyunjin - Always Love (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.848225",
"reason": "already_on_server"
},
"adrianne lenker_forwards beckon rebound": {
"artist": "Adrianne Lenker",
"title": "forwards beckon rebound (Karaoke Version)",
"video_title": "Adrianne Lenker - forwards beckon rebound (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.860582",
"reason": "already_on_server"
},
"bailey zimmerman, luke combs_backup plan": {
"artist": "Bailey Zimmerman, Luke Combs",
"title": "Backup Plan (Karaoke Version)",
"video_title": "Bailey Zimmerman, Luke Combs - Backup Plan (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.881985",
"reason": "already_on_server"
},
"bryson tiller_let em' know": {
"artist": "Bryson Tiller",
"title": "Let Em' Know (Karaoke Version)",
"video_title": "Bryson Tiller - Let Em' Know (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.898955",
"reason": "already_on_server"
},
"benson boone_mr electric blue": {
"artist": "Benson Boone",
"title": "Mr Electric Blue (Karaoke Version)",
"video_title": "Benson Boone - Mr Electric Blue (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.917870",
"reason": "already_on_server"
},
"glorilla_typa": {
"artist": "GloRilla",
"title": "Typa (Karaoke Version)",
"video_title": "GloRilla - Typa (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.937983",
"reason": "already_on_server"
},
"cardi b_outside": {
"artist": "Cardi B",
"title": "Outside (Karaoke Version)",
"video_title": "Cardi B - Outside (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.956697",
"reason": "already_on_server"
},
"morgan wallen_skoal, chevy, and browning": {
"artist": "Morgan Wallen",
"title": "Skoal, Chevy, and Browning (Karaoke Version)",
"video_title": "Morgan Wallen - Skoal, Chevy, and Browning (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.972016",
"reason": "already_on_server"
},
"jade_angel of my dreams": {
"artist": "JADE",
"title": "Angel Of My Dreams (Karaoke Version)",
"video_title": "JADE - Angel Of My Dreams (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:55.987385",
"reason": "already_on_server"
},
"karol g_latina foreva": {
"artist": "KAROL G",
"title": "LATINA FOREVA (Karaoke Version)",
"video_title": "KAROL G - LATINA FOREVA (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.001183",
"reason": "already_on_server"
},
"morgan wallen_i got better": {
"artist": "Morgan Wallen",
"title": "I Got Better (Karaoke Version)",
"video_title": "Morgan Wallen - I Got Better (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.018973",
"reason": "already_on_server"
},
"ella langley_weren't for the wind": {
"artist": "Ella Langley",
"title": "weren't for the wind (Karaoke Version)",
"video_title": "Ella Langley - weren't for the wind (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.036665",
"reason": "already_on_server"
},
"shabrina leanor_pendampingmu #tahtahatiku": {
"artist": "Shabrina Leanor",
"title": "Pendampingmu #TahtaHatiku (Karaoke Version)",
"video_title": "Shabrina Leanor - Pendampingmu #TahtaHatiku (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.050522",
"reason": "already_on_server"
},
"elle king_before you met me": {
"artist": "Elle King",
"title": "Before You Met Me (Karaoke Version)",
"video_title": "Elle King - Before You Met Me (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.070722",
"reason": "already_on_server"
},
"lorde_hammer": {
"artist": "Lorde",
"title": "Hammer (Karaoke Version)",
"video_title": "Lorde - Hammer (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.084734",
"reason": "already_on_server"
},
"sean paul_temperature": {
"artist": "Sean Paul",
"title": "Temperature (Karaoke Version)",
"video_title": "Sean Paul - Temperature (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.101490",
"reason": "already_on_server"
},
"karol g_papasito": {
"artist": "KAROL G",
"title": "Papasito (Karaoke Version)",
"video_title": "KAROL G - Papasito (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.118929",
"reason": "already_on_server"
},
"benson boone_before you": {
"artist": "Benson Boone",
"title": "Before You (Karaoke Version)",
"video_title": "Benson Boone - Before You (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.134488",
"reason": "already_on_server"
},
"forrest frank_your way's better": {
"artist": "Forrest Frank",
"title": "YOUR WAY'S BETTER (Karaoke Version)",
"video_title": "Forrest Frank - YOUR WAY'S BETTER (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.150270",
"reason": "already_on_server"
},
"morgan wallen_superman": {
"artist": "Morgan Wallen",
"title": "Superman (Karaoke Version)",
"video_title": "Morgan Wallen - Superman (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.169331",
"reason": "already_on_server"
},
"earl agustin_tibok": {
"artist": "Earl Agustin",
"title": "Tibok (Karaoke Version)",
"video_title": "Earl Agustin - Tibok (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.186227",
"reason": "already_on_server"
},
"prettymuch_eyes off you": {
"artist": "PRETTYMUCH",
"title": "Eyes Off You (Karaoke Version)",
"video_title": "PRETTYMUCH - Eyes Off You (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.201889",
"reason": "already_on_server"
},
"lorde_shapeshifter": {
"artist": "Lorde",
"title": "Shapeshifter (Karaoke Version)",
"video_title": "Lorde - Shapeshifter (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.216119",
"reason": "already_on_server"
},
"keith sweat, athena cage_nobody": {
"artist": "Keith Sweat, Athena Cage",
"title": "Nobody (Karaoke Version)",
"video_title": "Keith Sweat, Athena Cage - Nobody (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.230593",
"reason": "already_on_server"
},
"max, huh yunjin_stupid in love": {
"artist": "MAX, HUH YUNJIN",
"title": "STUPID IN LOVE (Karaoke Version)",
"video_title": "MAX, HUH YUNJIN - STUPID IN LOVE (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.249100",
"reason": "already_on_server"
},
"edward sharpe & the magnetic zeros_home": {
"artist": "Edward Sharpe & The Magnetic Zeros",
"title": "Home (Karaoke Version)",
"video_title": "Edward Sharpe & The Magnetic Zeros - Home (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.261583",
"reason": "already_on_server"
},
"penelope scott_lotta true crime": {
"artist": "Penelope Scott",
"title": "Lotta True Crime (Karaoke Version)",
"video_title": "Penelope Scott - Lotta True Crime (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.277707",
"reason": "already_on_server"
},
"alex g, emily yacina_treehouse": {
"artist": "Alex G, Emily Yacina",
"title": "Treehouse (Karaoke Version)",
"video_title": "Alex G, Emily Yacina - Treehouse (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.296486",
"reason": "already_on_server"
},
"kimya dawson_you love me": {
"artist": "Kimya Dawson",
"title": "You Love Me (Karaoke Version)",
"video_title": "Kimya Dawson - You Love Me (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.311288",
"reason": "already_on_server"
},
"towa bird_boomerang": {
"artist": "Towa Bird",
"title": "Boomerang (Karaoke Version)",
"video_title": "Towa Bird - Boomerang (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.331964",
"reason": "already_on_server"
},
"j-hope, glorilla_killin' it girl": {
"artist": "j-hope, GloRilla",
"title": "Killin' It Girl (Karaoke Version)",
"video_title": "j-hope, GloRilla - Killin' It Girl (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.350172",
"reason": "already_on_server"
},
"tate mcrae_miss possessive": {
"artist": "Tate McRae",
"title": "Miss possessive (Karaoke Version)",
"video_title": "Tate McRae - Miss possessive (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.370252",
"reason": "already_on_server"
},
"katseye_gabriela": {
"artist": "KATSEYE",
"title": "Gabriela (Karaoke Version)",
"video_title": "KATSEYE - Gabriela (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.386727",
"reason": "already_on_server"
},
"justyna steczkowska_gaja - eurovision edit": {
"artist": "Justyna Steczkowska",
"title": "GAJA - Eurovision Edit (Karaoke Version)",
"video_title": "Justyna Steczkowska - GAJA - Eurovision Edit (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.400857",
"reason": "already_on_server"
},
"linkin park_numb": {
"artist": "Linkin Park",
"title": "Numb (Karaoke Version)",
"video_title": "Linkin Park - Numb (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.435790",
"reason": "already_on_server"
},
"morgan wallen_just in case": {
"artist": "Morgan Wallen",
"title": "Just In Case (Karaoke Version)",
"video_title": "Morgan Wallen - Just In Case (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.449757",
"reason": "already_on_server"
},
"don toliver_no pole": {
"artist": "Don Toliver",
"title": "No Pole (Karaoke Version)",
"video_title": "Don Toliver - No Pole (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.477962",
"reason": "already_on_server"
},
"coldplay_sparks": {
"artist": "Coldplay",
"title": "Sparks (Karaoke Version)",
"video_title": "Coldplay - Sparks (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.496124",
"reason": "already_on_server"
},
"ed sheeran_dive": {
"artist": "Ed Sheeran",
"title": "Dive (Karaoke Version)",
"video_title": "Ed Sheeran - Dive (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.518187",
"reason": "already_on_server"
},
"amerie_1 thing": {
"artist": "Amerie",
"title": "1 Thing (Karaoke Version)",
"video_title": "Amerie - 1 Thing (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.544220",
"reason": "already_on_server"
},
"sabrina carpenter_manchild": {
"artist": "Sabrina Carpenter",
"title": "Manchild (Karaoke Version)",
"video_title": "Sabrina Carpenter - Manchild (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.560366",
"reason": "already_on_server"
},
"benson boone_sorry i'm here for someone else": {
"artist": "Benson Boone",
"title": "Sorry I'm Here For Someone Else (Karaoke Version)",
"video_title": "Benson Boone - Sorry I'm Here For Someone Else (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.582352",
"reason": "already_on_server"
},
"the red clay strays_wondering why": {
"artist": "The Red Clay Strays",
"title": "Wondering Why (Karaoke Version)",
"video_title": "The Red Clay Strays - Wondering Why (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.603599",
"reason": "already_on_server"
},
"pinkpantheress_illegal": {
"artist": "PinkPantheress",
"title": "Illegal (Karaoke Version)",
"video_title": "PinkPantheress - Illegal (Karaoke Version)",
"channel": "@SingKingKaraoke",
"marked_at": "2025-07-28T07:58:56.639835",
"reason": "already_on_server"
},
"iggy pop, kate pierson_candy": {
"artist": "Iggy Pop, Kate Pierson",
"title": "Candy (Karaoke)",
"video_title": "Iggy Pop, Kate Pierson - Candy (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.794620",
"reason": "already_on_server"
},
"porter wagoner_eat, drink and be merry (for tomorrow you'll cry)": {
"artist": "Porter Wagoner",
"title": "Eat, Drink And Be Merry (For Tomorrow You'll Cry) (Karaoke)",
"video_title": "Porter Wagoner - Eat, Drink And Be Merry (For Tomorrow You'll Cry) (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.818207",
"reason": "already_on_server"
},
"shocking blue_venus": {
"artist": "Shocking Blue",
"title": "Venus (Karaoke)",
"video_title": "Shocking Blue - Venus (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.838227",
"reason": "already_on_server"
},
"pratt & mcclain_happy days": {
"artist": "Pratt & McClain",
"title": "Happy Days (Karaoke)",
"video_title": "Pratt & McClain - Happy Days (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.853780",
"reason": "already_on_server"
},
"george jones_a picture of me (without you)": {
"artist": "George Jones",
"title": "A Picture Of Me (Without You) (Karaoke)",
"video_title": "George Jones - A Picture Of Me (Without You) (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.871975",
"reason": "already_on_server"
},
"little anthony & the imperials_shimmy shimmy ko-ko-bop": {
"artist": "Little Anthony & The Imperials",
"title": "Shimmy Shimmy Ko-Ko-Bop (Karaoke)",
"video_title": "Little Anthony & The Imperials - Shimmy Shimmy Ko-Ko-Bop (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.890634",
"reason": "already_on_server"
},
"hairspray_i can hear the bells": {
"artist": "Hairspray",
"title": "I Can Hear The Bells (Karaoke)",
"video_title": "Hairspray - I Can Hear The Bells (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.908193",
"reason": "already_on_server"
},
"the beatles_all my loving": {
"artist": "The Beatles",
"title": "All My Loving (Karaoke)",
"video_title": "The Beatles - All My Loving (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.924650",
"reason": "already_on_server"
},
"mccoury brothers_walk out in the rain": {
"artist": "McCoury Brothers",
"title": "Walk Out In The Rain (Karaoke)",
"video_title": "McCoury Brothers - Walk Out In The Rain (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.942100",
"reason": "already_on_server"
},
"anthony smith_john j. blanchard": {
"artist": "Anthony Smith",
"title": "John J. Blanchard (Karaoke)",
"video_title": "Anthony Smith - John J. Blanchard (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.962729",
"reason": "already_on_server"
},
"lykke li_i'm good, i'm gone": {
"artist": "Lykke LI",
"title": "I'm Good, I'm Gone (Karaoke)",
"video_title": "Lykke LI - I'm Good, I'm Gone (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.979197",
"reason": "already_on_server"
},
"tanya tucker_it's only over for you": {
"artist": "Tanya Tucker",
"title": "It's Only Over For You (Karaoke)",
"video_title": "Tanya Tucker - It's Only Over For You (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:56.993614",
"reason": "already_on_server"
},
"avril lavigne_things i'll never say": {
"artist": "Avril Lavigne",
"title": "Things I'll Never Say (Karaoke)",
"video_title": "Avril Lavigne - Things I'll Never Say (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.009292",
"reason": "already_on_server"
},
"aretha franklin, whitney houston_it isn't, it wasn't, it ain't never gonna be": {
"artist": "Aretha Franklin, Whitney Houston",
"title": "It Isn't, It Wasn't, It Ain't Never Gonna Be (Karaoke)",
"video_title": "Aretha Franklin, Whitney Houston - It Isn't, It Wasn't, It Ain't Never Gonna Be (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.026212",
"reason": "already_on_server"
},
"rob thomas_her diamonds": {
"artist": "Rob Thomas",
"title": "Her Diamonds (Karaoke)",
"video_title": "Rob Thomas - Her Diamonds (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.046360",
"reason": "already_on_server"
},
"darius rucker_history in the making": {
"artist": "Darius Rucker",
"title": "History In The Making (Karaoke)",
"video_title": "Darius Rucker - History In The Making (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.070156",
"reason": "already_on_server"
},
"sevyn streeter_it won't stop ft. chris brown": {
"artist": "Sevyn Streeter",
"title": "It Won't Stop (Karaoke) ft. Chris Brown",
"video_title": "Sevyn Streeter - It Won't Stop (Karaoke) ft. Chris Brown",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.092856",
"reason": "already_on_server"
},
"calvin harris_faith": {
"artist": "Calvin Harris",
"title": "Faith (Karaoke)",
"video_title": "Calvin Harris - Faith (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.110808",
"reason": "already_on_server"
},
"glen campbell_i have you": {
"artist": "Glen Campbell",
"title": "I Have You (Karaoke)",
"video_title": "Glen Campbell - I Have You (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.130045",
"reason": "already_on_server"
},
"no doubt_platinum blonde life": {
"artist": "No Doubt",
"title": "Platinum Blonde Life (Karaoke)",
"video_title": "No Doubt - Platinum Blonde Life (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.153720",
"reason": "already_on_server"
},
"def leppard_bringin' on the heartbreak": {
"artist": "Def Leppard",
"title": "Bringin' On The Heartbreak (Karaoke)",
"video_title": "Def Leppard - Bringin' On The Heartbreak (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.241132",
"reason": "already_on_server"
},
"no doubt_rock steady": {
"artist": "No Doubt",
"title": "Rock Steady (Karaoke)",
"video_title": "No Doubt - Rock Steady (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.316066",
"reason": "already_on_server"
},
"calvin harris_outside ft. ellie goulding": {
"artist": "Calvin Harris",
"title": "Outside (Karaoke) ft. Ellie Goulding",
"video_title": "Calvin Harris - Outside (Karaoke) ft. Ellie Goulding",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.379399",
"reason": "already_on_server"
},
"celine dion_my love": {
"artist": "Celine Dion",
"title": "My love (Karaoke)",
"video_title": "Celine Dion - My love (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.471278",
"reason": "already_on_server"
},
"def leppard_two steps behind": {
"artist": "Def Leppard",
"title": "Two Steps Behind (Karaoke)",
"video_title": "Def Leppard - Two Steps Behind (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.496210",
"reason": "already_on_server"
},
"carly simon_all i want is you": {
"artist": "Carly Simon",
"title": "All I Want Is You (Karaoke)",
"video_title": "Carly Simon - All I Want Is You (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.551556",
"reason": "already_on_server"
},
"sugarland_all i want to do": {
"artist": "Sugarland",
"title": "All I Want To Do (Karaoke)",
"video_title": "Sugarland - All I Want To Do (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.576319",
"reason": "already_on_server"
},
"john cougar mellencamp_ain't even done with the night": {
"artist": "John Cougar Mellencamp",
"title": "Ain't Even Done With The Night (Karaoke)",
"video_title": "John Cougar Mellencamp - Ain't Even Done With The Night (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.593743",
"reason": "already_on_server"
},
"p.o.d._thinking about forever": {
"artist": "P.O.D.",
"title": "Thinking About Forever (Karaoke)",
"video_title": "P.O.D. - Thinking About Forever (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.620465",
"reason": "already_on_server"
},
"alive and kicking_tighter, tighter": {
"artist": "Alive And Kicking",
"title": "Tighter, Tighter (Karaoke)",
"video_title": "Alive And Kicking - Tighter, Tighter (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.642482",
"reason": "already_on_server"
},
"george strait_go on": {
"artist": "George Strait",
"title": "Go On (Karaoke)",
"video_title": "George Strait - Go On (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.663741",
"reason": "already_on_server"
},
"songs from grease_those magic changes": {
"artist": "Songs from Grease",
"title": "Those Magic Changes (Karaoke)",
"video_title": "Songs from Grease - Those Magic Changes (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.681115",
"reason": "already_on_server"
},
"songs from you're a good man, charlie brown_snoopy": {
"artist": "Songs from You're A Good Man, Charlie Brown",
"title": "Snoopy (Karaoke)",
"video_title": "Songs from You're A Good Man, Charlie Brown - Snoopy (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.712307",
"reason": "already_on_server"
},
"sammy davis jr._that old black magic": {
"artist": "Sammy Davis Jr.",
"title": "That Old Black Magic (Karaoke)",
"video_title": "Sammy Davis Jr. - That Old Black Magic (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.734019",
"reason": "already_on_server"
},
"marshmello_light it up ft. tyga, chris brown": {
"artist": "Marshmello",
"title": "Light It Up (Karaoke) ft. Tyga, Chris Brown",
"video_title": "Marshmello - Light It Up (Karaoke) ft. Tyga, Chris Brown",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.754034",
"reason": "already_on_server"
},
"mavericks_there goes my heart": {
"artist": "Mavericks",
"title": "There Goes My Heart (Karaoke)",
"video_title": "Mavericks - There Goes My Heart (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.775143",
"reason": "already_on_server"
},
"paul mccartney_spies like us": {
"artist": "Paul McCartney",
"title": "Spies Like Us (Karaoke)",
"video_title": "Paul McCartney - Spies Like Us (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.841216",
"reason": "already_on_server"
},
"pearl jam_the fixer": {
"artist": "Pearl Jam",
"title": "The Fixer (Karaoke)",
"video_title": "Pearl Jam - The Fixer (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.866571",
"reason": "already_on_server"
},
"the chainsmokers_the one": {
"artist": "The Chainsmokers",
"title": "The One (Karaoke)",
"video_title": "The Chainsmokers - The One (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.881464",
"reason": "already_on_server"
},
"ciara_promise": {
"artist": "Ciara",
"title": "Promise (Karaoke)",
"video_title": "Ciara - Promise (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.901895",
"reason": "already_on_server"
},
"michael marcagi_scared to start": {
"artist": "Michael Marcagi",
"title": "Scared To Start (Karaoke)",
"video_title": "Michael Marcagi - Scared To Start (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.936281",
"reason": "already_on_server"
},
"darryl worley_a good day to run": {
"artist": "Darryl Worley",
"title": "A Good Day To Run (Karaoke)",
"video_title": "Darryl Worley - A Good Day To Run (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:57.970763",
"reason": "already_on_server"
},
"chappell roan_pink pony club": {
"artist": "Chappell Roan",
"title": "Pink Pony Club (Karaoke)",
"video_title": "Chappell Roan - Pink Pony Club (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:58.004568",
"reason": "already_on_server"
},
"wings_silly love songs": {
"artist": "Wings",
"title": "Silly Love Songs (Karaoke)",
"video_title": "Wings - Silly Love Songs (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T07:58:58.034106",
"reason": "already_on_server"
},
"chappell roan_the giver": {
"artist": "Chappell Roan",
"title": "The Giver (Karaoke Version)",
"video_title": "Chappell Roan - The Giver (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.146070",
"reason": "already_on_server"
},
"say you love me_fleetwood mac": {
"artist": "Say You Love Me",
"title": "Fleetwood Mac (Karaoke Version)",
"video_title": "Say You Love Me - Fleetwood Mac (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.174775",
"reason": "already_on_server"
},
"jack black_steve's lava chicken from the minecraft movie": {
"artist": "Jack Black",
"title": "Steve's Lava Chicken from The Minecraft Movie (Karaoke Version)",
"video_title": "Jack Black - Steve's Lava Chicken from The Minecraft Movie (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.198548",
"reason": "already_on_server"
},
"shaboozey_good news": {
"artist": "Shaboozey",
"title": "Good News (Karaoke Version)",
"video_title": "Shaboozey - Good News (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.218798",
"reason": "already_on_server"
},
"lola young_messy": {
"artist": "Lola Young",
"title": "Messy (Karaoke Version)",
"video_title": "Lola Young - Messy (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.241921",
"reason": "already_on_server"
},
"gigi perez_sailor song": {
"artist": "Gigi Perez",
"title": "Sailor Song (Karaoke Version)",
"video_title": "Gigi Perez - Sailor Song (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.260320",
"reason": "already_on_server"
},
"lana del rey_diet mountain dew": {
"artist": "Lana Del Rey",
"title": "Diet Mountain Dew (Karaoke Version)",
"video_title": "Lana Del Rey - Diet Mountain Dew (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.303660",
"reason": "already_on_server"
},
"the monkees_i'm a believer": {
"artist": "The Monkees",
"title": "I'm A Believer (Karaoke Version)",
"video_title": "The Monkees - I'm A Believer (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.330491",
"reason": "already_on_server"
},
"the isley brothers_shout": {
"artist": "The Isley Brothers",
"title": "Shout (Karaoke Version)",
"video_title": "The Isley Brothers - Shout (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.355082",
"reason": "already_on_server"
},
"tate mcrae_sports car": {
"artist": "Tate McRae",
"title": "Sports Car (Karaoke Version)",
"video_title": "Tate McRae - Sports Car (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.378170",
"reason": "already_on_server"
},
"jeff buckley_lover, you should've come over": {
"artist": "Jeff Buckley",
"title": "Lover, You Should've Come Over (Karaoke Version)",
"video_title": "Jeff Buckley - Lover, You Should've Come Over (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.392936",
"reason": "already_on_server"
},
"myles smith_stargazing": {
"artist": "Myles Smith",
"title": "Stargazing (Karaoke Version)",
"video_title": "Myles Smith - Stargazing (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.418311",
"reason": "already_on_server"
},
"chris stapleton_think i'm in love with you": {
"artist": "Chris Stapleton",
"title": "Think I'm In Love With You (Karaoke Version)",
"video_title": "Chris Stapleton - Think I'm In Love With You (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.438059",
"reason": "already_on_server"
},
"doechii_anxiety": {
"artist": "Doechii",
"title": "Anxiety (Karaoke Version)",
"video_title": "Doechii - Anxiety (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.461756",
"reason": "already_on_server"
},
"bad bunny_dtmf": {
"artist": "Bad Bunny",
"title": "DtMF (Karaoke Version)",
"video_title": "Bad Bunny - DtMF (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.505853",
"reason": "already_on_server"
},
"lisa_money": {
"artist": "Lisa",
"title": "Money (Karaoke Version)",
"video_title": "Lisa - Money (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.526336",
"reason": "already_on_server"
},
"sabrina carpenter feat. dolly parton_please please please": {
"artist": "Sabrina Carpenter feat. Dolly Parton",
"title": "Please Please Please (Karaoke Version)",
"video_title": "Sabrina Carpenter feat. Dolly Parton - Please Please Please (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.544462",
"reason": "already_on_server"
},
"alex warren_ordinary": {
"artist": "Alex Warren",
"title": "Ordinary (Karaoke Version)",
"video_title": "Alex Warren - Ordinary (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.568441",
"reason": "already_on_server"
},
"lady gaga_abracadabra": {
"artist": "Lady Gaga",
"title": "Abracadabra (Karaoke Version)",
"video_title": "Lady Gaga - Abracadabra (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.605805",
"reason": "already_on_server"
},
"rufus & chaka khan_ain't nobody": {
"artist": "Rufus & Chaka Khan",
"title": "Ain't Nobody (Karaoke Version)",
"video_title": "Rufus & Chaka Khan - Ain't Nobody (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.636001",
"reason": "already_on_server"
},
"gotye feat. kimbra_somebody that i used to know": {
"artist": "Gotye feat. Kimbra",
"title": "Somebody That I Used To Know (Karaoke Version)",
"video_title": "Gotye feat. Kimbra - Somebody That I Used To Know (Karaoke Version)",
"channel": "@StingrayKaraoke",
"marked_at": "2025-07-28T07:58:58.674165",
"reason": "already_on_server"
},
"chappell roan_red wine supernova": {
"artist": "Chappell Roan",
"title": "Red Wine Supernova (Karaoke)",
"video_title": "Chappell Roan - Red Wine Supernova (Karaoke)",
"channel": "@KaraokeOnVEVO",
"marked_at": "2025-07-28T08:08:58.214983",
"reason": "already_on_server"
}
}

View File

@ -16,13 +16,14 @@ DEFAULT_CACHE_DURATION_HOURS = 24
def main():
parser = argparse.ArgumentParser(
description="Karaoke Video Downloader - Download YouTube playlists and channel videos for karaoke",
description="Karaoke Video Downloader - Download YouTube playlists and channel videos for karaoke (default: downloads latest videos from all channels)",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python download_karaoke.py https://www.youtube.com/playlist?list=XYZ
python download_karaoke.py https://www.youtube.com/@SingKingKaraoke/videos
python download_karaoke.py --file data/channels.txt
python download_karaoke.py --limit 10 # Download latest 10 videos from all channels
python download_karaoke.py --songlist-only --limit 10 # Download only songlist songs across channels
python download_karaoke.py https://www.youtube.com/@SingKingKaraoke/videos # Download from specific channel
python download_karaoke.py --file data/channels.txt # Download from custom channel list
python download_karaoke.py --reset-channel SingKingKaraoke --delete-files
""",
)
@ -178,7 +179,7 @@ Examples:
parser.add_argument(
"--latest-per-channel",
action="store_true",
help="Download the latest N videos from each channel (use with --limit)",
help="Download the latest N videos from each channel (use with --limit) [DEPRECATED: This is now the default behavior]",
)
parser.add_argument(
"--fuzzy-match",
@ -445,8 +446,37 @@ Examples:
args.url, force_refresh=args.refresh
)
else:
parser.print_help()
sys.exit(1)
# Default behavior: download from channels (equivalent to --latest-per-channel)
print("🎯 No specific mode specified, defaulting to download from channels")
channel_file = args.file if args.file else "data/channels.txt"
if not os.path.exists(channel_file):
print(f"❌ Channel file not found: {channel_file}")
print("Please provide a channel URL or ensure data/channels.txt exists")
sys.exit(1)
with open(channel_file, "r", encoding="utf-8") as f:
channel_urls = [
line.strip()
for line in f
if line.strip() and not line.strip().startswith("#")
]
limit = args.limit if args.limit else DEFAULT_LATEST_PER_CHANNEL_LIMIT
force_refresh_download_plan = (
args.force_download_plan if hasattr(args, "force_download_plan") else False
)
fuzzy_match = args.fuzzy_match if hasattr(args, "fuzzy_match") else False
fuzzy_threshold = (
args.fuzzy_threshold
if hasattr(args, "fuzzy_threshold")
else DEFAULT_FUZZY_THRESHOLD
)
success = downloader.download_latest_per_channel(
channel_urls,
limit=limit,
force_refresh_download_plan=force_refresh_download_plan,
fuzzy_match=fuzzy_match,
fuzzy_threshold=fuzzy_threshold,
force_download=args.force,
)
# Generate unmatched report if requested (additive feature)
if args.generate_unmatched_report:
@ -560,13 +590,8 @@ Examples:
else:
print("❌ No songlist available for report generation")
# If no download command was specified but generate-unmatched-report was used, exit here
if not any([args.songlist_only, args.songlist_focus, args.latest_per_channel, args.url]):
if args.generate_unmatched_report:
sys.exit(0)
else:
parser.print_help()
sys.exit(1)
# Initialize success variable
success = False
downloader.tracker.force_save()
if success: