MonoS / SupMover

SupMover - Shift timings and Screen Area of PGS/Sup subtitle
GNU Affero General Public License v3.0
39 stars 4 forks source link

Add move functionality #12

Closed YourMJK closed 5 months ago

YourMJK commented 5 months ago

Added a new move mode for shifting the position of all windows and their composition objects by the specified delta amount, clamped to keep the window rect fully contained within the screen rect. Should work with crop flag enabled as well, but not tested.

Motivation for adding this mode was the issue that e.g. moving subtitles out of the lower letterbox area with the current crop mode results in all images having their bottom edge aligned with the bottom edge of the crop rect, which doesn't necessarily keep the relative position of subtitle lines. This means that baselines of consecutive subtitle lines aren't always aligned (e.g. if one line has a letter with a descender — like lowercase g — while the next line doesn't), which negatively effects reading experience. This new move mode avoids this issue by keeping the relative positions of images the same (unless it hits a screen edge).

(I also observed that the current crop mode also changes the scaling of the images in most players in addition to the position which is not acceptable in my case)

MonoS commented 5 months ago

Thank you, the idea is sound but it's based on some assumption that are not true, for example your solution will only work when all subpicture are close to the same border and are outside the new screen area, in my experience subtitle may be stationed near all corner of the screen, on the middle and not always the subpic is outside the screen area, for example on a 1920x1080->1920x800 conversion the subtitle may already be on the x800 section, and in that case we won't need to move them.

What you are looking for is something similar to what you have implemented but based on a different working principle. What I was thinking was to calculate the distance between the original subpic position and the original screen rectangle on the sides we are cropping and reapply this distance after the crop, maybe rescaled to the new screen dimension, as an example let's assume we have this subpic at the bottom of the screen with a 20px distance to the border and we are cropping from 1080 to 800, a 74% reduction, we first apply the crop moving the subpic right on the border and then apply a 15px move from the bottom, in that way it should work independently to where the subpics are being moved.

What do you think?

(I also observed that the current crop mode also changes the scaling of the images in most players in addition to the position which is not acceptable in my case)

Could you send me the original subtitle file and the crop parameter you are applying? In theory the crop functionality was implemented to AVOID such a behavior from the video player

YourMJK commented 5 months ago

A visual example to illustrate what my issue is and why the current crop functionality doesn't fix it

I have 1920x696 content centered in a 1920x1080 video with subtitles, which all currently appear in the lower black letterbox bar.

I created these screenshots with IINA (mpv). It looks the same in other players (in VLC the crop case is only scaled vertically and not horizontally as well).

Could you send me the original subtitle file and the crop parameter you are applying?

This is also the original subtitle file depicted in the screenshot (see above for crop parameters): orig.sup.zip (timestamps of my example frames are 1468.425 and 1472.012)


Your suggestion

let's assume we have this subpic at the bottom of the screen with a 20px distance to the border and we are cropping from 1080 to 800, a 74% reduction, we first apply the crop moving the subpic right on the border and then apply a 15px move from the bottom, in that way it should work independently to where the subpics are being moved.

If I understand your suggestion right, this again wouldn't necessarily keep the baselines aligned. The bottom edge of the subpic is then always 15px from the bottom edge of the new crop area, but since the subpics vary in height and the text is usually anchored to the top, the baseline of the text isn't always the same distance to the bottom of the subpic. So the distance between the new bottom screen edge and the baselines won't be the same: baselines


My solution

the idea is sound but it's based on some assumption that are not true, for example your solution will only work when all subpicture are close to the same border and are outside the new screen area

I'm not exactly sure what you mean here.

My solution is to leave the screen area unchanged and instead translate the whole coordinate system by the delta-values (in my case just a few pixels up). This keeps the relative distances the same as in the original (meaning baselines stay aligned) and is only a "problem" when you have subtitles on the top as well as on the bottom. In my case subtitles on the top (which my example file doesn't have) would move further into the upper letterbox bar but since I'm clamping their position individually, I can make sure that they never leave the 1920x1080 screen area.


Alternative solution

An alternative which I just thought of: You could instead change the implementation for crop (or implement a new mode) to move subtitles inward, i.e. towards the center. For example subtitles in the lower screen half move upwards and subtitles in the upper half move downwards. Subtitles that intersect the center line could stay where they are.

I'm not a huge fan of this idea, I prefer the manual flexibility of my move mode. In my case, I know exactly that I just want to move all subtitles upwards a few pixels and that there aren't any other subtitles for which this could be an issue.

MonoS commented 5 months ago

It looks the same in other players (in VLC the crop case is only scaled vertically and not horizontally as well).

I've analyzed the behavior of the player, those are scaling the internal subtitle resolution to the video resolution, VLC does an uneven scaling while other seems to do a proportional scaling, hence the stretched vertically subtitle. This functionality was introduced when encoding a video with black bars in that case the result is quite different, for example here i've created a 1920x696 video and muxed both original and cropped subtitle testsup.crop.mkv.zip Original vlcsnap-2024-01-30-15h38m07s755 Cropped vlcsnap-2024-01-30-15h38m19s750 As you can see, when using a cropped video, the Original is squished, while the Cropped is displayed "properly" (excluding the uneven baselines)

If I understand your suggestion right, this again wouldn't necessarily keep the baselines aligned.

For that i'll need to experiment, it is indeed possible that my idea does not handle all the case, i think your idea of "moving" everything towards the center may be the best one, but, again, i'll need to thinker with it a bit to understand how to best handle the baselines issue.

I'm not a huge fan of this idea, I prefer the manual flexibility of my move mode.

Yeah, your implementation is doing exactly what you're asking and will work fine when: 1) you are not cropping the video 2) the subtitle position subpic only on one side on the screen; in all other case it may not do what one expect.

In any case i don't see any issue in merging it, thank you for your contribution and my apologies for those wall of text :)

YourMJK commented 5 months ago

As you can see, when using a cropped video, the Original is squished, while the Cropped is displayed "properly" (excluding the uneven baselines)

Now I get how the crop mode is actually supposed to be used in a workflow, I think! That makes way more sense. It's basically like an anamorphic lens, you stretch the subtitle so that when you later mux it with an already cropped video, the player squishes it by the same inverse amount which results in the scaling essentially being undone. And additionally, you move everything within the new screen area. Is that right?

My workflow is different (which is probably why I made wrong assumptions), I just mux it with the original uncropped 1920x1080 video again and set MKV cropping metadata. Then some time later I let ffmpeg automatically overlay video and subtitle, burn it into the video and then apply the crop.


your implementation is doing exactly what you're asking and will work fine when: 1) you are not cropping the video 2) the subtitle position subpic only on one side on the screen; in all other case it may not do what one expect.

Yeah, it's not really intelligent but rather quite "low level". But I thought it would fit this tool since it also has the delay mode, which is essentially the same as my move but in the time dimension and not 2D-space dimensions. That gives my the idea for a suggestion of a new subtitle: "SupMover – Shift PGS/Sup subtitles in time and space" ;)

thank you for your contribution and my apologies for those wall of text :)

No worries, it was fun and I learned something about how players handle PGS subs :) I really like the idea of this tool in that it just changes the necessary bytes instead of parsing the input into a PGS-independent format and then generating a completely new PGS, like some others.

MonoS commented 5 months ago

Is that right?

Nope, the stretching is done by the player to match the subtitle resolution to the video resolution, the subtitle picture are maintained unchanged by this application, as you correctly stated at the end, only moved according to the crop/move parameters. In your case you cropped the subtitle but not the video, so it appeared stretched because the player decided that way, hence the difference between mvp and VLC.

That gives my the idea for a suggestion of a new subtitle: "SupMover – Shift PGS/Sup subtitles in time and space" ;)

I may borrow that one ;)

I really like the idea of this tool in that it just changes the necessary bytes instead of parsing the input into a PGS-independent format and then generating a completely new PGS, like some others.

That's the main reason why I've implemented the crop functionality, before that i used BDSup2Sub but it can introduce some artifact as it decodes the image to png, scale it and then reconvert it to sup, as sup are limited to 256 color palettes a lot of quantization error were introduced, from invisible to extremely noticeable, and in some cases even breaking the images