Skip to main content

Download music from YouTube, YouTube Music and Soundcloud, with great metadata and little effort.

Project description

shira

A smart music downloader

Download music from YouTube, YouTube Music and Soundcloud,
with great metadata and little effort.

Installation

You need to have:

Installation methods:

  1. uv (preferred) -> install uv, then run:
    uv tool install shiradl
    
  2. pipx -> install pipx, then run:
    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

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

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:
    - 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 you are a premium user.
  • You can export your cookies to a file by using this Google Chrome extension or Firefox extension on https://music.youtube.com

Contributing

  • Please report any bugs in Issues. Pull requests are welcome!
  • To contribute, you'll (likely) need a local installation of shira
    • To install the required python version, you can use either:
      • mise: mise install (what I use)
      • uv: uv sync or uv python install 3.12 (you will need uv anyway)
      • Fork this repo
      • Have ffmpeg and uv installed
      • Install dependencies locally with uv sync
      • Make changes (uv run shiradl to test)
      • Open a pull request
  • If you're planning on implementing something big / that changes a lot, it's worth opening an issue about it to discuss it first.
  • Thanks!

Running tests

  • Install dev dependencies: uv sync (includes dev deps automatically)
  • Run all tests: uv run task test (will take a couple of minutes, has to download stuff)
  • There are different types of tests
    • Smoke uv run task test:smoke: Downloads only like 3 songs, checking both resulting file size & metadata
    • Metadata uv run task test:meta: Skips downloading, only checking metadata
    • Download uv run task test:dl: performs real downloads, checking only if the files are large enough
  • To record or refresh inline snapshots run: e.g. uv run pytest tests/metadata.test.py -v --inline-snapshot=review
  • You can append additional pytest args after -- when using the uv run task helpers

Publishing a new release

  1. Bump the version: uv version --bump patch (or minor / major)
  2. Commit the version bump (replace X.Y.Z with the new version):
    git commit -am "chore: bump version to X.Y.Z"
    
  3. Tag and push: uv run task release (see ./scripts/release.sh) This automatically creates a vX.Y.Z git tag and runs git push && git push --tags.
    Pushing the tag triggers the CI workflow, which runs uv build + uv publish to release the new version to PyPI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shiradl-1.8.2.tar.gz (79.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shiradl-1.8.2-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file shiradl-1.8.2.tar.gz.

File metadata

  • Download URL: shiradl-1.8.2.tar.gz
  • Upload date:
  • Size: 79.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for shiradl-1.8.2.tar.gz
Algorithm Hash digest
SHA256 a97e19fdfa126b7b2f62b71624395cb4e9c453783ef36b85c02ae23924d960ec
MD5 712ef961f4b58e0acbf0b58f608d4398
BLAKE2b-256 ac95d23ebab34498298614082e01d3a9c16d6749c0da6ee30550aaa92fbff6ab

See more details on using hashes here.

File details

Details for the file shiradl-1.8.2-py3-none-any.whl.

File metadata

  • Download URL: shiradl-1.8.2-py3-none-any.whl
  • Upload date:
  • Size: 29.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for shiradl-1.8.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0a858c82e85dc1cbf2f0439022bd2eb54325fb2d35e76c49e7bedd83ede52518
MD5 856b47fe40c6675cb044b3bf20384a63
BLAKE2b-256 60122ebb44a14c31e69c788af72d36849679fcf3aba04f6fc58f9ee6e37c50c0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page