j-holub / Node-MPV

A NodeJs Module for MPV Player
https://www.npmjs.com/package/node-mpv
MIT License
116 stars 73 forks source link

stopped event not triggering on song end #55

Closed AxelTerizaki closed 4 years ago

AxelTerizaki commented 5 years ago

Hello hello.

I know you're busy but when you're back into coding this I have a new issue for you.

I'm trying to find the right way to determine when mpv is at the end of a video. My main issue is that I'd like to trigger a player ending event on my app, but for that I need to know precisely when mpv has stopped playing.

The problem is that mpv is not triggering the "idle" message which means it has stopped. Instead it pauses at the end of the current video and emits a "pause" event that node-mpv catches. But a pause event isn't exactly what I'm looking for.

I also tried to play with the playback-remaining property, catching it between 1 and 0 seconds and ending the song there if it pauses, but alas, it's not as precise as I'd like...

If you've got any ideas on this, I'm all ears.

j-holub commented 5 years ago

Don't worry, keep those Issues coming :)

I see I see, It's good that you use a lot of videos, because I mainly test it with music and didn't run into that problem yet. MPV's IPC api gives me a hard time in general, it lacks so much and I have to code so many workarounds.

The only thing I can come up with right now is the following:

trigger a quit even if the pause event is triggered and there's no next song and there's only < 0.1 seconds left

I can understand if that's not as precise as you'd like to have it though :(

AxelTerizaki commented 5 years ago

Here's how it worked before for me : After starting a video, I load a new file in append mode (a JPG background). I then tested the statuschange event for the presence of that wallpaper in the filename property to tell if we had reached the end of a song.

After posting this issue I researched a little further and here's what I did :

player.observeProperty('playtime-remaining',16);
    player.observeProperty('eof-reached',17);
    player.on('statuschange', status => {
        if (playerState._playing && status && ((status['playtime-remaining'] !== null && status['playtime-remaining'] >= 0 && status['playtime-remaining'] <= 1 && status.pause) || status['eof-reached']) ) {
            // immediate switch to Playing = false to avoid multiple triggers
            playerState._playing = false;
            playerEnding();
        }
    });

For now it works well and there's no background anymore inbetween songs/videos. the only way I've managed to break it was to hammer the right arrow key during playback. It zooms through songs until it reaches a weird case when the last statuschange I get doesn't meet the right conditions.

Hope that can help someone with the same problem until we can find a better solution :)

AxelTerizaki commented 5 years ago

Also, why I decided to get rid of the background file loading in append mode : in sopme rare cases I couldn't reproduce well, the loading sometimes failed right after the video playback, which left the app in a weird state. I got something like a generic mpv error telling me it was unable to load file or stream.

My guess what that the image file (background) loading happened too fast for mpv to process, right after video file loading and playback, which confused mpv somehow. Might be a bug in node-mpv in how messages are being sent to the IPC, I don't know...

Forgot to say it but I totally understand your isse with mpv's IPC, it's difficult to work with it.

j-holub commented 4 years ago

I know this is almot a year old. So the good news, with the latest commit 2ea53b5fbd4c8e9250712dea55ecca76f22e8d83, your append issue should be gone.

As for this issue, in my cases I never found any problem where the stopped event wasn't precise enough. Do you think it's worth the hassle to implement your fix into the library?

AxelTerizaki commented 4 years ago

The fix I implemented in my app seems to work so far (it's been one year in testing haha) so I think it's safe to close the issue. I'll reopen it if any problem involving this arises again.

I'm not sure how you'd implement my fix into the library though? Reading my code it's mainly the app's job to do this. Of course a library can provide easier methods but...

Well, it's up to you how you'd like to tackle this, if at all.