Sinono3 / souvlaki

A cross-platform library for handling OS media controls and metadata.
MIT License
79 stars 15 forks source link

Metadata not updating (linux) #50

Closed jernejmarcic closed 6 months ago

jernejmarcic commented 6 months ago

First of all I would like to apologize as I am new to reporting issues and this may be bad. My repository where my code is located is: https://github.com/jernejmarcic/RustyPlayer

My metadata does not update (it only shows the metadata from the first song after the program is ran), I used the code straight from examples and pasted it in, when I had my music logic all in a loop it worked, however now it no longer works.

Old working code

Working code example, I apologize if I uploaded more than was needed:

pub(crate) fn play_random_song(music_list: &[String], debug_mode: bool /*, config_path: &PathBuf*/) -> std::io::Result<()> {
    if music_list.is_empty() {
        println!("No songs found in the specified directory.");
        return Ok(());
    }

    let mut rng = rand::thread_rng();
    let mut played_songs:Vec<usize> = Vec::new();

//    let mut last_paused_state = IS_PAUSED.load(Ordering::SeqCst);

    loop {
 //       let current_paused_state = IS_PAUSED.load(Ordering::SeqCst);
        let randint = rng.gen_range(0..music_list.len());
        // Your actual logic goes here.
        played_songs.push(randint);  // Track played songs
        if debug_mode {println!("Playing song number: {}",randint)}
        if debug_mode {println!("Song numbers played: {:?}", played_songs)}
        if debug_mode{ println!("Playing song file: {}", music_list[randint]);}
        // println!("Played songs index: {:?}", played_songs);
        // Get an output stream handle to the default physical sound device
        let (_stream, stream_handle) = OutputStream::try_default().unwrap();
        let file = BufReader::new(File::open(&music_list[randint]).unwrap());
        let sink = Sink::try_new(&stream_handle).unwrap();
        let tag = Tag::new().read_from_path(&music_list[randint]).unwrap();
        let title = tag.title().unwrap_or_else(|| "Unknown".into());
 //       let album_cover = tag.album_cover();
        let duration_seconds: Option<f64> = tag.duration();  // Example duration in seconds
        let duration: Option<Duration> = convert_to_duration(duration_seconds);
        let artists = tag
            .artists()
            .map(|a| a.join(", "))
            .unwrap_or_else(|| "Unknown".into());
        let album = tag.album_title().unwrap_or_else(|| "Unknown".into());

// Add a dummy source of the sake of the example.
        let source = Decoder::new(file).unwrap();
        sink.append(source);

        // Construct the path to the directory where the .jpg files are located

        let cover_output_path = format!("/tmp/{}.jpg", album);
        let cover_output_path_clone = cover_output_path.clone();
        if debug_mode {println!("Cover export path is: {}", cover_output_path)}
        terminal_ui(&music_list, randint, title, album, artists.clone(), debug_mode, cover_output_path_clone);

  //      let played_songs_clone = played_songs.clone();  // Clone played_songs for the closure
        //     let music_list_clone = music_list;

        #[cfg(not(target_os = "windows"))]
            let hwnd = None;

        #[cfg(target_os = "windows")]
            let hwnd = {
            use raw_window_handle::windows::WindowsHandle;

            let handle: WindowsHandle = unimplemented!();
            Some(handle.hwnd)
        };

        let config = PlatformConfig {
            dbus_name: "rustyplayer",
            display_name: "Rusty Player",
            hwnd,
        };

        let mut controls = MediaControls::new(config).unwrap();

        // The closure must be Send and have a static lifetime.
       // let played_songs_clone = Arc::clone(&played_songs);
        controls
            .attach(
                move |event: MediaControlEvent| match event {
                MediaControlEvent::Play => {
                    if debug_mode {println!("{:?} event received via MPRIS",event)}
                    let current_state = IS_PAUSED.load(Ordering::SeqCst);
                    IS_PAUSED.store(!current_state, Ordering::SeqCst);  // Toggle the state
                },

                MediaControlEvent::Pause => {
                    if debug_mode {println!("{:?} event received via MPRIS",event)}
                    // Logic to pause the music
                    let current_state = IS_PAUSED.load(Ordering::SeqCst);
                    IS_PAUSED.store(!current_state, Ordering::SeqCst);  // Toggle the state

                },
                MediaControlEvent::Toggle => {
                    if debug_mode {println!("{:?} event received via MPRIS",event)}
                    // Toggle logic here
                    let current_state = IS_PAUSED.load(Ordering::SeqCst);
                    IS_PAUSED.store(!current_state, Ordering::SeqCst);  // Toggle the state
                },

                MediaControlEvent::Next => {
                    if debug_mode {println!("{:?} event received via MPRIS",event)}
                    // Logic to skip to the next track
                    // You might need to signal your playback loop to move to the next song
                    SHOULD_SKIP.store(true, Ordering::SeqCst);

                },

                MediaControlEvent::Previous => {
                    if debug_mode {println!("{:?} event received via MPRIS",event)}

                    // TODO: Well make it work. LOL
                    // If only it was not so FUCKING HARD.

                },

                // Add more event handlers as needed
                _ => println!("Event received: {:?}. If you see this message contact me I probably just haven't added support yet for it", event),
            })
            .unwrap();

        // Update the media metadata.
        controls
            .set_metadata(MediaMetadata {
                title: Some(title),
                artist: Some(&*artists),
                album: Some(album),
                duration: duration,
                cover_url: Some(&*format!("file://{}", cover_output_path)),
                ..Default::default()
            })
            .unwrap();

        while !sink.empty() && !SHOULD_SKIP.load(Ordering::SeqCst) {
            // Check and handle play/pause state...
            let current_paused_state = IS_PAUSED.load(Ordering::SeqCst);
            if current_paused_state != LAST_PAUSED_STATE.load(Ordering::SeqCst) {
                if current_paused_state {
                    if debug_mode {println!("Attempting to pause")}
                    sink.pause();
                    if debug_mode {println!("Track should be paused")}
                   // println!("Paused");
                } else if !current_paused_state {  // Changed from 'else' to 'else if' to explicitly check the condition
                    if debug_mode {println!("Attempting to resume/play")}
                    sink.play();
                    if debug_mode {println!("Track should be resumed")}
                   // println!("Play");
                }
                // Update the last paused state to the current state
                LAST_PAUSED_STATE.store(current_paused_state, Ordering::SeqCst);
            }

            thread::sleep(Duration::from_millis(50));
        }

        // Check again for skip in case it was set during playback
        if SHOULD_SKIP.load(Ordering::SeqCst) {
            SHOULD_SKIP.store(false, Ordering::SeqCst);  // Reset the flag
            println!("Attempting to skip to the next track...");
            // No need for 'continue;' here as it's the end of the loop
            continue;
        }

        sink.sleep_until_end();

// The sound plays in a separate thread. This call will block the current thread until the sink
// has finished playing all its queued sounds.

    }
}

Now this implementation is lacking as It did not allow me to have support to play the previous song.

New not working code

This is the function of my new code:

fn music_player(music_list: &[String], debug_mode: bool, song_history: &mut Vec<Vec<usize>>, song_index: usize) {
    if debug_mode { println!("Playing song number: {}", song_index) }
    if debug_mode { println!("Song numbers played: {:?}", song_history) }
    if debug_mode { println!("Playing song file: {}", music_list[song_index]); }
    // println!("Played songs index: {:?}", song_history);
    // Get an output stream handle to the default physical sound device
    let (_stream, stream_handle) = OutputStream::try_default().unwrap();
    let file = BufReader::new(File::open(&music_list[song_index]).unwrap());
    let sink = Sink::try_new(&stream_handle).unwrap();

    let tag = Tag::new().read_from_path(&music_list[song_index]).unwrap();
    let title = tag.title().unwrap_or_else(|| "Unknown".into());
    //       let album_cover = tag.album_cover();
    let duration_seconds: Option<f64> = tag.duration();  // Example duration in miliseconds
    let duration: Option<Duration> = convert_to_duration(duration_seconds);
    let artists = tag
        .artists()
        .map(|a| a.join(", "))
        .unwrap_or_else(|| "Unknown".into());
    let album = tag.album_title().unwrap_or_else(|| "Unknown".into());

// Add a dummy source of the sake of the example.
    let source = Decoder::new(file).unwrap();
    sink.append(source);

    // Construct the path to the directory where the .jpg files are located

    let cover_output_path = format!("/tmp/{}-cover-{}.jpg",PACKAGE_NAME, song_index);
    let cover_output_path_clone = cover_output_path.clone();

    if debug_mode { println!("Cover export path is: {}", cover_output_path) }
    terminal_ui(&music_list, song_index, title, album, artists.clone(), debug_mode, cover_output_path_clone);

    #[cfg(not(target_os = "windows"))]
        let hwnd = None;

    #[cfg(target_os = "windows")]
        let hwnd = {
        use raw_window_handle::windows::WindowsHandle;

        let handle: WindowsHandle = unimplemented!();
        Some(handle.hwnd)
    };

    let config = PlatformConfig {
        dbus_name: PACKAGE_NAME,
        display_name: "Rusty Player",
        hwnd,
    };

    let mut controls = MediaControls::new(config).unwrap();

        controls
            .attach(
                move |event: MediaControlEvent| match event {
                    MediaControlEvent::Play => {
                        if debug_mode { println!("{:?} event received via MPRIS", event) }
                        let current_state = IS_PAUSED.load(Ordering::SeqCst);
                        IS_PAUSED.store(!current_state, Ordering::SeqCst);  // Toggle the state
                    }

                    MediaControlEvent::Pause => {
                        if debug_mode { println!("{:?} event received via MPRIS", event) }
                        // Logic to pause the music
                        let current_state = IS_PAUSED.load(Ordering::SeqCst);
                        IS_PAUSED.store(!current_state, Ordering::SeqCst);  // Toggle the state
                    }
                    MediaControlEvent::Toggle => {
                        if debug_mode { println!("{:?} event received via MPRIS", event) }
                        // Toggle logic here
                        let current_state = IS_PAUSED.load(Ordering::SeqCst);
                        IS_PAUSED.store(!current_state, Ordering::SeqCst);  // Toggle the state
                    }

                    MediaControlEvent::Next => {
                        if debug_mode { println!("{:?} event received via MPRIS", event) }
                        // Logic to skip to the next track
                        // You might need to signal your playback loop to move to the next song
                        SHOULD_SKIP.store(true, Ordering::SeqCst);
                    }

                    MediaControlEvent::Previous => {
                        if debug_mode { println!("{:?} event received via MPRIS", event) }
                        SHOULD_PLAY_PREVIOUS.store(true, Ordering::SeqCst);

                    }

                    // Add more event handlers as needed
                    _ => println!("Event received: {:?}. If you see this message contact me I probably just haven't added support yet for it", event),
                })
            .unwrap();

    controls
        .set_metadata(MediaMetadata {
            title: Some(title),
            artist: Some(&*artists),
            album: Some(album),
            duration: duration,
            cover_url: Some(&*format!("file://{}", cover_output_path)),
            ..Default::default()
        })
        .unwrap();

    //    println!("TEST, {album}, {title}, {:?}", artists);

    while !sink.empty() && !SHOULD_SKIP.load(Ordering::SeqCst) && !SHOULD_PLAY_PREVIOUS.load(Ordering::SeqCst){

        // Check and handle play/pause state...
        let current_paused_state = IS_PAUSED.load(Ordering::SeqCst);
        if current_paused_state != LAST_PAUSED_STATE.load(Ordering::SeqCst) {
            if current_paused_state {
                if debug_mode { println!("Attempting to pause") }
                sink.pause();
                if debug_mode { println!("Track should be paused") }
                // println!("Paused");
            } else if !current_paused_state {  // Changed from 'else' to 'else if' to explicitly check the condition
                if debug_mode { println!("Attempting to resume/play") }
                sink.play();
                if debug_mode { println!("Track should be resumed") }
                // println!("Play");
            }
            // Update the last paused state to the current state
            LAST_PAUSED_STATE.store(current_paused_state, Ordering::SeqCst);
        }

        thread::sleep(Duration::from_millis(50));
    }

// Inside your playback loop
    while !sink.empty() {
        if SHOULD_SKIP.load(Ordering::SeqCst) {
            SHOULD_SKIP.store(false, Ordering::SeqCst);  // Reset the flag
            if debug_mode { println!("Attempting to skip to the next track..."); }
            sink.clear();

            if song_history[1].len() >= 1 {
                let song_index = song_history[1][song_history[1].len()-1];
                song_history[1].pop();
                music_player(music_list, debug_mode,song_history, song_index/*&mut rng*/);

            } else {
                random_passer(music_list, debug_mode,song_history, /*&mut rng*/);
            }
            // Logic to skip to the next track, adjust `current_index` as needed
            random_passer(music_list, debug_mode,song_history, /*&mut rng*/);
        }

        if SHOULD_PLAY_PREVIOUS.load(Ordering::SeqCst) {
            SHOULD_PLAY_PREVIOUS.store(false, Ordering::SeqCst);  // Reset the flag
            if debug_mode { println!("Attempting to go back to the previous track..."); }

            // Logic to play the previous track, adjust `current_index` as needed
            if song_history[0].len() >= 2 {
                sink.clear();
                song_history[1].push(song_index);
                let song_index = song_history[0][song_history[0].len()-2];
                song_history[0].pop();
                music_player(music_list, debug_mode,song_history, song_index/*&mut rng*/);
            } else {
                println!("Not enough songs in the play queue")
            }

        }

        // Continue existing play/pause state checks here...
        thread::sleep(Duration::from_millis(50));
    }

    sink.sleep_until_end();
    if song_history[1].len() >= 1 {
        let song_index = song_history[1][song_history[1].len()-1];
        song_history[1].pop();
        music_player(music_list, debug_mode,song_history, song_index/*&mut rng*/);

    } else {
        random_passer(music_list, debug_mode,song_history, /*&mut rng*/);
    }
    // Logic to skip to the next track, adjust `current_index` as needed

// The sound plays in a separate thread. This call will block the current thread until the sink
// has finished playing all its queued sounds.
}

This code fixes my issue and allows me to traverse my song queue however when I ran it I notices that my metadata is no longer updated

How I tried fixing the issue:

First of all I made sure my variables (title, artist, album_url, duration) were being updated and they were. I tried-making sure metadata is ran so I put it in a loop repeating several times, I tried putting it above the mediakey listener but that just broke it, I tried putting the varaible (let mut controls = MediaControls::new(config).unwrap();) in a loop several times and it did not worked. As of now no solutions that I thought of have worked.

I would like to thank you for all the help in advance :)

Sinono3 commented 6 months ago

Hi! Can you create a branch in your repository reproducing the bug? Have you tried using the use_zbus feature in souvlaki?

jernejmarcic commented 6 months ago

Hello main branch in my repo does have the bug you can try to use the program yourself (cargo install --git https://github.com/jernejmarcic/RustyPlayer if you have Linux) therefore you can just run it you will be able to reproduce the error after you skip to the next track. As you can see on this image when I initially run the program the metadata is correct: 20240302_15h35m06s_grim

then when I skip to the next song (which re-runs the function that is ran when the program starts) the metadata is still of the first song that is played when the program is initially run: 20240302_15h35m27s_grim 20240302_15h36m10s_grim

Here is when the metadata still worked: https://github.com/jernejmarcic/RustyPlayer/tree/d0873d8fe29b7a7d4a71c4a573f9179e651ccf1f. I will try to use z-bus and raport

jernejmarcic commented 6 months ago

Tried using zbus (souvlaki = { version = "0.7.3", default-features = false, features = ["use_zbus"] }) however that causes my an error during compile:

error[E0432]: unresolved import `nix::unistd::Uid`
  --> /home/jernej/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zbus-3.14.1/src/address.rs:9:5
   |
9  | use nix::unistd::Uid;
   |     ^^^^^^^^^^^^^^^^ no `Uid` in `unistd`
   |
note: found an item that was configured out
  --> /home/jernej/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nix-0.26.4/src/unistd.rs:73:12
   |
73 | pub struct Uid(uid_t);
   |            ^^^
   = note: the item is gated behind the `user` feature

If I instead do use_dbus I get no errors, however my metedata does not get updated.

Sinono3 commented 6 months ago

Ok. I have my suspicions about why the dbus-crossroads backend isn't working. Still, try running cargo update after changing to zbus and see if it working then (it works on my machine).

jernejmarcic commented 6 months ago

updated it and this time it did not crash, however when I run my program and for example skip to the next song I have get this error (I ran it with RUST_BACKTRACE=full). Also it still only displays the metadata from the song it plays after running. The media keys despite this error continue to work.

Is there any debugging or changes to my code I should to to make it easier for you?

thread '<unnamed>' panicked at /home/jernej/.cargo/registry/src/index.crates.io-6f17d22bba15001f/souvlaki-0.7.3/src/platform/mpris/zbus.rs:100:22:
called `Result::unwrap()` on an `Err` value: NameTaken
stack backtrace:
   0:     0x5a41c792cd3c - std::backtrace_rs::backtrace::libunwind::trace::ha69d38c49f1bf263
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x5a41c792cd3c - std::backtrace_rs::backtrace::trace_unsynchronized::h93125d0b85fd543c
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x5a41c792cd3c - std::sys_common::backtrace::_print_fmt::h8d65f438e8343444
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x5a41c792cd3c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h41751d2af6c8033a
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x5a41c7959ecc - core::fmt::rt::Argument::fmt::h5db2f552d8a28f63
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/rt.rs:138:9
   5:     0x5a41c7959ecc - core::fmt::write::h99465148a27e4883
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/mod.rs:1114:21
   6:     0x5a41c79290ce - std::io::Write::write_fmt::hee8dfd57bd179ab2
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/io/mod.rs:1763:15
   7:     0x5a41c792cb24 - std::sys_common::backtrace::_print::h019a3cee3e814da4
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x5a41c792cb24 - std::sys_common::backtrace::print::h55694121c2ddf918
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x5a41c792e193 - std::panicking::default_hook::{{closure}}::h29cbe3da3891b0b0
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:272:22
  10:     0x5a41c792deb4 - std::panicking::default_hook::h881e76b2b8c74280
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:292:9
  11:     0x5a41c792e715 - std::panicking::rust_panic_with_hook::hcc36e25b6e33969c
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:731:13
  12:     0x5a41c792e611 - std::panicking::begin_panic_handler::{{closure}}::ha415efb0f69f41f9
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:609:13
  13:     0x5a41c792d266 - std::sys_common::backtrace::__rust_end_short_backtrace::h395fe90f99451e4e
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:170:18
  14:     0x5a41c792e362 - rust_begin_unwind
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
  15:     0x5a41c7042fb5 - core::panicking::panic_fmt::h452a83e54ecd764e
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
  16:     0x5a41c7043583 - core::result::unwrap_failed::hed0fccbe07e724fc
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
  17:     0x5a41c70e98ad - core::result::Result<T,E>::unwrap::h4b9d9c485aa66dad
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1077:23
  18:     0x5a41c70ef800 - souvlaki::platform::platform::zbus::MediaControls::attach::{{closure}}::h7ca1327dbb556bb4
                               at /home/jernej/.cargo/registry/src/index.crates.io-6f17d22bba15001f/souvlaki-0.7.3/src/platform/mpris/zbus.rs:99:17
  19:     0x5a41c70cfcb6 - std::sys_common::backtrace::__rust_begin_short_backtrace::h241aa8a3f1df878a
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:154:18
  20:     0x5a41c70b2f5c - std::thread::Builder::spawn_unchecked_::{{closure}}::{{closure}}::h9f66f48474faab34
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/thread/mod.rs:529:17
  21:     0x5a41c70ffa40 - <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h4d6d3116ebad8517
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panic/unwind_safe.rs:271:9
  22:     0x5a41c70b304a - std::panicking::try::do_call::h353543ce1783b972
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:504:40
  23:     0x5a41c70b30fb - __rust_try
  24:     0x5a41c70b2fc2 - std::panicking::try::h17f16b51319d6545
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:468:19
  25:     0x5a41c70b2d9d - std::panic::catch_unwind::h10e5b23fb2673eb2
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panic.rs:142:14
  26:     0x5a41c70b2d9d - std::thread::Builder::spawn_unchecked_::{{closure}}::h77ad5f5cafec4010
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/thread/mod.rs:528:30
  27:     0x5a41c708e2ae - core::ops::function::FnOnce::call_once{{vtable.shim}}::h7533c118b76878df
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/ops/function.rs:250:5
  28:     0x5a41c7933865 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h51435299acd7166e
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/alloc/src/boxed.rs:2007:9
  29:     0x5a41c7933865 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h3f833c0a4926bdd4
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/alloc/src/boxed.rs:2007:9
  30:     0x5a41c7933865 - std::sys::unix::thread::Thread::new::thread_start::h2c486d0230ab0d99
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys/unix/thread.rs:108:17
  31:     0x750ce716f55a - <unknown>
  32:     0x750ce71eca3c - <unknown>
  33:                0x0 - <unknown>
Sinono3 commented 6 months ago

That error may occur because you have a process of the music player running in the background. Try doing pkill -9 <name of your executable>

jernejmarcic commented 6 months ago

My program does not have any slaves, it re-runs, if I pkill it then the whole program stops. However tryinig this and looking for processes has alerted me to my programs extreme memory usage hopefully fixing that issue will fix the metadata issue as well

jernejmarcic commented 6 months ago

I was a brain-dead moron and I had a skill issue

Sinono3 commented 6 months ago

Hahah, don't beat yourself up. I'm curious, what was the issue?

jernejmarcic commented 6 months ago

I had a recursion loop, I had a function call itself recursively where it ran itself inside itself, ate 5mb of RAM every time that happened. Fixed it by having it be a loop instead