cococry / lyssa

Aestethic, minimal, suckless music player
163 stars 6 forks source link

crash when downloading playlist #10

Closed aetherspritee closed 3 months ago

aetherspritee commented 3 months ago

hi, awesome piece of software!

downloading a playlist causes the program to segfault:

terminate called after throwing an instance of 'std::invalid_argument'
  what():  stoi
zsh: IOT instruction (core dumped)  lyssa

Also, the download script is currently called download-yt.sh, but the program expects a script called download.sh, so i renamed it, maybe the script is outdated?

cococry commented 3 months ago

There is a script called download.sh in ~/.lyssa/scripts right?

Also, the playlist needs to be public. If you want, you can provide a link to the playlist to reproduce the problem.

aetherspritee commented 3 months ago

Nope, the script in github is called download-yt.sh, while the code expects download.sh. And as far as i can see it isn't renamed only copied into the .lyssa directory.

The download of the playlist did run successfully in the background even after the crash, so i dont expect that to be the issue

cococry commented 3 months ago

Okay, i added the download.sh script into the repository now. Just pull and try to download the playlist again.

brmarkus commented 3 months ago

I have exactly the same:

terminate called after throwing an instance of 'std::invalid_argument'
  what():  stoi

On Ubuntu 22.04LTS. First I needed to get yt-dlp updated (the version from Ubuntu 22.04LTS seems too old, according to some Google-findings; the older version caused some parsing/extracting problems, now cannot remember exactly which...), now usined the latest:

$ yt-dlp -U
Latest version: stable@2024.05.27 from yt-dlp/yt-dlp
yt-dlp is up to date (stable@2024.05.27 from yt-dlp/yt-dlp)

Starting lyssa from a terminal and downloading a "youtube video" via its URL (e.g. different U2 music video URLs). In the terminal in the background I see first the crash of the application - but then see several logs from the playlist download happening and finishing successfully (seems the script download.sh is working). (when starting the application again I can manually select the folder from the downloaded "playlist", see the extracted audio-file, the created thumbnail and cn playback the MP3 file).

Then modifying the Makfile to add debug-infos to and remove optimization from the compiler command-line and starting the application again in gdb (sorry on my constrained systems no IDE like VisualCode available).

I get this callstack when the application crashes:

(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737346320256) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737346320256) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737346320256, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff7642476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff76287f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff7ca2b9e in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff7cae20c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff7cae277 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff7cae4d8 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#9  0x00007ffff7ca53f2 in std::__throw_invalid_argument(char const*) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#10 0x00005555555a3fd4 in int __gnu_cxx::__stoa<long, int, char, int>(long (*)(char const*, char**, int), char const*, char const*, unsigned long*, int) ()
#11 0x00005555555a0c9a in std::__cxx11::stoi(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long*, int) ()
#12 0x0000555555578941 in LyssaUtils::getPlaylistFileCountURL(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#13 0x0000555555581dda in renderDownloadPlaylist() ()
#14 0x00005555555992f8 in main ()

Looking closer into frame number 12:

(gdb) info frame
Stack level 12, frame at 0x7fffffffda40:
 rip = 0x555555578941 in LyssaUtils::getPlaylistFileCountURL(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&); saved rip = 0x555555581dda
 called by frame at 0x7fffffffe0a0, caller of frame at 0x7fffffffd9b0
 Arglist at 0x7fffffffda30, args:
 Locals at 0x7fffffffda30, Previous frame's sp is 0x7fffffffda40
 Saved registers:
  rbx at 0x7fffffffda28, rbp at 0x7fffffffda30, rip at 0x7fffffffda38
cococry commented 3 months ago

bro, you can not download a single youtube video with lyssa.

the player expects a playlist of videos that needs to be public. the error you are getting is caused as lyssa tries to figure out how many songs are in your given playlist. but as you are giving it a link of a yt video, that obviously does not work.

brmarkus commented 3 months ago

The player could be a bit more rebust to such cases... when yt-dlp is used in the background... it successfully downloads the single video, extracts audio successfully and stores the MP3-file and the thumbnail successfully.

bro, you can not download a single youtube video with lyssa.

I can ;-), the GUI expects just an URL...

In the GUI, after restarting, I can manually create a new "playlist" by selecting the folder ~/.lyssa/downloaded_playlists/ - selecting a folder from "a single downloaded file". Everything from that seems to work.

When moving to another computer, let me see what can be done to process such a "single file" case and try to prevent the crash.

brmarkus commented 3 months ago

When searching for "u2 playlist" in youtube.com and picking the first result's URL: "https://www.youtube.com/watch?v=e3-5YC_oHjE&list=RDEM42gVzHaBaiOyuec4jx6v-A&start_radio=1"

Then I see the same crash. In the background the download-scripts again completely downloads the "playlist" to a "MixU2" folder (all 107 items from the playlist) - which can be selected when starting the application again (by adding a playlist based on a folder and select the folder "MixU2"): image

Maybe the yt-dlp has changed in the meantime, returning and/or interpreting the results differently, or Youtube (as in my case) has changed something.

cococry commented 3 months ago

alright, this should be fixed with the last commit.

aetherspritee commented 3 months ago

Works like a charm! Thank you!

brmarkus commented 3 months ago

Nope, still crashing for me - trying to download a "playlist" (again just a single music video on Youtube):

Thread 1 "lyssa" received signal SIGFPE, Arithmetic exception.
0x000055555558301a in renderDownloadPlaylist () at src/lyssa.cpp:1286
[download] ftjEcrrf7r0: has already been recorded in the archive
1286          int percentage = MIN(((downloadedFileCount * 100) / state.downloadPlaylistFileCount), 100);
(gdb) bt full
#0  0x000055555558301a in renderDownloadPlaylist () at src/lyssa.cpp:1286
        percentage = 1122240311
        oss = <incomplete type>
        percentStr = "\234N\226\bPU\000\000q\354Gd\222\003I\002eOfficialMusicVideo..."
        text_props = {color = {r = 96 '`', g = 69 'E', b = 205 '\315', a = 93 ']'}, hover_color = {r = 85 'U', g = 85 'U', b = 0 '\000',
            a = 0 '\000'}, text_color = {r = 80 'P', g = 69 'E', b = 205 '\315', a = 93 ']'}, hover_text_color = {r = 85 'U', g = 85 'U',
            b = 0 '\000', a = 0 '\000'}, border_color = {r = 0 '\000', g = 0 '\000', b = 62 '>', a = 66 'B'}, padding = 0,
          margin_left = -nan(0x7fdc90), margin_right = 4.59163468e-41, margin_top = 1, margin_bottom = 2.24207754e-44, border_width = -1.5211049e+32,
          corner_radius = 4.59163468e-41}
        progressBarSize = {raw = {400, 6}, {x = 400, y = 6}, {r = 400, i = 6}, {u = 400, v = 6}, {s = 400, t = 6}}
        props = {color = {r = 30 '\036', g = 34 '"', b = 42 '*', a = 255 '\377'}, hover_color = {r = 0 '\000', g = 0 '\000', b = 0 '\000',
            a = 0 '\000'}, text_color = {r = 0 '\000', g = 0 '\000', b = 0 '\000', a = 0 '\000'}, hover_text_color = {r = 0 '\000', g = 0 '\000',
            b = 0 '\000', a = 0 '\000'}, border_color = {r = 0 '\000', g = 0 '\000', b = 0 '\000', a = 0 '\000'}, padding = 0, margin_left = 0,
          margin_right = 0, margin_top = 0, margin_bottom = 0, border_width = 0, corner_radius = 6}
        ytdlpDownTimer = 0
        downloadedPlaylistDir = "/home/efuser/.lyssa/downloaded_playlists/U2OneOfficialMusicVideo"
        downloadedFileCount = 1
        url = "https://www.youtube.com/watch?v=ftjEcrrf7r0"

(gdb) p state.downloadPlaylistFileCount
$3 = 0
(gdb) p downloadedFileCount
$4 = 1

=> division by zero

brmarkus commented 3 months ago

After adding a check to prevent division-by-zero to "renderDownloadPlaylist()", finding another place:

Thread 1 "lyssa" received signal SIGFPE, Arithmetic exception.
0x0000555555638a35 in _lf_progress_bar_int_loc ()
(gdb) bt
#0  0x0000555555638a35 in _lf_progress_bar_int_loc ()
#1  0x0000555555583360 in renderDownloadPlaylist () at src/lyssa.cpp:1314
#2  0x0000555555599778 in main (argc=1, argv=0x7fffffffe2e8) at src/lyssa.cpp:3570

Which is here:

      props.margin_left = 15;
      props.margin_right = 0;
      lf_push_style_props(props);
=>  lf_progress_bar_int(downloadedFileCount, 0, (float)state.downloadPlaylistFileCount, progressBarSize.x, progressBarSize.y);
      lf_pop_style_props();
    }

    lf_next_line();

yes, another state.downloadPlaylistFileCount being zero.