Skip to content

Instantly share code, notes, and snippets.

@d3v-null
Last active March 16, 2022 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d3v-null/ea4e8741237a711f3801c2c4580ddcff to your computer and use it in GitHub Desktop.
Save d3v-null/ea4e8741237a711f3801c2c4580ddcff to your computer and use it in GitHub Desktop.

Just some bash one-liners for using ytmusic

Setup

pip install ytmusicapi pandas tabulate beets

Follow the prompts to store your ytmusic credentials from a python shell

import pandas as pd
from ytmusicapi import YTMusic
YTMusic.setup(filepath='headers_auth.json')
ytmusic = YTMusic('headers_auth.json')

Create youtube-dl config:

cat > youtube-dl-music.ini <<EOF 
--extract-audio
--add-metadata
--embed-thumbnail
--audio-quality 0
--audio-format 'best'
--audio-format mp3
EOF

List playlists

pd.DataFrame(data=ytmusic.get_library_playlists())

Case Insensitive Playlist Search

pd.DataFrame(data=ytmusic.get_library_playlists()).query('title.str.contains("download", case=False)')

Preview playlist contents

in Python:

playlist_id="<whatever>"
pd.DataFrame(data=ytmusic.get_playlist(playlist_id)['tracks'])

in bash:

export playlist_id="<whatever>"
python -c "pd.DataFrame(data=__import__('ytmusicapi').YTMusic('headers_auth.json').get_playlist(${playlist_id})['tracks'])"

Download playlist

python -c "[\
  __import__('subprocess').Popen([\
    'youtube-dl', 
    '--config-location',
    './youtube-dl-music.ini',
    'https://music.youtube.com/watch?v={id}'.format(id=x['videoId']),
    '-o',
    '~/Music/youtube-dl/{artist}/%(release_year)s - {album}/{id} - {artist} - {track}.%(ext)s'.format(\
      id=x.get('videoId'), \
      artist=(x.get('artists') or [{}])[0].get('name','NA').split(',')[0], \
      album=(x.get('album', None) or {}).get('name','NA'),\
      track=x.get('title','NA')\
    )\
  ]).wait() for x in __import__('ytmusicapi').YTMusic('headers_auth.json').get_playlist('${playlist_id}')['tracks']\
]"

another, less readable version:

python -c "print('\n'.join(['\0'.join([x.get('videoId', 'NA'), (x.get('artists') or [{}])[0].get('name','NA').split(',')[0], (x.get('album') or {}).get('name','NA'), x.get('title','NA')]) \
  for x in __import__('ytmusicapi').YTMusic('headers_auth.json').get_playlist('${playlist_id}')['tracks']]))\
" \
  | while IFS= read -r -d '' id \
  && IFS= read -r -d '' artist \ 
  && IFS= read -r -d '' album \
  && read -r track; \
do \
  echo "downloading: id: $id , artist: $artist , album: $album , track: $track";
  youtube-dl --config-location 'youtube-dl-music.ini' "https://music.youtube.com/watch?v=${id}" -o "~/Music/youtube-dl/${artist}/%(release_year)s - ${album}/${id} - ${artist} - ${track}.%(ext)s" ; \
done

Clear Playlist

python -c "ytmusic=__import__('ytmusicapi').YTMusic('headers_auth.json'); \
ytmusic.remove_playlist_items('${playlist_id}', ytmusic.get_playlist('${playlist_id}')['tracks'])"

Get album artwork / medatadata

python -m beets import '~/Music/youtube-dl'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment