MCPcopy Index your code
hub / github.com/KraXen72/shira

github.com/KraXen72/shira @v1.8.5

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.8.5 ↗ · + Follow
101 symbols 337 edges 14 files 39 documented · 39%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

shira

A smart music downloader

Download music from YouTube, YouTube Music and Soundcloud,

with great metadata and little effort.

Installation

You need to have:
- python (3.11+) installed - ffmpeg installed (See Installing ffmpeg) and added to PATH, or specify it with --ffmpeg-location/config

Installation methods: 1. uv (preferred) -> install uv, then run: bash uv tool install shiradl 2. pipx -> install pipx, then run: bash pipx install shiradl 3. local installation with uv (for development) - see Contributing

If you don't want to install shira and just want to try it out / use it once, run uvx shiradl <args>

Updating

If you have previously installed shira, it's important to update it to the last version, otherwise it may not work. - uv: uv tool upgrade shiradl - pipx: pipx upgrade shiradl --pip-args='--upgrade-strategy=eager'

Guides: Using a cookies file, Troubleshooting

Usage Examples

  • shiradl https://music.youtube.com/watch?v=HdX2COsY2Xk YouTube Music
  • shiradl "https://music.youtube.com/watch?v=8YwKlPH93Ps&list=PLC1og_v3eb4jE0bmdkWtizrSQ4zt86-3D"
  • shiradl https://www.youtube.com/watch?v=X0-AvRA7kB0 YouTube (video)
  • shiradl https://soundcloud.com/neffexmusic/fight-back SoundCloud
  • shiradl https://music.youtube.com/playlist?list=PLC1og_v3eb4jE0bmdkWtizrSQ4zt86-3D Album/Playlist
  • shiradl -u ./links.txt List of links to download
  • See all cli options/flags

Goals

  • Provide an easy way to download audio from YouTube Music, YouTube or SoundCloud
  • Instead of a GUI/manual input for some steps like in tiger, shira requires no additional user input once ran.
  • Provide objectively correct or at least very reasonable music metadata & properly tag music files.
  • objectively correct: Shira queries the MusicBrainz Database and YouTube Music's API to get metadata
  • very reasonable: When downloading a Youtube video, tags will be inferred from the video info: title, channel_name, description, upload_date, etc.

Tagging

  • Adds a lot of metadata to music files, in these native tags (m4a, mp3)
  • Embeds proper m4a (iTunes) and .mp3 (ID3v2.4) tags with mediafile
  • Uses YouTube Music's API to get info.
  • Uses MusicBrainz API to resolve MusicBrainz ID's from their api
  • track, album, artist, albumartist ids
    • falls back to artist, albumartist if this recording can't be found, but artist can.
  • Uses my custom smart-metadata system from tiger for non-music videos
  • collects as much information as possible for each tag, and selects the value with most occurrences (with fallbacks)
  • Cleans up messy titles into more reasonable ones:
  • IDOL【ENGLISH EDM COVER】「アイドル」 by ARTIST【Artist1 x @Artist2 】 =>
  • IDOL [ENGLISH EDM COVER] [アイドル] by ARTIST
  • Is smart about turning a video's thumbnail into a square album cover

More info about YouTube thumbnail to Album Art algorithm

  1. samples 4 pixels near the corners of the thumbnail (which is first smoothed and reduced to 64 colors)
  2. decides to crop if average of standard deviations of r, g and b color channels from each sample point is lower than a than a threshold
  3. otherwise pads the image to 1:1 with it's dominant color

About & Credits

Support development

Recurring donation via Liberapay One-time donation via ko-fi.com
Any donations are highly appreciated! <3

Configuration

Shira can be configured using the command line arguments or the config file.
The config file is created automatically when you run shira for the first time at ~/.shiradl/config.json on Linux and %USERPROFILE%\.shiradl\config.json on Windows. Config file values can be overridden using command line arguments.

Command line argument / Config file key Description Default value
-f, --final-path / final_path Path where the downloaded files will be saved. ./YouTube Music
-t, --temp-path / temp_path Path where the temporary files will be saved. ./temp
-c, --cookies-location / cookies_location Location of the cookies file. null
--ffmpeg-location / ffmpeg_location Location of the FFmpeg binary. ffmpeg
--config-location / - Location of the config file. <home folder>/.shiradl/config.json
-i, --itag / itag Itag (audio quality/format). More info 140
--cover-size / cover_size Size of the cover. size >= 0 and <= 16383 1200
--cover-format / cover_format Format of the cover. jpg or png jpg
--cover-quality / cover_quality JPEG quality of the cover. [1<=x<=100] 94
--cover-img / cover_img Path to image or folder of images. More info null
--cover-crop / cover_crop 'crop' takes a 1:1 square from the center, pad always pads top & bottom. auto, crop or pad auto - More info
--template-folder / template_folder Template of the album folders as a format string. {albumartist}/{album}
--template-file / template_file Template of the track files as a format string. {track:02d} {title}
-e, --exclude-tags / exclude_tags List of tags to exclude from file tagging separated by commas without spaces. null
--truncate / truncate Maximum length of the file/folder names. 40
-l, --log-level / log_level Log level. INFO
-s, --save-cover / save_cover Save cover as a separate file. false
-o, --overwrite / overwrite Overwrite existing files. false
-p, --print-exceptions / print_exceptions Print exceptions. false
-u, --url-txt / - Read URLs as location of text files containing URLs. false
-n, --no-config-file / - Don't use the config file. false
-w, --single-folder / - Wrap singles in their own folder instead of placing them directly into artist's folder. false

Itags

The following itags are available: - 140 (128kbps AAC) - default, because it's the result of bestaudio/best on a free account - 141 (256kbps AAC) - use if you have premium alongside --cookies-location - 251 (128kbps Opus) - most stuff will error with Failed to check URL 1/1. Better to use 140

SoundCloud will always download in 128kbps MP3 - SoundCloud also offers OPUS, which is currently not supported. Some people were complaining that the quality is worse
- These are questionable claims at best, but better safe than sorry.

Tag variables

The following variables can be used in the template folder/file and/or in the exclude_tags list:
title, album, artist, albumartist, track, tracktotal, year, date, cover, comments, lyrics, media_type, rating, track, tracktotal, mb_releasetrackid, mb_releasegroupid, mb_artistid, mb_albumartistid
To exclude all musicbrainz tags, you can add mb* to exclude_tags. (This does not work for other types of tags).

Cover formats

Can be either jpg or png.

Cover img

  • Pass in a path to an image file, and it will get used for all of the links you're currently downloading.
  • Pass in a path to a folder, and the script will use the first image matching the track/video id and jpeg/png format
  • You don't have to create covers for all tracks/videos in the playlist/album/etc.
  • SoundCloud will also consider images based on the URL slug instead of id
  • for example: https://soundcloud.com/yatashi-gang-63564467/lovely-bastards-yatashigang => lovely-bastards-yatashigang.jpg / .png

Troubleshooting

  • if shira can't download songs, first try updating; the issue is likely that yt-dlp or something else needs updating
  • In case shira still can't download songs / you're having other issues:
  • If the PyPI version is outdated or broken, you can install directly from git as a workaround:
  • uv: uv tool install git+https://github.com/KraXen72/shira
  • pipx: pipx install git+https://github.com/KraXen72/shira
  • uvx: uvx --from git+https://github.com/KraXen72/shira shiradl <args> (doesn't install, only runs)
  • python: No module named shiradl
  • Make sure you are not already in the shiradl directory, e.g. /shira/shiradl. if yes, move up one directory with cd .. and retry.
  • I really need to run this on python 3.8+ and updating to 3.11+ is not an option
  • run uv add typing-extensions and modify tagging.py accordingly: ```diff
  • from typing import NotRequired, TypedDict
  • from typing_extensions import NotRequired, TypedDict ```

Uninstalling

If you're uninstalling because shira doesn't work, I would like to kindly ask you to please make a GitHub issue about what exactly doesn't work. Thanks!
To uninstall, run the appropriate command. If unsure which way you installed shira, run both.
- uv: uv tool uninstall shiradl - pipx: pipx uninstall shiradl

Installing ffmpeg

Installing ffmpeg with scoop

  • Scoop is a package manager for windows. It allows easy installing of programs and their updating from the command line.
  • Install scoop by running a powershell command (on their website)
  • Run scoop install main/ffmpeg
  • Scoop automatically adds it to path. you can update ffmpeg by doing scoop update and scoop update ffmpeg/*
  • If installing scoop/with scoop is not an option, continue reading:

Installing ffmpeg on Windows (manual install)

Adding ffmpeg to PATH
  • Look for Edit the system environment variables in the Start Menu, launch it.
  • Find the Path user variable, click Edit
  • Click New on the side and enter the path to the ffmpeg\bin folder which has ffmpeg.exe in it, e.g. C:\ffmpeg\bin
  • Click Ok. To verify that ffmpeg is installed, run ffmpeg -version in the terminal.

Pointing to ffmpeg manually

  • If you do not want to add ffmpeg to path, you can point to it manually.
  • Use the config option ffmpeg_location or the cli flag --ffmpeg-location to point to the ffmpeg.exe file.
  • Keep the ffplay.exe and ffprobe.exe files in the same directory.

Installing ffmpeg on linux

  • use your distro's package manager to install ffmpeg -

Setting a cookies file

  • By setting a cookies file, you can download age restricted tracks, private playlists and songs in 256kbps AAC if

Core symbols most depended-on inside this repo

progprint
called by 5
shiradl/util.py
get_ydl_extract_info
called by 4
shiradl/dl.py
get_sanizated_string
called by 4
shiradl/dl.py
smart_tag
called by 4
shiradl/metadata.py
clean_title
called by 4
shiradl/metadata.py
get_mbid_tags
called by 4
shiradl/musicbrainz.py
red_if_none
called by 3
shiradl/mbtag.py
normalized_compare_regex
called by 3
shiradl/musicbrainz.py

Shape

Function 65
Method 31
Class 4
Route 1

Languages

Python100%

Modules by API surface

shiradl/dl.py23 symbols
shiradl/musicbrainz.py19 symbols
tests/metadata.test.py11 symbols
shiradl/metadata.py10 symbols
shiradl/tagging.py8 symbols
shiradl/mbtag.py8 symbols
tests/test_harness.py5 symbols
shiradl/util.py5 symbols
tests/smoke.test.py4 symbols
tests/conftest.py4 symbols
shiradl/cli.py3 symbols
tests/download.test.py1 symbols

For agents

$ claude mcp add shira \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact