{"id":24110219,"url":"https://github.com/egezenn/ytmasc","last_synced_at":"2025-05-13T00:35:31.437Z","repository":{"id":267808808,"uuid":"902420196","full_name":"Egezenn/YTMASC","owner":"Egezenn","description":"Your offline music library with YouTube as it's backend!","archived":false,"fork":false,"pushed_at":"2025-03-25T19:24:29.000Z","size":176,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-04-01T05:11:14.110Z","etag":null,"topics":["conversion","ffmpeg","library","offline","python","synchronization","tagging","webscraping","youtube","youtube-downloader","youtube-music","yt-dlp"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Egezenn.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-12T14:31:15.000Z","updated_at":"2025-03-27T15:58:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"30ffa75f-f08f-49c0-87a6-ab5bc99fa5de","html_url":"https://github.com/Egezenn/YTMASC","commit_stats":null,"previous_names":["egezenn/ytmasc"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Egezenn%2FYTMASC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Egezenn%2FYTMASC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Egezenn%2FYTMASC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Egezenn%2FYTMASC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Egezenn","download_url":"https://codeload.github.com/Egezenn/YTMASC/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253850531,"owners_count":21973662,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["conversion","ffmpeg","library","offline","python","synchronization","tagging","webscraping","youtube","youtube-downloader","youtube-music","yt-dlp"],"created_at":"2025-01-11T01:13:01.308Z","updated_at":"2025-05-13T00:35:31.426Z","avatar_url":"https://github.com/Egezenn.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# YTMASC\r\n\r\n\u003ca href=\"#\"\u003e\u003cimg alt=\"horrible orange triangle\" style=\"padding:16px;\" align=\"left\" src=\"assets/icon.svg\"\u003e\u003c/a\u003e\r\n\r\nYTMASC(**Y**ou**T**ube **M**usic **A**udio **S**craper \u0026 syn**C**hronizer) in a nutshell, aims to get your music library off of YouTube and provide you an offline backup of it along with other maintenance niceties.\r\n\r\nGrab the latest alpha version [here](https://github.com/Egezenn/YTMASC/releases)!\r\n\r\nIt's features are:\r\n\r\n- Automatic downloading, converting and tagging\r\n- CLI (shipped as a binary for Windows!)\r\n- Import a CSV of your own (columns are: *`watch_id`, `artist`, `title`)\r\n- Importing favorites from a [RiMusic](https://github.com/fast4x/RiMusic) database\r\n- Maintaining a data file for your music for an easily reproducible collection\r\n- Scraping your library page from YouTube\r\n- Some helper functions to modify your data file easier and for easy migration\r\n\r\nThe project just keeps expanding as I learn more stuff and want to implement niche things. So it's currently in alpha stages, you may see new features come and go every now and then.\r\n\r\n## CLI Usage Examples\r\n\r\n\u003e Show the help:\r\n\u003e\r\n\u003e `ytmasc` | `ytmasc -h`\r\n\r\n\u003e Run a singular file operation using the fire interface:\r\n\u003e\r\n\u003e `ytmasc --fire download | convert | tag \u003cwatch_id\u003e`\r\n\r\n\u003e Import (Changes in file tags, CSV, RiMusic database export):\r\n\u003e\r\n\u003e `ytmasc --import-from files | path/to/your.csv | path/to/your.db --import-level soft`\r\n\r\n\u003e Import library page\r\n\u003e\r\n\u003e `ytmasc --import-library-page fetch-soft | fetch-soft-no-overwrite | no-fetch-softno-fetch-soft-no-overwrite`\r\n\r\n\u003e Export the library as CSV to the path you specify\r\n\u003e\r\n\u003e `ytmasc --export-to path-of-your-choosing`\r\n\r\n\u003e [!TIP]\r\n\u003e You can chain all these commands in a meaningful manner, see the [flowchart](#flowchart-of-the-cli).\r\n\u003e\r\n\u003e `ytmasc --import-library-page fetch-soft --delete-library-page-files-afterwards --refetch-metadata --import-from rimusic_xxxxxxxxxxxxxx.db --import-from data/x.csv --download --convert --tag --lib-find-same`\r\n\r\n## Side notes\r\n\r\n- You need `ffmpeg` binaries for conversion.\r\n- YouTube blocks API requests if you exceed the amount they classify you as a bot (around 200 requests). You can either use a VPN, proxy or just wait to bypass this. See related `yt-dlp` [issue](https://github.com/yt-dlp/yt-dlp/issues/10128). Currently the download loop breaks and skips to the next task.\r\n- While downloading, some changes may occur in YouTube which results in an error.\r\nYou can use `ytmasc --db-replace-fails` to replace these `watch_id`s to something else.\r\n\r\n### `fetcher.py`\r\n\r\nThis part is a little duct taped, I couldn't find a good way to get the `libraryPage` formerly known as `likesPage` so I just emulated user input. It's written for a Windows computer that has `firefox` or `zen` as the default browser and `file explorer`. Shouldn't be hard to tinker and get it to work for your configuration. You can do this manually too, shouldn't take much of your time.\r\n\r\nChange `resendAmount` based on your internet connection, page length. Rule of thumb is to divide your like amount by 10 for this.\r\n\r\nChange `openingDelay` based on your internet connection.\r\n\r\nChange `savePageAsIndexOnRightClick` to which index your save as is on your browser.\r\n\r\nThe rest is fine if you don't have a really old computer.\r\n\r\n## Requirements to run from source or build\r\n\r\n- `~=python3.11`\r\n- `python3-tk` (Linux)\r\n- `ffmpeg`\r\n\r\n## Flowchart of the CLI\r\n\r\nIn the monstrosity of a flowchart below, you can find the chaining logic for all the arguments. This is in an effort for the user to run seperate commands and do the whole shebang in one fell swoop. Strange results may occur, it's completely up to the user's usage.\r\n\r\n```mermaid\r\ngraph TD;\r\nconvert--\u003eLibrary_tools\r\nconvert--\u003etag\r\ndelete-library-page-files-afterwards---\u003erefetch-metadata\r\ndelete-library-page-files-afterwards--\u003eexport\r\ndelete-library-page-files-afterwards--\u003eTasks\r\ndownload--\u003econvert\r\ndownload--\u003eLibrary_tools\r\ndownload--\u003etag\r\nexport--\u003eTasks\r\nimports--\u003edelete-library-page-files-afterwards\r\nimports--\u003eexport\r\nimports--\u003erefetch-metadata\r\nimports--\u003eTasks\r\nlib-find-same--\u003elib-compare\r\nlib-find-same--\u003elib-find-unpaired\r\nlib-find-same--\u003elib-replace-fails\r\nlib-find-unpaired--\u003elib-compare\r\nlib-find-unpaired--\u003elib-replace-fails\r\nlib-replace-fails--\u003elib-compare\r\nLibrary_operations--\u003eexport\r\nLibrary_operations--\u003eimports\r\nLibrary_operations--\u003eLibrary_tools\r\nLibrary_operations--\u003erefetch-metadata\r\nLibrary_operations--\u003eTasks\r\nLibrary_tools--\u003elib-compare--\u003eFINISH\r\nLibrary_tools--\u003elib-find-same--\u003eFINISH\r\nLibrary_tools--\u003elib-find-unpaired--\u003eFINISH\r\nLibrary_tools--\u003elib-replace-fails--\u003eFINISH\r\nrefetch-metadata--\u003eexport\r\nrefetch-metadata--\u003eTasks\r\nSTART--\u003ehelp--\u003eFINISH\r\nSTART--\u003efire--\u003eFINISH\r\nSTART--\u003eLibrary_operations\r\nSTART--\u003everbosity\r\ntag--\u003eLibrary_tools\r\nTasks--\u003econvert\r\nTasks--\u003edownload\r\nTasks--\u003eLibrary_tools\r\nTasks--\u003etag\r\nverbosity--\u003eLibrary_operations\r\n```\r\n\r\n## Dependencies\r\n\r\n### Binaries\r\n\r\n[Python ~=3.11](https://www.python.org/) - Core language. Licensed under PSFL license.\r\n\r\n[FFmpeg](https://ffmpeg.org/) - Required for the conversion of files. Licensed under LGPLv2.1 license.\r\n\r\n### Python packages\r\n\r\n[beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/) - Used in parsing the user's likes page HTML. Licensed under MIT license.\r\n\r\n[click](https://github.com/pallets/click) - Used in CLI, Licensed under BSD-3-Clause license.\r\n\r\n[eyed3](https://github.com/nicfit/eyeD3) - Used in tagging the files. Licensed under GPL-3.0 license.\r\n\r\n[fire](https://github.com/google/python-fire) - Used in exposing some base functions for a basic CLI. Licensed under Apache-2.0 license.\r\n\r\n[ffmpeg-python](https://github.com/kkroening/ffmpeg-python) - Used in converting files to desired format(s) as a wrapper. Licensed under Apache-2.0 license.\r\n\r\n[mutagen](https://github.com/quodlibet/mutagen)* - Subdependency, planned to replace eyed3. Licensed under GPL-2.0 license.\r\n\r\n[pandas](https://github.com/pandas-dev/pandas) - Used in CSV/JSON helper utilities. Licensed under BSD-3-Clause license.\r\n\r\n[pillow](https://github.com/python-pillow/Pillow) - Used in modification of covers. Licensed under MIT-CMU license.\r\n\r\n[pyautogui](https://github.com/asweigart/pyautogui) - Used in fetcher to get the user's likes page. Licensed under BSD-3-Clause license.\r\n\r\n[pyinstaller](https://github.com/pyinstaller/pyinstaller) - Used in compilation. Licensed under a GPLv2 license.\r\n\r\n[yt-dlp](https://github.com/yt-dlp/yt-dlp) - Used in downloading user's library. Licensed under Unlicense license.\r\n\r\n[ytmusicapi](https://github.com/sigma67/ytmusicapi) - Used in metadata fetching. Licensed under MIT license.\r\n\r\n[fuzzywuzzy](https://github.com/seatgeek/fuzzywuzzy) - Used in comparison utilities for migration for fuzzy matching. Licensed under GPLv2 license.\r\n\r\n[python-levenshtein](https://github.com/rapidfuzz/python-Levenshtein)* - Subdependency for fuzzywuzzy. Licensed under GPL-2.0 license.\r\n\r\n[keyboard](https://github.com/boppreh/keyboard) - Used in comparison utilities for migration to handle keypresses. Licensed under MIT license.\r\n\r\n[prettytable](https://github.com/prettytable/prettytable) - Used in comparison utilities as a part of UX. Licensed under a custom license.\r\n\r\n## Disclaimer\r\n\r\nThis project is not in any way, shape or form affiliated with YouTube, Google or any of their subsidiaries and affiliates.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegezenn%2Fytmasc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegezenn%2Fytmasc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegezenn%2Fytmasc/lists"}