mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
27.94k stars 2.87k forks source link

Changing video pan always happens before playlist-next #7293

Open noctuid opened 4 years ago

noctuid commented 4 years ago

mpv version and platform

Mpv master on linux (Arch)

Reproduction steps

I am trying out mpv as an image viewer and would like to setup keybindings for reading comics. For example I want to have a key to go to the bottom of the current image then go to the top of the next image on the next press (and so on). I have this working, but the problem is that playlist-next always happens after changing video-pan-y (or other settings like video-zoom), which is disorienting.

Basic example with this in input.conf

ctrl+a no-osd add video-pan-y -0.1
ctrl+SPACE playlist-next; no-osd set video-pan-y 0

Open a directory with mpv that just contains images and pause playback. Press ctrl+a a few times and then press ctrl+SPACE.

Expected behavior

Mpv goes to the next image and then sets video-pan-y to 0.

Actual behavior

Mpv sets video-pan-y to 0 for the current image before going to the next image, causing flashing/flickering. This seems to be a lot more noticeable if I have a lot of scripts in the scripts directory (i.e. longer delay between pan and playlist-next), but it is still noticeable without any.

I tried various ways in a script of getting this to work without success (e.g. separate mp.command or mp.set_property_number calls). It would be nice if there was some way to switch to the next image in a playlist and then afterwards change a setting like video-pan-y with a single keybinding.

Log file

out.txt

ghost commented 4 years ago

That's just how it works currently. playlist-next only starts going to the next file (which happens asynchronously for multiple reasons). video-pan is run and applied while the old file is still active.

You could either pass the pan options to --reset-on-next-file (but not sure if that really resets them at a point you want), or you could use scripting and try to wait for the right event or property change (trying to apply the option directly after the command will result in the same behavior as using input.conf bindings). With some effort, I could also make playlist-next blocking - then it'll probably behave similar to using --reset-on-next-file.

In general, it's not possible to make this flicker-free, because the VO (aka the window) is kept open between the files. The VO is updated with the new image at some random moment after the new file is loaded. Although a script could probably catch this moment, there's no mechanism to really set the zooming/scaling parameters synchronously.

noctuid commented 4 years ago

You could either pass the pan options to --reset-on-next-file (but not sure if that really resets them at a point you want)

Yeah the behavior is the same with --reset-on-next-file=video-pan-y (pan happens while old image is being displayed).

Although a script could probably catch this moment

Any idea on a way to do this?

ghost commented 4 years ago

If the image dimensions (or other properties) are different, observing video-out-params with the native format might work. Haven't tried it.

But as I said, there's no good way to get it race condition free. (Although I may have some ideas to achieve almost what you want. But it'd be messy and weird, would require code changes, and I'd do it only if nothing else works for you and if I feel like it.)

noctuid commented 4 years ago

Yeah, observing video-out-params and looking for changes does let me change video-pan-y after a new image is displayed but has the same problem on the other end (the change to video-pan-y happens after new image is displayed, causing flicker; I think that's what you meant by there being no way to make it flicker free?). Also, the properties in video-out-params generally don't change for comics.

Ideally it would be possible to set the pan, zoom, or whatever for the next playlist entry to be displayed with instead of changing it afterwards or before on the previous entry. I'm guessing there's no good way to do this currently then?

Edit: Changing video-pan-y with an on_load hook causes flicker. Temporarily changing the pan for the current file by setting file-local-options/video-pan-y also causes flicker when going to the next file. I can't think of anything else.

noctuid commented 4 years ago

So I messed around with this some more with a horrible idea for a hack. If I add a file (or multiple files) that matches mpv's background (completely black) in between images I can at least reduce the flickering by observing video params, changing the pan on the black file, and then going to actual next item in the playlist. I could probably write a hacky script to insert/remove images like this, but it seems like a terrible idea.

Although I may have some ideas to achieve almost what you want. But it'd be messy and weird, would require code changes, and I'd do it only if nothing else works for you and if I feel like it.

Could you elaborate on the ideas you had about handling this?

Dudemanguy commented 3 years ago

I dunno if you're still working on this or not but I accidentally solved flicker issues in my manga reader script by using the on_preloaded hook. In there you should be able to set the pan and whatnot before the next image actually loads and I think that eliminates visible flickering. Didn't test your case but at least it eliminated flickering for me when changing the lavfi-complex property.

noctuid commented 3 years ago

Maybe that improves it slightly (I can't tell), but there is definitely still flicker for me when changing the pan. The functions I want to use to set the pan correctly also rely on video-out-params which isn't available in that hook. I've tried events too. As far as I can tell, there is no workaround without a change to mpv.

I'm not sure how continuous mode works in your script (it fails to activate for me), but do you think I could get something similar to what I want working with it (key to show top of page, then bottom of page, then top of next page)?

Dudemanguy commented 3 years ago

How are we defining "flicker" here in this case? I just briefly hacked in setting the video-pan-y to 0 in the on_preloaded hook, did some pans and then flipped pages. Visually, I think I see exactly mpv going to the next image first and then setting the pan to 0. Now I guess there is a "flicker" of some sort since you can see the pan happen but I think the order is correct. I suppose what you actually want is for the pan (and other similar operations) to happen in that perfect black space in-between images. Sounds really unfeasible but I'm not sure.

rely on video-out-params which isn't available in that hook

That would definitely render my suggestion pointless though since there is no video at that point.

key to show top of page, then bottom of page, then top of next page

Sure it's possible with using video-align-y and switching pages as appropriate.

noctuid commented 3 years ago

Right, the order changes depending on what you observe or what event you use (e.g. I previously mentioned observing video-out-params which also pans afterwards), but I wouldn't call either order "correct." The correct order to prevent flicker would have to be unload, load but not display (so video-out-params and other properties are available), set pan/zoom/whatever, and then display. Since this isn't currently possible, there will always be flicker. Pqiv, for example, can set the pan for the next image without flicker. Besides for comics, this would also be useful to store/restore or reset video zoom and pan values for images in general, but it just looks too glitchy currently. I'll stick with a dedicated image viewer for now.