sigma67 / spotify_to_ytmusic

Clone a Spotify playlist to YouTube Music
MIT License
895 stars 67 forks source link

ZeroDivisionError: float division by zero #32

Closed JonathanAaron closed 1 year ago

JonathanAaron commented 2 years ago

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

JonathanAaron commented 2 years ago

I think we need a 0 check for song['duration'] what do you think @sigma67 I'm trying it right now in this huge playlist of 1200 songs. If it works I can get a pr out or something.

sigma67 commented 2 years ago

Can you point the specific song this is happening with? Could certainly introduce a workaround for the case that the duration is missing

sigma67 commented 2 years ago

Alternatively please link the playlist in question

guglielmobartelloni commented 2 years ago

I have the same problem, I was trying with this playlist

sigma67 commented 2 years ago

I think we need to find a song where this consistently occurs, it no longer works for me with the above playlist

guglielmobartelloni commented 2 years ago

I will try to work on this bug in my spare time. I will let you know what I find

guglielmobartelloni commented 2 years ago

This isn't a consistent bug and I think it is in the way the YTMusic library parses songs, sometimes one of the search results will be empty and thats when the bug occurs.

I tried with the following code to print the song information:

         durationMatch = None
         if 'duration' in res and res['duration']:
                durationItems = res['duration'].split(':')
                duration = int(durationItems[0]) * 60 + int(durationItems[1])
                print(song)
                durationMatch = 1 - abs(duration - song['duration']) * 2 / song['duration']

and the output is:

{'artist': 'Don Toliver Travis Scott', 'name': 'Flocky Flocky (feat. Travis Scott)', 'album': 'Life of a DON', 'duration': 183.513}
{'artist': 'Don Toliver Travis Scott', 'name': 'Flocky Flocky (feat. Travis Scott)', 'album': 'Life of a DON', 'duration': 183.513}
{'artist': 'Don Toliver Travis Scott', 'name': 'Flocky Flocky (feat. Travis Scott)', 'album': 'Life of a DON', 'duration': 183.513}
{'artist': 'Don Toliver Travis Scott', 'name': 'Flocky Flocky (feat. Travis Scott)', 'album': 'Life of a DON', 'duration': 183.513}
{'artist': 'Don Toliver Travis Scott', 'name': 'Flocky Flocky (feat. Travis Scott)', 'album': 'Life of a DON', 'duration': 183.513}
{'artist': 'Don Toliver Travis Scott', 'name': 'Flocky Flocky (feat. Travis Scott)', 'album': 'Life of a DON', 'duration': 183.513}
{'artist': 'Don Toliver Travis Scott', 'name': 'Flocky Flocky (feat. Travis Scott)', 'album': 'Life of a DON', 'duration': 183.513}
{'artist': '', 'name': '', 'album': '', 'duration': 0.0}
Traceback (most recent call last):
  File "/Users/samurai/Documents/progetti/spotifyplaylist_to_ytmusic/YouTube.py", line 191, in <module>
    main()
  File "/Users/samurai/Documents/progetti/spotifyplaylist_to_ytmusic/YouTube.py", line 183, in main
    videoIds = ytmusic.search_songs(playlist['tracks'])
  File "/Users/samurai/Documents/progetti/spotifyplaylist_to_ytmusic/YouTube.py", line 75, in search_songs
    targetSong = self.get_best_fit_song_id(result, song)
  File "/Users/samurai/Documents/progetti/spotifyplaylist_to_ytmusic/YouTube.py", line 33, in get_best_fit_song_id
    durationMatch = 1 - abs(duration - song['duration']) * 2 / song['duration']
ZeroDivisionError: float division by zero

as you can see the last result is has all the values empty. One thing I noticed is that this bug is not tied to a particular song but it's tied to a particular playlist. If I try to put the same "bugged" song to another playlist it will be fine.

Maybe to work out this bug, we can remove the "bad" results (or skip it directly) and then do all the math so this problem can't happen.

Let me know what do you think

sigma67 commented 2 years ago

Oh so the dictionary is completely empty? That seems like it would be a bug in ytmusicapi. Can you post the search query used for this empty result?

guglielmobartelloni commented 2 years ago

Yes, it seems to be a ytmusic library problem. When I come back home I'll post the search query.

guglielmobartelloni commented 2 years ago

Turns out that the search query is empty:

Query: Don Toliver Kali Uchis Drugs N Hella Melodies
Query: Don Toliver Travis Scott Flocky Flocky
Query:
Traceback (most recent call last):
  File "/Users/samurai/Documents/progetti/spotifyplaylist_to_ytmusic/YouTube.py", line 201, in <module>
    main()
  File "/Users/samurai/Documents/progetti/spotifyplaylist_to_ytmusic/YouTube.py", line 193, in main
    videoIds = ytmusic.search_songs(playlist['tracks'])
  File "/Users/samurai/Documents/progetti/spotifyplaylist_to_ytmusic/YouTube.py", line 78, in search_songs
    targetSong = self.get_best_fit_song_id(result, song)
  File "/Users/samurai/Documents/progetti/spotifyplaylist_to_ytmusic/YouTube.py", line 35, in get_best_fit_song_id
    durationMatch = 1 - abs(duration - song['duration']) * 2 / song['duration']
ZeroDivisionError: float division by zero

Very strange

guglielmobartelloni commented 2 years ago

After debugging for some time I found what was causing the bug for me. In the playlist there were some songs that where removed from Spotify for some reason so the song list will have those songs with all the values empty

xDroni commented 2 years ago

Got this error today, any workaround?

nicolas-suzuki commented 2 years ago

Got this error today, any workaround?

I got this today and what I did was to check where it is failling in the console:

YouTube tracks: 360/1571
Traceback (most recent call last):
...
ZeroDivisionError: float division by zero

With that, go to your Spotify playlist and check for the songs after "360". One of them will probably be a 0:00 minute song. Remove it from the playlist (worth checking the entire playlist for songs "0:00" long). And then, just re-run the command.