{"id":13442897,"url":"https://github.com/cooperhammond/irs","last_synced_at":"2025-04-06T10:13:29.126Z","repository":{"id":38984022,"uuid":"62849173","full_name":"cooperhammond/irs","owner":"cooperhammond","description":":guitar: :notes: A music downloader that understands your metadata needs.","archived":false,"fork":false,"pushed_at":"2022-02-23T17:58:49.000Z","size":6733,"stargazers_count":374,"open_issues_count":5,"forks_count":27,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-04-21T16:49:26.091Z","etag":null,"topics":["cli","crystal","crystal-lang","downloader","id3","metadata","mp3","music"],"latest_commit_sha":null,"homepage":"","language":"Crystal","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/cooperhammond.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}},"created_at":"2016-07-08T01:24:46.000Z","updated_at":"2024-04-13T06:15:24.000Z","dependencies_parsed_at":"2022-08-01T07:49:31.429Z","dependency_job_id":null,"html_url":"https://github.com/cooperhammond/irs","commit_stats":null,"previous_names":["kepoorhampond/irs"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cooperhammond%2Firs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cooperhammond%2Firs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cooperhammond%2Firs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cooperhammond%2Firs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cooperhammond","download_url":"https://codeload.github.com/cooperhammond/irs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247441918,"owners_count":20939382,"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":["cli","crystal","crystal-lang","downloader","id3","metadata","mp3","music"],"created_at":"2024-07-31T03:01:52.909Z","updated_at":"2025-04-06T10:13:29.108Z","avatar_url":"https://github.com/cooperhammond.png","language":"Crystal","funding_links":[],"categories":["Crystal"],"sub_categories":[],"readme":"# irs: The Ironic Repositioning System\n\n[![made-with-crystal](https://img.shields.io/badge/Made%20with-Crystal-1f425f.svg?style=flat-square)](https://crystal-lang.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](https://github.com/cooperhammond/irs/blob/master/LICENSE)\n[![Say Thanks](https://img.shields.io/badge/say-thanks-ff69b4.svg?style=flat-square)](https://saythanks.io/to/kepoorh%40gmail.com)\n\n\u003e A music scraper that understands your metadata needs.\n\n`irs` is a command-line application that downloads audio and metadata in order\nto package an mp3 with both. Extensible, the user can download individual \nsongs, entire albums, or playlists from Spotify.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://i.imgur.com/7QTM6rD.png\" height=\"400\" title=\"#1F816D\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\n\n[![forthebadge](https://forthebadge.com/images/badges/compatibility-betamax.svg)](https://forthebadge.com)\n[![forthebadge](https://forthebadge.com/images/badges/ages-18.svg)](https://forthebadge.com)\n[![forthebadge](https://forthebadge.com/images/badges/built-by-codebabes.svg)](https://forthebadge.com)\n\u003c/p\u003e\n\n---\n\n## Table of Contents\n\n- [Usage](#usage)\n    - [Demo](#demo)\n- [Installation](#installation)\n    - [Pre-built](#pre-built)\n    - [From source](#from-source)\n    - [Set up](#setup)\n- [Config](#config)\n- [How it works](#how-it-works)\n- [Contributing](#contributing)\n\n\n## Usage\n\n```\n~ $ irs -h\n\nUsage: irs [--help] [--version] [--install]\n           [-s \u003csong\u003e -a \u003cartist\u003e]\n           [-A \u003calbum\u003e -a \u003cartist\u003e]\n           [-p \u003cplaylist\u003e -a \u003cusername\u003e]\n\nArguments:\n    -h, --help                  Show this help message and exit\n    -v, --version               Show the program version and exit\n    -i, --install               Download binaries to config location\n    -c, --config                Show config file location\n    -a, --artist \u003cartist\u003e       Specify artist name for downloading\n    -s, --song \u003csong\u003e           Specify song name to download\n    -A, --album \u003calbum\u003e         Specify the album name to download\n    -p, --playlist \u003cplaylist\u003e   Specify the playlist name to download\n    -u, --url \u003curl\u003e             Specify the youtube url to download from (for single songs only)\n    -g, --give-url              Specify the youtube url sources while downloading (for albums or playlists only only)\n\nExamples:\n    $ irs --song \"Bohemian Rhapsody\" --artist \"Queen\"\n    # =\u003e downloads the song \"Bohemian Rhapsody\" by \"Queen\"\n    $ irs --album \"Demon Days\" --artist \"Gorillaz\"\n    # =\u003e downloads the album \"Demon Days\" by \"Gorillaz\"\n    $ irs --playlist \"a different drummer\" --artist \"prakkillian\"\n    # =\u003e downloads the playlist \"a different drummer\" by the user prakkillian\n```\n\n### Demo\n\n[![asciicast](https://asciinema.org/a/332793.svg)](https://asciinema.org/a/332793)\n\n## Installation\n\n### Pre-built \n\nJust download the latest release for your platform \n[here](https://github.com/cooperhammond/irs/releases).\n\nNote that the binaries right now have only been tested on WSL. They *should* run on most linux distros, and OS X, but if they don't please make an issue above.\n\n### From Source\n\nIf you're one of those cool people who compiles from source\n\n1. Install crystal-lang \n    ([`https://crystal-lang.org/install/`](https://crystal-lang.org/install/))\n1. Clone it (`git clone https://github.com/cooperhammond/irs`)\n1. CD it (`cd irs`)\n1. Build it (`shards build`)\n\n### Setup\n\n1. Create a `.yaml` config file somewhere on your system (usually `~/.irs/`)\n1. Copy the following into it\n    ```yaml\n    binary_directory: ~/.irs/bin\n    music_directory: ~/Music\n    filename_pattern: \"{track_number} - {title}\"\n    directory_pattern: \"{artist}/{album}\"\n    client_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    client_secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    single_folder_playlist:\n        enabled: true\n        retain_playlist_order: true\n        unify_into_album: false\n    ```\n1. Set the environment variable `IRS_CONFIG_LOCATION` pointing to that file\n1. Go to [`https://developer.spotify.com/dashboard/`](https://developer.spotify.com/dashboard/)\n1. Log in or create an account\n1. Click `CREATE A CLIENT ID`\n1. Enter all necessary info, true or false, continue\n1. Find your client key and client secret\n1. Copy each respectively into the X's in your config file\n1. Run `irs --install` and answer the prompts!\n\nYou should be good to go! Run the file from your command line to get more help on\nusage or keep reading!\n\n# Config\n\nYou may have noticed that there's a config file with more than a few options. \nHere's what they do:\n```yaml\nbinary_directory: ~/.irs/bin\nmusic_directory: ~/Music\nsearch_terms: \"lyrics\"\nfilename_pattern: \"{track_number} - {title}\"\ndirectory_pattern: \"{artist}/{album}\"\nclient_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nclient_secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nsingle_folder_playlist:\n    enabled: true\n    retain_playlist_order: true\n    unify_into_album: false\n```\n - `binary_directory`: a path specifying where the downloaded binaries should\n    be placed\n - `music_directory`: a path specifying where downloaded mp3s should be placed.\n - `search_terms`: additional search terms to plug into youtube, which can be\n    potentially useful for not grabbing erroneous audio.\n - `filename_pattern`: a pattern for the output filename of the mp3\n - `directory_pattern`: a pattern for the folder structure your mp3s are saved in\n - `client_key`: a client key from your spotify API application\n - `client_secret`: a client secret key from your spotify API application\n - `single_folder_playlist/enabled`: if set to true, all mp3s from a downloaded\n    playlist will be placed in the same folder.\n - `single_folder_playlist/retain_playlist_order`: if set to true, the track \n    numbers of the mp3s of the playlist will be overwritten to correspond to\n    their place in the playlist\n - `single_folder_playlist/unify_into_album`: if set to true, will overwrite\n    the album name and album image of the mp3 with the title of your playlist\n    and the image for your playlist respectively\n\n\nIn a pattern following keywords will be replaced:\n\n| Keyword | Replacement | Example |\n| :----: | :----: | :----: |\n| `{artist}` | Artist Name | Queen |\n| `{title}` | Track Title | Bohemian Rhapsody |\n| `{album}` | Album Name | Stone Cold Classics |\n| `{track_number}` | Track Number | 9 |\n| `{total_tracks}` | Total Tracks in Album | 14 |\n| `{disc_number}` | Disc Number | 1 |\n| `{day}` | Release Day | 01 |\n| `{month}` | Release Month | 01 |\n| `{year}` | Release Year | 2006 |\n| `{id}` | Spotify ID | 6l8GvAyoUZwWDgF1e4822w |\n\nBeware OS-restrictions when naming your mp3s.\n\nPattern Examples:\n```yaml\nmusic_directory: ~/Music\nfilename_pattern: \"{track_number} - {title}\"\ndirectory_pattern: \"{artist}/{album}\"\n```\nOutputs: `~/Music/Queen/Stone Cold Classics/9 - Bohemian Rhapsody.mp3`\n\u003cbr\u003e\u003cbr\u003e\n```yaml\nmusic_directory: ~/Music\nfilename_pattern: \"{artist} - {title}\"\ndirectory_pattern: \"\"\n```\nOutputs: `~/Music/Queen - Bohemian Rhapsody.mp3`\n\u003cbr\u003e\u003cbr\u003e\n```yaml\nmusic_directory: ~/Music\nfilename_pattern: \"{track_number} of {total_tracks} - {title}\"\ndirectory_pattern: \"{year}/{artist}/{album}\"\n```\nOutputs: `~/Music/2006/Queen/Stone Cold Classics/9 of 14 - Bohemian Rhapsody.mp3`\n\u003cbr\u003e\u003cbr\u003e\n```yaml\nmusic_directory: ~/Music\nfilename_pattern: \"{track_number}. {title}\"\ndirectory_pattern: \"irs/{artist} - {album}\"\n```\nOutputs: `~/Music/irs/Queen - Stone Cold Classics/9. Bohemian Rhapsody.mp3`\n\u003cbr\u003e\n\n\n## How it works\n\n**At it's core** `irs` downloads individual songs. It does this by interfacing\nwith the Spotify API, grabbing metadata, and then searching Youtube for a video\ncontaining the song's audio. It will download the video using \n[`youtube-dl`](https://github.com/ytdl-org/youtube-dl), extract the audio using\n[`ffmpeg`](https://ffmpeg.org/), and then pack the audio and metadata together\ninto an MP3.\n\nFrom the core, it has been extended to download the index of albums and \nplaylists through the spotify API, and then iteratively use the method above\nfor downloading each song.\n\nIt used to be in python, but\n1. I wasn't a fan of python's limited ability to distribute standalone binaries\n1. It was a charlie foxtrot of code that I made when I was little and I wanted\n    to refine it\n1. `crystal-lang` made some promises and I was interested in seeing how well it\n    did (verdict: if you're building high-level tools you want to run quickly \n    and distribute, it's perfect)\n\n\n## Contributing\n\nAny and all contributions are welcome. If you think of a cool feature, send a \nPR or shoot me an [email](mailto:kepoorh@gmail.com). If you think something \ncould be implemented better, _please_ shoot me an email. If you like what I'm\ndoing here, _pretty please_ shoot me an email.\n\n1. Fork it (\u003chttps://github.com/your-github-user/irs/fork\u003e)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcooperhammond%2Firs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcooperhammond%2Firs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcooperhammond%2Firs/lists"}