Code Monkey home page Code Monkey logo

spotify_to_ytmusic's Introduction

spotify_to_ytmusic

PyPI Downloads

Ask questions at Discussions

Code coverage

Latest release

Commits since latest release

A simple command line script to clone a Spotify playlist to YouTube Music.

  • Transfer a single Spotify playlist
  • Update a transferred playlist on YouTube Music
  • Transfer all playlists for a Spotify user
  • Remove playlists from YouTube Music

Install

pip install spotify_to_ytmusic

Setup

  1. Generate a new app at https://developer.spotify.com/dashboard
  2. Run
spotify_to_ytmusic setup

For backwards compatibility you can also create your own file and pass it using --file settings.ini.

If you want to transfer private playlists from Spotify (i.e. liked songs), choose "yes" for oAuth authentication, otherwise choose "no". For oAuth authentication you should set http://localhost as redirect URI for your app in Spotify's developer dashboard.

Usage

After you've completed setup, you can simply run the script from the command line using:

spotify_to_ytmusic create <spotifylink>

where <spotifylink> is a link like https://open.spotify.com/playlist/0S0cuX8pnvmF7gA47Eu63M

The script will log its progress and output songs that were not found in YouTube Music to noresults_youtube.txt.

Transfer all playlists of a Spotify user

For migration purposes, it is possible to transfer all public playlists of a user by using the Spotify user's ID (unique username).

spotify_to_ytmusic all <spotifyuserid>

Transfer liked tracks of the Spotify user

You must you oAuth authentication for transferring liked songs.

spotify_to_ytmusic liked

This command will open browser where you should give access to your account (if you haven't done that before). After authorization you will be redirected to localhost, copy link you were redirected to (looks like localhost/?code=...) and paste to command line.

Command line options

There are some additional command line options for setting the playlist name and determining whether it's public or not. To view them, run

spotify_to_ytmusic -h

To view subcommand help, run i.e.

spotify_to_ytmusic setup -h

Available subcommands:

positional arguments:
  {setup,create,update,remove,all}
                        Provide a subcommand
    setup               Set up credentials
    create              Create a new playlist on YouTube Music.
    update              Delete all entries in the provided Google Play Music playlist and update the playlist with entries from the Spotify playlist.
    remove              Remove playlists with specified regex pattern.
    all                 Transfer all public playlists of the specified user (Spotify User ID).

options:
  -h, --help            show this help message and exit

spotify_to_ytmusic's People

Contributors

benthillerkus avatar demesm avatar dottemechy avatar griffobeid avatar lmagasweran-sc avatar mrmbernardi avatar necrolyte2 avatar rolln-dev avatar sigma67 avatar tgrrr avatar webns avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spotify_to_ytmusic's Issues

not able to import from a text file

I am trying to import from a text file and I get the following error:

$ python3 YouTube.py playlist.txt -n TEst -i Test
Could not get Spotify playlist. Please check the playlist link.
Error: IndexError('list index out of range')

This is the file I'm trying to import:

System Olympia - Okay Nature
Towa Tei & Bebel Gilberto - Technova (Many Hands Cherry Blossom Chop Chop)
Beringei - Hearts
Gavsbourg - Domestic Termites Love Rock Music
E. Geddes - Old Pan Version
Androo - Sync Dancehall
Rockers HiFi - More & More (The Hidden Persuader)
Apiento - Things You Do For Love (Machine Mix)
System Olympia ft. P.Nut - Falling In Love
Wajeed - Jeedo Suave
Marvin Gaye - Running From Love (Version 1)
Edits Des Amateurs - Spliff Dub
El Guiri - El Gitano En Nueva York (Radio edit)
Simone - Mebsouta
Bobo & Agony - Soca Taliban (MH BSMNT version)
Angelique Kidjo - Batonga (The Jungle Club Mix)
Ed Longo & The Applied Arts Ensemble - Palm In The Closet
Scan Man - Arabian (inst)
Modern Artifacts - Din Daa Daa
Futura 2000 - Escapades Dub
Bobby Cash Redd - Skate Party People
Modula - Robotic Body Shake (7" mix)
Igor Jadranin - Heavy In Stereo
Local Artist - Dancer
Peter Britto - I Want Your Love
Hector Plimmer - Step (Daz I Kue radio mix)
Emma-Jean Thackray - Movement
Str4ta - Vision9 (Delfonic Rework)
Duke Hugh ft. Renato Paris - Common Ground
Donny Hathaway - Valdez In The Country

Can not setup youtube music

After running the Setup.py I get no firefox request headers:

liviu@streamripper:~/GoogleMusic/spotifyplaylist_to_ytmusic$ python3 Setup.py youtube
Please paste the request headers from Firefox and press Ctrl-D to continue:


And nothing happens ....

Request contains an invalid argument

Trying to transfer any playlist results in this error:

โฏ python3 YouTube.py "https://open.spotify.com/playlist/04TqDTuVBKg9OjPPezjmcE?si=YB7XVWHCTgm4umw-f64IUg"
requested from 100
requested from 200
requested from 300
requested from 400
requested from 500
requested from 600
requested from 700
requested from 800
requested from 900
requested from 1000
requested from 1100
requested from 1200
10 searched
20 searched
30 searched
40 searched
50 searched
60 searched
70 searched
80 searched
90 searched
100 searched
110 searched
120 searched
130 searched
140 searched
150 searched
160 searched
170 searched
180 searched
190 searched
200 searched
210 searched
220 searched
230 searched
240 searched
250 searched
260 searched
270 searched
280 searched
290 searched
300 searched
310 searched
320 searched
330 searched
340 searched
350 searched
360 searched
370 searched
380 searched
390 searched
400 searched
410 searched
420 searched
430 searched
440 searched
450 searched
460 searched
470 searched
480 searched
490 searched
500 searched
510 searched
520 searched
530 searched
540 searched
550 searched
560 searched
570 searched
580 searched
590 searched
600 searched
610 searched
620 searched
630 searched
640 searched
650 searched
660 searched
670 searched
680 searched
690 searched
700 searched
710 searched
720 searched
730 searched
740 searched
750 searched
760 searched
770 searched
780 searched
790 searched
800 searched
810 searched
820 searched
830 searched
840 searched
850 searched
860 searched
870 searched
880 searched

[youtube]
890 searched
900 searched
910 searched
920 searched
930 searched
940 searched
950 searched
960 searched
970 searched
980 searched
990 searched
1000 searched
1010 searched
1020 searched
1030 searched
1040 searched
1050 searched
1060 searched
1070 searched
1080 searched
1090 searched
1100 searched
1110 searched
1120 searched
1130 searched
1140 searched
1150 searched
1160 searched
1170 searched
1180 searched
1190 searched
1200 searched
1210 searched
1220 searched
1230 searched
Traceback (most recent call last):
File "YouTube.py", line 190, in
main()
File "YouTube.py", line 182, in main
playlistId = ytmusic.create_playlist(name, info, 'PUBLIC' if args.public else 'PRIVATE')
File "YouTube.py", line 19, in create_playlist
return self.api.create_playlist(name, info, privacy, video_ids=tracks)
File "/home/scott/.local/lib/python3.8/site-packages/ytmusicapi/mixins/playlists.py", line 145, in create_playlist
response = self._send_request(endpoint, body)
File "/home/scott/.local/lib/python3.8/site-packages/ytmusicapi/ytmusic.py", line 129, in _send_request
raise Exception(message + error)
Exception: Server returned HTTP 400: Bad Request.
Request contains an invalid argument.

I used firefox to copy the headers, also tried with chrome

Spotify authentication doesn't work

Hey, not sure if I'm configuring stuff correctly, but in the Spotify app, I've set the redirect URL to localhost:8080.

When I run spotify_to_ytmusic commands that require Spotify auth, the browser opens first a Spotify login page, and after signing in redirects to a page that says INVALID_CLIENT: Invalid redirect URI.
That page has a URL that looks like this:

https://accounts.spotify.com/authorize?scope=user-library-read&response_type=code&flow_ctx={{a uuid}}%3A{{a unix timestamp}}&redirect_uri=http%3A%2F%2Flocalhost&client_id={{the client id}}

Pasting that URL back into spotify_to_ytmusic does not work:

Could not get Spotify playlist. Please check the playlist link.
 Error: SpotifyOauthError('error: invalid_request, error_description: code must be supplied')
Traceback (most recent call last):
  File "/opt/homebrew/bin/spotify_to_ytmusic", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/spotify_to_ytmusic/main.py", line 86, in main
    args.func(args)
  File "/opt/homebrew/lib/python3.11/site-packages/spotify_to_ytmusic/controllers.py", line 71, in create
    _create_ytmusic(args, playlist, ytmusic)
  File "/opt/homebrew/lib/python3.11/site-packages/spotify_to_ytmusic/controllers.py", line 58, in _create_ytmusic
    name = args.name + date if args.name else playlist["name"] + date
                                              ~~~~~~~~^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

List index out of range for some playlists

Example playlist below. I may try to dig into it a bit later but I've only had two fail so no big deal. Thanks for this tool!

requested from 100
requested from 200
requested from 300
10 searched
20 searched
30 searched
40 searched
50 searched
60 searched
70 searched
80 searched
90 searched
100 searched
110 searched
120 searched
130 searched
140 searched
150 searched
Traceback (most recent call last):
  File "/Users/vincent/Documents/Personal/spotifyplaylist_to_ytmusic/YouTube.py", line 190, in <module>
    main()
  File "/Users/vincent/Documents/Personal/spotifyplaylist_to_ytmusic/YouTube.py", line 181, in main
    videoIds = ytmusic.search_songs(playlist['tracks'])
  File "/Users/vincent/Documents/Personal/spotifyplaylist_to_ytmusic/YouTube.py", line 70, in search_songs
    result = self.api.search(query, ignore_spelling=True)
  File "/usr/local/lib/python3.9/site-packages/ytmusicapi/mixins/browsing.py", line 176, in search
    search_results.extend(self.parser.parse_search_results(results, type))
  File "/usr/local/lib/python3.9/site-packages/ytmusicapi/helpers.py", line 83, in _impl
    return method(self, *method_args, **method_kwargs)
  File "/usr/local/lib/python3.9/site-packages/ytmusicapi/parsers/browsing.py", line 46, in parse_search_results
    search_result['itemCount'] = get_item_text(data, 1,
  File "/usr/local/lib/python3.9/site-packages/ytmusicapi/parsers/utils.py", line 28, in get_item_text
    return column['text']['runs'][run_index]['text']
IndexError: list index out of range

Traceback error no module named spotipy

This is an error i am getting after doing all the steps right
File "C:\Users\User\Downloads\spotifyplaylist_to_ytmusic-master\Youtube.py", line 8, in
from SpotifyExport import Spotify
File "C:\Users\User\Downloads\spotifyplaylist_to_ytmusic-master\SpotifyExport.py", line 1, in
from spotipy.oauth2 import SpotifyClientCredentials
ModuleNotFoundError: No module named 'spotipy'

Error: AttributeError("'Spotify' object has no attribute 'playlist_items'")

Getting this error when no. of tracks > 100:

Spotify tracks: 100/104
Could not get Spotify playlist. Please check the playlist link.
 Error: AttributeError("'Spotify' object has no attribute 'playlist_items'")

Works only when no. of tracks <= 100:

Spotify tracks: 60/60
YouTube tracks: 10/60
YouTube tracks: 20/60
YouTube tracks: 30/60
YouTube tracks: 40/60
YouTube tracks: 50/60
Success: created playlist "<playlist name>"
Spotify tracks: 100/100
YouTube tracks: 10/100
YouTube tracks: 20/100
YouTube tracks: 30/100
YouTube tracks: 40/100
YouTube tracks: 50/100
YouTube tracks: 60/100
YouTube tracks: 70/100
YouTube tracks: 80/100
YouTube tracks: 90/100
Success: created playlist "<playlist name>"

Youtube is broken? Or is it the request?

Im getting the following error when trying to convert a playlist, I've printed the res variable to make it easier.

{'videoId': 'F4NTvcdr4d0', 'title': 'Your Song', 'artist': 'Elisa Mosel', 'duration': 'Piano Dinner Music', 'resultType': 'song'}
Traceback (most recent call last):
  File "YouTube.py", line 163, in <module>
    main()
  File "YouTube.py", line 155, in main
    videoIds = ytmusic.search_songs(playlist['tracks'])
  File "YouTube.py", line 68, in search_songs
    targetSong = self.get_best_fit_song_id(result, song)
  File "YouTube.py", line 29, in get_best_fit_song_id
    duration = int(durationItems[0]) * 60 + int(durationItems[1])
ValueError: invalid literal for int() with base 10: 'Piano Dinner Music'

KeyError: 'album'

If there is no 'album' key in ytm object in get_best_fit_song_id method, there is error in "match.py", line 48:

        # ...
        # add album for songs only
        if ytm["resultType"] == "song" and ytm["album"] is not None:
            scores.append(
                difflib.SequenceMatcher(
                    a=ytm["album"]["name"].lower(), b=spoti["album"].lower()
                ).ratio()
            )
        # ...

Problem occured on song: https://open.spotify.com/track/6CwGUsO3RzRU5Y9IE4Tf1B

Command used: spotify_to_ytmusic liked

ZeroDivisionError: float division by zero

Traceback (most recent call last):
File "YouTube.py", line 190, in
main()
File "YouTube.py", line 182, in main
videoIds = ytmusic.search_songs(playlist['tracks'])
File "YouTube.py", line 74, in search_songs
targetSong = self.get_best_fit_song_id(result, song)
File "YouTube.py", line 32, in get_best_fit_song_id
durationMatch = 1 - abs(duration - song['duration']) * 2 / song['duration']
ZeroDivisionError: float division by zero

Force originals (Disney)

Dear all,

Was wondering if there is a way to force originals e.g disney.
I'm following an awesome Disney playlist on spotify that updates every now and again.
So i want this app to update my youtube playlist every day.

Now it updates just fine, but some of the disney songs are translated to other languages.
So last week i was singing along with with We dont talk about bruno in Mandarin instead of English.
And also the family Madrigal in Thai.

Is there any way to force the language?
Or is there any way you guys could make it possible?

Link to playlist.
https://open.spotify.com/playlist/37i9dQZF1DX8C9xQcOrE6T?si=a4edf239ea87447f

Playlist creation failing silently

Firstly, thanks for spotify_to_ytmusic โค๏ธ

I've used it successfully in the past, but I'm having an issue now. I've configured Spotify and Google via OAuth, and have run with:

$ spotify_to_ytmusic all user-foo

It seems to work, finding YouTube tracks, and creating playlists:

Playlist 2: Rory
Getting Spotify tracks...
Spotify tracks: 14/14
Searching YouTube...
YouTube tracks: 10/14
Success: created playlist 'Rory' at
https://music.youtube.com/playlist?list={'responseContext': {'visitorData': 'REDACTED', 'serviceTrackingParams': [{'service': 'CSI', 'params': [{'key': 'c', 'value': 'WEB_REMIX'}, {'key': 'cver', 'value': '1.20231014.01.00'}, {'key': 'yt_li', 'value': '1'}, {'key': 'CreatePlaylist_rid', 'value': '0x6c2c51d61fc34166'}]}, {'service': 'GFEEDBACK', 'params': [{'key': 'logged_in', 'value': '1'}, {'key': 'e', 'value': '23804281,23858057,23946420,23966208,23983296,23998056,24004644,24007246,24034168,24036948,24077241,24080738,24120820,24135310,24140247,24181174,24186125,24187377,24241378,24255543,24255545,24288664,24290971,24362597,24367579,24371779,24377320,24377598,24377909,24379125,24379354,24379964,24379969,24382552,24385612,24386593,24389127,24389130,24390675,24391689,24428788,24439361,24451319,24458317,24458324,24458329,24458839,24466624,24468724,24485421,24506625,24506784,24515423,24518452,24519102,24520147,24520975,24524098,24526515,24526642,24526772,24526783,24526790,24526799,24526808,24526815,24526823,24528463,24528468,24528477,24528484,24528548,24528557,24528573,24528584,24528642,24528647,24528661,24528664,24529354,24529363,24537200,24542367,24542452,24543277,24546060,24546075,24547939,24548138,24548627,24548629,24548854,24549786,24550285,24559327,24560416,24560687,24561136,24561156,24561210,24563746,24566687,24566937,24569887,24581275,24585758,24585907,24588352,24588590,24632205,24650809,24694842,24696752,24697013,24697068,24698452,39324156,39324942,51003636,51004018,51006181,51009655,51009699,51009781,51009900,51010235,51010680,51010768,51011488,51011713,51012165,51012290,51012331,51014091,51015206,51016856,51018866,51019442,51019560,51019626,51020406,51020570,51021953,51024036,51024077,51024086,51025415,51025833,51026208,51026938,51027796,51027870,51028271,51030101,51030300,51030311,51030435,51030815,51030875,51031412,51032492,51033399,51033577,51033903,51034286,51034519,51034526,51034886,51035244,51035372,51036440,51036735,51037342,51037351,51038399,51040473,51041294,51041335,51042257'}]}, {'service': 'ECATCHER', 'params': [{'key': 'client.version', 'value': '1.20000101'}, {'key': 'client.name', 'value': 'WEB_REMIX'}, {'key': 'client.fexp', 'value': '51037351,24004644,24563746,24561136,39324156,23983296,51014091,24385612,24528548,51016856,51019560,24528584,24519102,24650809,51030311,24077241,24458324,24391689,23804281,24529354,24367579,24458317,24581275,24528642,24390675,24288664,51011488,24255545,24697068,24428788,24696752,24007246,51006181,24379969,51024077,24528664,24537200,24120820,24566937,24371779,51026938,24550285,24560416,24561156,51019626,24548854,24140247,24362597,51010768,24526515,24036948,51010680,51038399,51036440,51037342,51027796,24187377,51032492,24546075,24528557,24389130,24549786,24528463,51041294,51034519,51030435,24135310,24546060,24529363,51042257,24255543,39324942,23946420,51036735,51028271,51025833,51025415,24468724,51010235,24528477,51033577,24524098,24543277,24560687,51024086,24585758,24526823,24186125,24548629,51034526,24466624,24528484,24528573,51031412,24526772,24526815,51012290,51009781,51030815,24569887,24566687,24526808,24547939,23998056,24485421,24526642,24694842,24506625,24034168,51020570,51033903,51018866,24377320,24559327,24379125,24382552,24548138,24585907,51027870,51030300,24698452,51033399,24528468,24632205,24386593,24451319,24542452,51041335,51024036,23858057,51030875,51034886,24588352,24439361,24377909,24379354,51019442,24588590,24548627,24518452,51011713,24458839,24520975,51020406,51040473,24528661,24241378,51026208,24526799,24561210,23966208,24458329,51012331,24528647,51021953,24290971,51009900,51035372,51034286,51009699,24379964,24080738,51003636,51030101,51012165,24520147,24515423,24377598,24506784,24542367,51004018,24697013,51009655,24181174,51015206,24526783,51035244,24526790,24389127'}]}]}, 'actions': [{'clickTrackingParams': 'CAAQ2c0EIhMI78aG5pD1gQMVuftMAh2lqw17', 'channelCreationFormEndpoint': {'channelCreationToken': 'REDACTED', 'source': 'CREATE_PLAYLIST_PRIVACY_DROPDOWN_CHANNEL_CREATION_SOURCE'}}], 'trackingParams': 'CAAQ2c0EIhMI78aG5pD1gQMVuftMAh2lqw17'}

However, I don't see any playlists in my library:

playlists

Any idea what I might be doing wrong?

System details:

  • FreeBSD 13.2-RELEASE-p2
  • Python 3.9.18
  • spotify-to-ytmusic 0.3.0

Tracks that are missing from the YouTube playlist don't appear in the "noresults" file

My Spotify playlist has 1587 tracks. The YouTube playlist created has 1511. However, the "noresults" file only contains 4. I expect there to be 76.

Note: the playlist is named "1587" (the number of tracks) for convenience as I validate the transfer.

$  python YouTube.py https://open.spotify.com/playlist/0yasezcPZp9GvDpiIonDPv 
Spotify tracks: 100/1587
Spotify tracks: 200/1587
Spotify tracks: 300/1587
Spotify tracks: 400/1587
Spotify tracks: 500/1587
Spotify tracks: 600/1587
Spotify tracks: 700/1587
Spotify tracks: 800/1587
Spotify tracks: 900/1587
Spotify tracks: 1000/1587
Spotify tracks: 1100/1587
Spotify tracks: 1200/1587
Spotify tracks: 1300/1587
Spotify tracks: 1400/1587
Spotify tracks: 1500/1587
Spotify tracks: 1587/1587
YouTube tracks: 10/1587
YouTube tracks: 20/1587
YouTube tracks: 30/1587
YouTube tracks: 40/1587
YouTube tracks: 50/1587
YouTube tracks: 60/1587
YouTube tracks: 70/1587
YouTube tracks: 80/1587
YouTube tracks: 90/1587
YouTube tracks: 100/1587
YouTube tracks: 110/1587
YouTube tracks: 120/1587
YouTube tracks: 130/1587
YouTube tracks: 140/1587
YouTube tracks: 150/1587
YouTube tracks: 160/1587
YouTube tracks: 170/1587
YouTube tracks: 180/1587
YouTube tracks: 190/1587
YouTube tracks: 200/1587
YouTube tracks: 210/1587
YouTube tracks: 220/1587
YouTube tracks: 230/1587
YouTube tracks: 240/1587
YouTube tracks: 250/1587
YouTube tracks: 260/1587
YouTube tracks: 270/1587
YouTube tracks: 280/1587
YouTube tracks: 290/1587
YouTube tracks: 300/1587
YouTube tracks: 310/1587
YouTube tracks: 320/1587
YouTube tracks: 330/1587
YouTube tracks: 340/1587
YouTube tracks: 350/1587
YouTube tracks: 360/1587
YouTube tracks: 370/1587
YouTube tracks: 380/1587
YouTube tracks: 390/1587
YouTube tracks: 400/1587
YouTube tracks: 410/1587
YouTube tracks: 420/1587
YouTube tracks: 430/1587
YouTube tracks: 440/1587
YouTube tracks: 450/1587
YouTube tracks: 460/1587
YouTube tracks: 470/1587
YouTube tracks: 480/1587
YouTube tracks: 490/1587
YouTube tracks: 500/1587
YouTube tracks: 510/1587
YouTube tracks: 520/1587
YouTube tracks: 530/1587
YouTube tracks: 540/1587
YouTube tracks: 550/1587
YouTube tracks: 560/1587
YouTube tracks: 570/1587
YouTube tracks: 580/1587
YouTube tracks: 590/1587
YouTube tracks: 600/1587
YouTube tracks: 610/1587
YouTube tracks: 620/1587
YouTube tracks: 630/1587
YouTube tracks: 640/1587
YouTube tracks: 650/1587
YouTube tracks: 660/1587
YouTube tracks: 670/1587
YouTube tracks: 680/1587
YouTube tracks: 690/1587
YouTube tracks: 700/1587
YouTube tracks: 710/1587
YouTube tracks: 720/1587
YouTube tracks: 730/1587
YouTube tracks: 740/1587
YouTube tracks: 750/1587
YouTube tracks: 760/1587
YouTube tracks: 770/1587
YouTube tracks: 780/1587
YouTube tracks: 790/1587
YouTube tracks: 800/1587
YouTube tracks: 810/1587
YouTube tracks: 820/1587
YouTube tracks: 830/1587
YouTube tracks: 840/1587
YouTube tracks: 850/1587
YouTube tracks: 860/1587
YouTube tracks: 870/1587
YouTube tracks: 880/1587
YouTube tracks: 890/1587
YouTube tracks: 900/1587
YouTube tracks: 910/1587
YouTube tracks: 920/1587
YouTube tracks: 930/1587
YouTube tracks: 940/1587
YouTube tracks: 950/1587
YouTube tracks: 960/1587
YouTube tracks: 970/1587
YouTube tracks: 980/1587
YouTube tracks: 990/1587
YouTube tracks: 1000/1587
YouTube tracks: 1010/1587
YouTube tracks: 1020/1587
YouTube tracks: 1030/1587
YouTube tracks: 1040/1587
YouTube tracks: 1050/1587
YouTube tracks: 1060/1587
YouTube tracks: 1070/1587
YouTube tracks: 1080/1587
YouTube tracks: 1090/1587
YouTube tracks: 1100/1587
YouTube tracks: 1110/1587
YouTube tracks: 1120/1587
YouTube tracks: 1130/1587
YouTube tracks: 1140/1587
YouTube tracks: 1150/1587
YouTube tracks: 1160/1587
YouTube tracks: 1170/1587
YouTube tracks: 1180/1587
YouTube tracks: 1190/1587
YouTube tracks: 1200/1587
YouTube tracks: 1210/1587
YouTube tracks: 1220/1587
YouTube tracks: 1230/1587
YouTube tracks: 1240/1587
YouTube tracks: 1250/1587
YouTube tracks: 1260/1587
YouTube tracks: 1270/1587
YouTube tracks: 1280/1587
YouTube tracks: 1290/1587
YouTube tracks: 1300/1587
YouTube tracks: 1310/1587
YouTube tracks: 1320/1587
YouTube tracks: 1330/1587
YouTube tracks: 1340/1587
YouTube tracks: 1350/1587
YouTube tracks: 1360/1587
YouTube tracks: 1370/1587
YouTube tracks: 1380/1587
YouTube tracks: 1390/1587
YouTube tracks: 1400/1587
YouTube tracks: 1410/1587
YouTube tracks: 1420/1587
YouTube tracks: 1430/1587
YouTube tracks: 1440/1587
YouTube tracks: 1450/1587
YouTube tracks: 1460/1587
YouTube tracks: 1470/1587
YouTube tracks: 1480/1587
YouTube tracks: 1490/1587
YouTube tracks: 1500/1587
YouTube tracks: 1510/1587
YouTube tracks: 1520/1587
YouTube tracks: 1530/1587
YouTube tracks: 1540/1587
YouTube tracks: 1550/1587
YouTube tracks: 1560/1587
YouTube tracks: 1570/1587
YouTube tracks: 1580/1587
Success: created playlist "1587"
https://music.youtube.com/playlist?list=PLxaUaA1nFpS1wfV9how_CgCBPCSy8AdHE

$ wc -l noresults_youtube.txt 
4 noresults_youtube.txt

$ cat noresults_youtube.txt 
Essโˆšยฐy Lyla
Crisopa Kit De Crein North Left - Kit De Crein Remix
Syntaks Shiftandshade Ahead
Off The Sky Agonic Drift

Backend Error

I try to copy playlist with this command:
python GoogleMusic.py https://open.spotify.com/playlist/0KZ5DVqPok9qxPC7dxNdJO\?si\=BZ9bsyYyQLyC9z0y1ApH1g

I got the fallowing error:

Traceback (most recent call last):
  File "/Users/stephane/CODE/spotifyplaylist_to_gmusic/mac/lib/python3.8/site-packages/gmusicapi/protocol/shared.py", line 216, in perform
    response.raise_for_status()
  File "/Users/stephane/CODE/spotifyplaylist_to_gmusic/mac/lib/python3.8/site-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: https://mclients.googleapis.com/sj/v2.5/playlistbatch?alt=json&hl=en_US&dv=0&tier=fr

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "GoogleMusic.py", line 148, in <module>
    main()
  File "GoogleMusic.py", line 144, in main
    gmusic.createPlaylist(name, info, playlist['tracks'], args.public)
  File "GoogleMusic.py", line 22, in createPlaylist
    playlistId = self.api.create_playlist(name=name, description=description, public=public)
  File "/Users/stephane/CODE/spotifyplaylist_to_gmusic/mac/lib/python3.8/site-packages/gmusicapi/clients/mobileclient.py", line 533, in create_playlist
    res = self._make_call(mutate_call, add_mutations)
  File "/Users/stephane/CODE/spotifyplaylist_to_gmusic/mac/lib/python3.8/site-packages/gmusicapi/clients/mobileclient.py", line 43, in _make_call
    return super()._make_call(protocol, *args, **kwargs)
  File "/Users/stephane/CODE/spotifyplaylist_to_gmusic/mac/lib/python3.8/site-packages/gmusicapi/clients/shared.py", line 83, in _make_call
    return protocol.perform(self.session, self.validate, *args, **kwargs)
  File "/Users/stephane/CODE/spotifyplaylist_to_gmusic/mac/lib/python3.8/site-packages/gmusicapi/protocol/shared.py", line 224, in perform
    raise CallFailure(err_msg, call_name)
gmusicapi.exceptions.CallFailure: BatchMutatePlaylists: 500 Server Error: Internal Server Error for url: https://mclients.googleapis.com/sj/v2.5/playlistbatch?alt=json&hl=en_US&dv=0&tier=fr
(requests kwargs: {'method': 'POST', 'url': 'https://mclients.googleapis.com/sj/v2.5/playlistbatch', 'data': '{"mutations": [{"create": {"creationTimestamp": "-1", "deleted": false, "lastModifiedTimestamp": "0", "name": "Playlist 1", "description": "", "type": "USER_GENERATED", "shareState": "PRIVATE"}}]}', 'headers': {'Content-Type': 'application/json', 'Authorization': '<omitted>'}, 'params': {'alt': 'json', 'hl': 'en_US', 'dv': 0, 'tier': 'fr'}})
(response was: '{"error":{"errors":[{"domain":"global","reason":"backendError","message":"Backend Error"}],"code":500,"message":"Backend Error"}}')

When I try to copy all playlist from username I got the fallowing error for each playlist:
Could not transfer playlist
And certains playlist are not show in the list.

Update playlists without deletion

Hi,

First thanks for your work this is a vert interesting and usefull project.
This is not an issue but more a question on how to modify the code to update a existing playlist without delete all the songs before.

I try to comment the line 178 remove_songs but it doesn't transfert songs anymore.
Do you know why it doesn't transfert songs or do you have suggestions on what to modify to be able to do that ?

Thanks,
Pierre

Exception: Server returned HTTP 400: Bad Request.

Hello, people. This happens to me when I'm moving a playlist from Spotify to Youtube Music. Is there any solution?

Traceback (most recent call last):
File "", line 198, in _run_module_as_main
File "", line 88, in run_code
File "C:\Users\varga\AppData\Local\Programs\Python\Python312\Scripts\spotify_to_ytmusic.exe_main
.py", line 7, in
File "C:\Users\varga\AppData\Local\Programs\Python\Python312\Lib\site-packages\spotify_to_ytmusic\main.py", line 86, in main
args.func(args)
File "C:\Users\varga\AppData\Local\Programs\Python\Python312\Lib\site-packages\spotify_to_ytmusic\controllers.py", line 71, in create
_create_ytmusic(args, playlist, ytmusic)
File "C:\Users\varga\AppData\Local\Programs\Python\Python312\Lib\site-packages\spotify_to_ytmusic\controllers.py", line 62, in _create_ytmusic
playlistId = ytmusic.create_playlist(
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\varga\AppData\Local\Programs\Python\Python312\Lib\site-packages\spotify_to_ytmusic\ytmusic.py", line 21, in create_playlist
return self.api.create_playlist(name, info, privacy, video_ids=tracks)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\varga\AppData\Local\Programs\Python\Python312\Lib\site-packages\ytmusicapi\mixins\playlists.py", line 226, in create_playlist
response = self._send_request(endpoint, body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\varga\AppData\Local\Programs\Python\Python312\Lib\site-packages\ytmusicapi\ytmusic.py", line 156, in _send_request
raise Exception(message + error)
Exception: Server returned HTTP 400: Bad Request.
Request contains an invalid argument.

Cache conversions

I'm trying to transfer a playlist of 1792 songs from spotify to youtube. On my first attempt I got 920/1792 converted before encountering this error:

Could not transfer playlist 1792. ExceptionHTTPSConnectionPool(host='music.youtube.com', port=443): Read timed out. (read timeout=30)

I go to retry the command and this time I get to 460 songs before I get a similar read timeout error.

If the program would cache the conversions it's already made, I would be able to keep running this command until it converts all the songs and completes successfully, but without this it's up to chance as it starts from the beginning every time.

How to keep YT - Spotify in sync?

Some ideas:

maybe there could be a --all --exportonly flag,
this should just download the playlists to a sub directory.

I think there should be an import from file/directory method also, which takes the folder names as name inputs but I will add that later (WIll make a pr)

Spotify authentication doesn't work

Hi, Iโ€™m trying to run the setup, but keep giving me this message error
Some details: Python version (Python 3.10.9), Pip version (22.3.1), Windows 10 (10.0.19045)
The redirect URI in my app in Spotify's developer dashboard is set as: http://localhost
The message error:

spotify_to_ytmusic setup
Traceback (most recent call last):
File "C:\Users\caiom\AppData\Local\miniconda3\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\caiom\AppData\Local\miniconda3\lib\runpy.py", line 86, in run_code
exec(code, run_globals)
File "C:\Users\caiom\AppData\Local\miniconda3\Scripts\spotify_to_ytmusic.exe_main
.py", line 4, in
File "C:\Users\caiom\AppData\Local\miniconda3\lib\site-packages\spotify_to_ytmusic\main.py", line 4, in
from spotify_to_ytmusic import controllers
File "C:\Users\caiom\AppData\Local\miniconda3\lib\site-packages\spotify_to_ytmusic\controllers.py", line 6, in
from spotify_to_ytmusic.setup import setup as setup_func
File "C:\Users\caiom\AppData\Local\miniconda3\lib\site-packages\spotify_to_ytmusic\setup.py", line 9, in
from spotify_to_ytmusic.settings import DEFAULT_PATH, EXAMPLE_PATH, Settings
File "C:\Users\caiom\AppData\Local\miniconda3\lib\site-packages\spotify_to_ytmusic\settings.py", line 10, in
platformdirs.user_cache_dir(appname="spotify_to_ytmusic", appauthor=False, ensure_exists=True)
TypeError: user_cache_dir() got an unexpected keyword argument 'ensure_exists'

Support for Liked Songs

Library is great, but doesn't support user's liked Songs. This is because it's currently using the Client Credentials Flow. Turns out you can support user's liked songs with only a few extra steps.

I'll outline here and try put together a PR sometime, it just requires a few changes.

  • Add http://localhost as a redirect URL on Spotify
  • Swap out SpotifyClientCredentials for SpotifyOAuth(client_id=conf['client_id'], client_secret=conf['client_secret'], scope="user-library-read", redirect_uri="http://localhost")
  • When you login, it'll open a browser, ask the user to sign in, then you copy the URL back into console
  • Make a new func like this:
def getSpotifyLikedTracks(self):

        results = []
        playlists = self.api.current_user_saved_tracks(20)
        while playlists:
            for i, playlist in enumerate(playlists['items']):

                result = build_result(playlist);

                results.append(result)

            if playlists['next']:
                playlists = self.api.next(playlists)
            else:
                playlists = None

        return results

Splitting out build_results into:

def build_results(tracks, album=None):
    results = []
    for track in tracks:

        result = build_result(track, album)

        if result is not None:
            results.append(result)

    return results

def build_result(track, album=None):
    if 'track' in track:
        track = track['track']
    
    album_name = album if album else track['album']['name']

    return {
        'artist': ' '.join([artist['name'] for artist in track['artists']]),
        'name': track['name'],
        'album': album_name,
        'duration': track['duration_ms']/1000
    }

And then have a func somewhere in main doing the following:

tracks = Spotify().getSpotifyLikedTracks()
videoIds = ytmusic.search_songs(tracks)
playlist_id = ytmusic.create_playlist("Liked Music", "Liked Music", "PRIVATE", videoIds)

App doesn`t boot

spotify_to_ytmusic : The term 'spotify_to_ytmusic' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try a
gain.
At line:1 char:1

  • spotify_to_ytmusic setup
  •   + CategoryInfo          : ObjectNotFound: (spotify_to_ytmusic:String) [], CommandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException
    

YouTube.py - Support brand accounts

Is there a way to utilize ytmusicapi's ability to use brand accounts?

I thought I was having problems creating playlists in youtube but found that they created them in my main account. Thanks for any info.

Issue with installing ytmusicapi

When I run the command: pip install spotify_to_ytmusic, I get the error:

ERROR: Could not install packages due to an OSError: [WinError 2] The system cannot find the file specified: 'C:\\Python311\\Scripts\\ytmusicapi.exe' -> 'C:\\Python311\\Scripts\\ytmusicapi.exe.deleteme'

Thus, I can't run the command spotify_to_ytmusic.

KeyError: 'google' during setup

Traceback (most recent call last):
File "Setup.py", line 8, in
settings['google']['mobileclient'] = api.perform_oauth(open_browser=True).to_json()
File "/mnt/c/Users/kyled/Documents/spotifyplaylist_to_gmusic/settings.py", line 14, in getitem
return config[key]
File "/usr/lib/python3.6/configparser.py", line 959, in getitem
raise KeyError(key)
KeyError: 'google'

Unable to export Spotify Playlist to YouTube Music

Hello

I've tried a few different playlist URLs and keep getting the following error. Is someone able to advise on what's wrong, please? Using Termux on Android 11

Traceback (most recent call last):
File "/data/data/com.termux/files/home/spotifyplaylist_to_ytmusic/YouTube.py", line 190, in
main()
File "/data/data/com.termux/files/home/spotifyplaylist_to_ytmusic/YouTube.py", line 183, in main
ytmusic.add_playlist_items(playlistId, videoIds)
File "/data/data/com.termux/files/home/spotifyplaylist_to_ytmusic/YouTube.py", line 91, in add_playlist_items
self.api.add_playlist_items(playlistId, videoIds)
File "/data/data/com.termux/files/usr/lib/python3.10/site-packages/ytmusicapi/mixins/playlists.py", line 297, in add_playlist_items
raise Exception(
Exception: You must provide either videoIds or a source_playlist to add to the playlist

Possible ZeroDivisionError in YouTube.py durationMatch

Hi,

I just encountered a ZeroDivisionError in YouTube.py line32 while calculating durationMatch. Therefore I suggest following fix:

  if song['duration'] > 0:
      durationMatch = 1 - abs(duration - song['duration']) * 2 / song['duration']

Youtube headers make no sense

The settings.ini file requests a JSON request header, however this is not available as a Copy option. When converting to a JSON format, it then passes them into the YTAPI which expects \n characters. Can you provide an example of what a complete settings.ini file should look like?

Requests from referer https://www.youtube.com are blocked

After following every step of the Readme instructions, I get

Spotify tracks: 4/4
Traceback (most recent call last):
  File "C:\Users\phara\git\spotifyplaylist_to_ytmusic\YouTube.py", line 191, in <module>
    main()
  File "C:\Users\phara\git\spotifyplaylist_to_ytmusic\YouTube.py", line 182, in main
    videoIds = ytmusic.search_songs(playlist['tracks'])
  File "C:\Users\phara\git\spotifyplaylist_to_ytmusic\YouTube.py", line 70, in search_songs
    result = self.api.search(query, ignore_spelling=True)
  File "C:\Users\phara\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\ytmusicapi\mixins\browsing.py", line 135, in search
    response = self._send_request(endpoint, body)
  File "C:\Users\phara\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\ytmusicapi\ytmusic.py", line 133, in _send_request
    raise Exception(message + error)
Exception: Server returned HTTP 403: Forbidden.
Requests from referer https://www.youtube.com are blocked

Is there something more to do to avoid the Forbidden error message?

AttributeError: 'NoneType' object has no attribute 'split'

got this error after 10 minutes of script running ๐Ÿ˜…

YouTube tracks: 980/1502
YouTube tracks: 990/1502
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Source\Scripts\spotify_to_ytmusic.exe\__main__.py", line 7, in <module>
  File "C:\Source\lib\site-packages\spotify_to_ytmusic\main.py", line 79, in main
    args.func(args)
  File "C:\Source\lib\site-packages\spotify_to_ytmusic\controllers.py", line 54, in create
    videoIds = ytmusic.search_songs(playlist["tracks"])
  File "C:\Source\lib\site-packages\spotify_to_ytmusic\ytmusic.py", line 36, in search_songs
    targetSong = get_best_fit_song_id(result, song)
  File "C:\Source\lib\site-packages\spotify_to_ytmusic\match.py", line 27, in get_best_fit_song_id
    title_split = title.split("-")
AttributeError: 'NoneType' object has no attribute 'split'

Bug with YouTube music

Hi,

I've generated the headers following the instructions here: https://ytmusicapi.readthedocs.io/en/latest/setup.html

{
    "Accept": "*/*",
    "Accept-Language": "en-US,en;q=0.5",
    "Content-Type": "application/json",
    "Cookie": "<REACTED>",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0",
    "X-Goog-AuthUser": "3",
    "X-Goog-Visitor-Id": "<REACTED>",
    "origin": "https://music.youtube.com"
}

I've also turned it into single line json, following the same format as Google Music

Any suggestions?

Could not transfer playlist test. Exception'videoId'

Hi, I encounter the following error when running the YouTube.py script:

4 playlists found. Starting transfer...
Playlist 1: test
Spotify tracks: 5/5
Could not transfer playlist WLG. Exception'videoId'
[...]

Removing the try/except I get a better help message:

4 playlists found. Starting transfer...
Playlist 1: test
Spotify tracks: 5/5
Traceback (most recent call last):
  File "/Volumes/datvol/Perso/spym/spotifyplaylist_to_ytmusic/YouTube.py", line 190, in <module>
    main()
  File "/Volumes/datvol/Perso/spym/spotifyplaylist_to_ytmusic/YouTube.py", line 150, in main
    videoIds = ytmusic.search_songs(playlist['tracks'])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Volumes/datvol/Perso/spym/spotifyplaylist_to_ytmusic/YouTube.py", line 74, in search_songs
    targetSong = self.get_best_fit_song_id(result, song)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Volumes/datvol/Perso/spym/spotifyplaylist_to_ytmusic/YouTube.py", line 43, in get_best_fit_song_id
    title_score[res['videoId']] = difflib.SequenceMatcher(a=title.lower(), b=song['name'].lower()).ratio()
                ~~~^^^^^^^^^^^
KeyError: 'videoId'

And this is what I get when I print req:

{'resultType': 'song', 'title': 'Avant Gardener', 'artists': [{'name': 'Courtney Barnett', 'id': 'UCAR6fZVOSmnctDecWdS9rtQ'}], 'album': {'name': 'The Double EP: A Sea of Split Peas', 'id': 'MPREb_T088NuxNhsq'}, 'duration': '5:13', 'duration_seconds': 313, 'thumbnails': [{'url': 'https://lh3.googleusercontent.com/D3R44aaDMdBbV5QZCk_qjizA-teEO2GtYDY62NjP1-fRVDhyk7Qh1AxFA5AOxMuk3GSM0Chpqg5Jicy4=w60-h60-l90-rj', 'width': 60, 'height': 60}, {'url': 'https://lh3.googleusercontent.com/D3R44aaDMdBbV5QZCk_qjizA-teEO2GtYDY62NjP1-fRVDhyk7Qh1AxFA5AOxMuk3GSM0Chpqg5Jicy4=w120-h120-l90-rj', 'width': 120, 'height': 120}]}

Hope that helps! Thanks for developing and maintaining this repo.

key error: Youtube when importing headers

I am trying to copy-paste the headers using the Setup.py

Steps to reproduce

Headers i try to copy paste

User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept-Language: en-US,en;q=0.5
Content-Type: application/json
X-Goog-AuthUser: 0
X-Origin: https://music.youtube.com
Connection: keep-alive
Cookie: <<Cookie header>> 

Terminal

python3 setup.py youtube 
Please paste the request headers from Firefox and press Ctrl-D to continue:
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept-Language: en-US,en;q=0.5
Content-Type: application/json
X-Goog-AuthUser: 0
X-Origin: https://music.youtube.com
Connection: keep-alive
Cookie: <<Cookie header>> 

I Get the error:

Traceback (most recent call last):
  File "Setup.py", line 8, in <module>
    settings['youtube']['headers'] = api.setup()
  File "/home/mike/Documents/spotifyplaylist_to_ytmusic/settings.py", line 14, in __getitem__
    return config[key]
  File "/usr/lib/python3.8/configparser.py", line 960, in __getitem__
    raise KeyError(key)
KeyError: 'youtube'


So am i doing the copy-pasting wrong or ? If i copy 1 header it works fine, but if i try to copy paste them all i get the key error.

Setup Failing

Version: 0.1.2
Device: Macbook Air M1
MacOS Version: 12.0.1
Python version: 3.11.1

When following the instructions:
pip install spotify_to_ytmusic

It installs successfully:
Successfully installed spotify_to_ytmusic-0.1.2 spotipy-2.23.0 ytmusicapi-1.0.0

Then when I run
spotify_to_ytmusic setup
I get to the menu:

Choose which API to set up
(1) Spotify
(2) YouTube
(3) both

And regardless of the option I select I get the following error:

Traceback (most recent call last):
  File "/Users/username/.pyenv/versions/3.11.1/bin/spotify_to_ytmusic", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/username/.pyenv/versions/3.11.1/lib/python3.11/site-packages/spotify_to_ytmusic/main.py", line 79, in main
    args.func(args)
  File "/Users/username/.pyenv/versions/3.11.1/lib/python3.11/site-packages/spotify_to_ytmusic/controllers.py", line 80, in setup
    setup_func(args.file)
  File "/Users/username/.pyenv/versions/3.11.1/lib/python3.11/site-packages/spotify_to_ytmusic/setup.py", line 27, in setup
    setup_spotify()
  File "/Users/username/.pyenv/versions/3.11.1/lib/python3.11/site-packages/spotify_to_ytmusic/setup.py", line 38, in setup_spotify
    settings = Settings()
               ^^^^^^^^^^
  File "/Users/username/.pyenv/versions/3.11.1/lib/python3.11/site-packages/spotify_to_ytmusic/settings.py", line 15, in __init__
    raise FileNotFoundError(
FileNotFoundError: No settings.ini not found! Please run 

 spotify_to_ytmusic setup

This seems circular. Maybe I'm doing something wrong, but it seems like the setup is dependent on Settings(), which is dependent on a settings.ini

--all argument is not working in some cases

SpotifyExport.py
The getUserPlaylists method returns 0 in a specific use case:

I initially registered for Spotify with my Facebook account, but later I unlinked them and deleted my Facebook. Now I log in with the Spotify user ID number, and my displayname can't be pulled from Facebook anymore, so it defaults to "Spotify"

Therefore this return fails:
return [p for p in pl if p['owner']['display_name'] == user and p['tracks']['total'] > 0]

because in this case owner = <spotify user ID#> and 'display name' = "Spotify". Removing this if statement from the code fixed my problem.

Transfer Liked songs --> Couldn't read/write token to cache at: .cache

Hi! Currently trying to transfer my liked songs from Spotify to Youtube Music.

I made a new 'app' on spotify developer with the website and redirect uri set to http://localhost

After running the setup (spotify_to_ytmusic setup), I chose option (3) -- Both. Specified my client ID and client secret from the app on the developer dashboard for Spotify. Then I specified 'yes' for OAuth method for authorization, went to the specified google.com link and linked my account and got the 'Success! Device connected' message on the site.

Afterwards I tried running (spotify_to_ytmusic liked) and it directed me to an https://localhost/?code=AQBAjlzUz2B.... [link truncated]

Which of course could not load on my browser.

The instructions on the terminal indicated pasting the 'URL (I was) redirected to:'

to which I did and it basically opened the same URL in a new browser window with the following message:

Couldn't write token to cache at: .cache
Couldn't read cache at: .cache
Using `localhost` as redirect URI without a port. Specify a port (e.g. `localhost:8080`) to allow automatic retrieval of authentication code instead of having to copy and paste the URL your browser is redirected to.

I also tried switching the URI to localhost:8080 in the Spotify app developer dashboard with no success. What did I miss??

Error with Spotify credentials

Discussed in #54

Originally posted by brickforbrains April 22, 2023
I have used this project before with great success but upon recently fetching the project, I can't seem to get it to work.

the error i get is "AssertionError: Spotify client_id not set or invalid: id_from_developer_console"

after running setup, my settings.ini contains the following (i have replaced the bulk of my client ID and client secret with **):

[youtube]
headers = {"error": "authorization_pending", "error_description": "Precondition Required"}
user_id =

[spotify]
client_id = id_from_developer_console
client_secret = secret_from_developer_console
client_credentials = 25
client_secrets = f
2

is there anything you see obviously wrong? would love to use this tool again

Trouble setting up the setttings file

Not sure where to find the headers as "browse?" doesn't show using chrome nor firefox. I'm also not sure where to find the user id to add in as well.

match.py crashes on privated videos

match.py iterates through the results from YouTube and scores them. However, if a privated video is fed to it, it will crash.

This happened to me when I was trying to import All My Loving - The Beetles. I got the following response from YouTube:

{'category': 'More from YouTube', 'resultType': 'video', 'title': None, 'videoId': 'VadsG2xoHHE', 'videoType': None, 'duration': None, 'year': None, 'artists': [], 'thumbnails': [{'url': 'https://i.ytimg.com/vi/VadsG2xoHHE/mqdefault.jpg', 'width': 0, 'height': 0}]}

Because the video does not have a title, match.py crashes on this line:

https://github.com/sigma67/spotify_to_ytmusic/blob/master/spotify_to_ytmusic/match.py#L27

A simple workaround is to add a continue to ignore the video. I tried this, and it worked:

if ytm["resultType"] == "video":
    if not title:
        # If the video has been made private, it will not have a title
         continue
    else:
        title_split = title.split("-")
        if len(title_split) == 2:
            title = title_split[1]

Crash importing a specific playlist

I imported all of my playlists fine, however this one generates an error.

https://open.spotify.com/playlist/37i9dQZF1DWVY4eLfA3XFQ

I simply ran: python3 YouTube.py https://open.spotify.com/playlist/37i9dQZF1DWVY4eLfA3XFQ

Traceback (most recent call last):
  File "YouTube.py", line 190, in <module>
    main()
  File "YouTube.py", line 182, in main
    videoIds = ytmusic.search_songs(playlist['tracks'])
  File "YouTube.py", line 70, in search_songs
    result = self.api.search(query)
  File "/home/cappyt/.local/lib/python3.8/site-packages/ytmusicapi/mixins/browsing.py", line 179, in search
    search_results.extend(self.parser.parse_search_results(results, type, category))
  File "/home/cappyt/.local/lib/python3.8/site-packages/ytmusicapi/helpers.py", line 126, in _impl
    return method(self, *method_args, **method_kwargs)
  File "/home/cappyt/.local/lib/python3.8/site-packages/ytmusicapi/parsers/browsing.py", line 39, in parse_search_results
    parse_menu_playlists(data, search_result)
  File "/home/cappyt/.local/lib/python3.8/site-packages/ytmusicapi/parsers/utils.py", line 5, in parse_menu_playlists
    watch_menu = find_objects_by_key(nav(data, MENU_ITEMS), 'menuNavigationItemRenderer')
  File "/home/cappyt/.local/lib/python3.8/site-packages/ytmusicapi/parsers/utils.py", line 155, in nav
    raise err
  File "/home/cappyt/.local/lib/python3.8/site-packages/ytmusicapi/parsers/utils.py", line 149, in nav
    root = root[k]
KeyError: 'menu'

Hope this helps.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.