Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MoviePy2: TextClip transperancy glitch with multiple CompositeVideoClip #2269

Closed
rockfarmor opened this issue Dec 1, 2024 · 10 comments
Closed
Labels
bug Issues that report (apparent) bugs. text Issues dealing with TextClip, SubtitlesClip, or handling of text in general. v2.x Issues based on MoviePy version 2.0 and upwards

Comments

@rockfarmor
Copy link

Expected Behavior

When layering a CompositeVideoClip with a ColorClip and TextClip onto a new CompositeVideoClip with a VideoClip.

The expected result should look like this: (Works in MoviePy version < 2)
image

Actual Behavior

The transperancy of the text shines through the ColorClip
image

Steps to Reproduce the Problem

video = VideoFileClip("movie.mp4")
    
color_clip = ColorClip((500,200), (255,0,0,255)).with_duration(10)

font = "font.ttf"    
txt_clip_with_margin = TextClip(text="Hello", font=font, font_size=72, stroke_color="white", stroke_width=10, margin=(10,5,0,0), text_align="center").with_duration(10)
    
comp1 = CompositeVideoClip([color_clip, txt_clip_with_margin.with_position(("center", "center"))])
comp2 = CompositeVideoClip([video, comp1.with_position(("center", "center"))])
    
comp2.subclipped(0,10).write_videofile("test.mp4")

Specifications

  • Python Version: 3.11.3
  • MoviePy Version: 2.1.1
  • Platform Name: Windows
  • Platform Version: 11
@rockfarmor rockfarmor added the bug Issues that report (apparent) bugs. label Dec 1, 2024
@Glazed
Copy link

Glazed commented Dec 5, 2024

I'm having a similar issue. Not entirely sure it's related, but I'll share here rather than open a new issue.

I have an ImageClip with a composited TextClip. It looks fine if I save it to a file. However, if I concatenate that CompositeVideoClip to a VideoFileClip, the text loses its transparency. (The text is also cut off on the bottom, but that's not my primary concern at the moment.)

from moviepy import *

clip_babycakes = VideoFileClip("Baby Cakes - Buh Buh-Baby Cakes.mp4")\
    .subclipped(0, '00:03.656')

clip_babycakes_still = ImageClip("BabyCakes.png")\
    .with_duration(5)\
    .with_fps(29.97)

txt_some_text= TextClip(
    font="C:/Windows/Fonts/verdana.ttf",
    text="Some Text",
    color="red",
    font_size=50
)\
    .with_duration(5)\
    .with_position("center")

clip_babycakes_still_with_text = CompositeVideoClip([clip_babycakes_still, txt_some_text])
clip_babycakes_still_with_text.write_videofile("clip_babycakes_still_with_text.mp4", codec="libx264")

final_clip = concatenate_videoclips([clip_babycakes, clip_babycakes_still_with_text], method="compose")
final_clip.write_videofile("final_clip.mp4", codec="libx264")

clip_babycakes_still_with_text screenshot:
clip_babycakes_still_with_text

final_clip screenshot:
final_clip

@OsaAjani
Copy link
Collaborator

OsaAjani commented Dec 6, 2024

Well, this seems like two pretty complementary problems ! You should render each other clip and everything will work as intended ^^ !
Seriously though their is indeed a good chance both problems are related. I'll try to take a look when I have some free time. @Zulko if you have some time to take a look before I think this one should be a priority.

@NitroChromium
Copy link

NitroChromium commented Dec 7, 2024

I've run into (what I assume) is the same issue with transparency when using ImageClip rather than TextClip. It seems in this case somehow related to having a background with transparency.

from moviepy import *

square = ImageClip('./square.png').with_position((128, 128))
circle = ImageClip('./circle.png').with_position((256, 192))

# The transparency around the circle eats into the square
comp1 = CompositeVideoClip([square, circle], size=(512, 512))
comp1.save_frame('example1.png')

# With a solid background the circle overlays the square as expected
comp2 = CompositeVideoClip([square, circle], size=(512, 512), bg_color=(64, 64, 64))
comp2.save_frame('example2.png')

# The transparent area of a CompositeVideoClip itself has the same
# effect on another CompositeVideoClip
comp1b = comp1.with_position((0, 256))
comp3 = CompositeVideoClip([comp1, comp1b])
comp3.save_frame('example3.png')
Example images:

The circle's alpha channel deleting part of the square:
example1
No issue when there's a non-transparent background:
example2
The alpha channel of a CompositeVideoClip has the same behaviour:
example3

@OsaAjani
Copy link
Collaborator

OsaAjani commented Dec 7, 2024

I was pretty sure I already see something like that, and apparently I did and posted about it back when working on the V2 migration #2012 (comment)

I will take a deep dive and try to remember what my understanding of the problem was at the time. If anybody want to take a shot at this one maybe take a look at my comment back in the day as a start point.

@keikoro keikoro added text Issues dealing with TextClip, SubtitlesClip, or handling of text in general. v2.x Issues based on MoviePy version 2.0 and upwards labels Dec 8, 2024
@OsaAjani
Copy link
Collaborator

Things are progressing, I'm working on a fix and I think that I'm close to a solution. I still need to fix a problem with first clip transparency, but I'm making good progress. Not only will the changes fix this particular issue for CompositeVideoClip, but it should actually fix the entire transparent video generation bug that crippled moviepy for years.

@claell
Copy link

claell commented Dec 25, 2024

I think I ran into a rather similar issue with nested composite video clips, as well. Maybe this will also be fixed by the work of @OsaAjani. Will try posting some small example, anyway (hopefully will have time for that) for verification.

@claell
Copy link

claell commented Jan 4, 2025

@OsaAjani sorry, took a while to have a look again and compose the test code:

from moviepy import VideoClip, TextClip, ColorClip, CompositeVideoClip


def test_transparency_bug(output_file="test_output.mp4", fps=24, duration=5):
    bg = ColorClip(size=(640, 360), color=(0, 0, 0)).with_duration(duration)

    white_text = TextClip(text="Hello World!", font="C:/Windows/Fonts/Arial.ttf",
                          font_size=60, color="white").with_duration(duration).with_position("center")

    def reveal_mask_frame(t, w, h):
        # 0 at start, 1 at end
        fraction = max(0, min((t / duration), 1))
        import numpy as np
        arr = np.zeros((h, w))
        arr[:, : int(w * fraction)] = 1
        return arr

    w, h = white_text.size

    mask_clip = VideoClip(
        frame_function=lambda t: reveal_mask_frame(t, w, h),
        is_mask=True,
        duration=duration
    )

    color_text = TextClip(text="Hello World!", font="C:/Windows/Fonts/Arial.ttf",
                          font_size=60, color="red").with_duration(duration).with_position("center")
    masked_text = color_text.with_mask(mask_clip)

    final_clip = CompositeVideoClip(
        [bg, white_text, masked_text], size=(640, 360))
    final_clip.write_videofile(output_file, fps=fps)

    # Compose again to highlight the second-clip issue
    second_clip = CompositeVideoClip([bg, final_clip], size=(640, 360))
    second_clip.write_videofile("test_composed_again.mp4", fps=fps)


if __name__ == "__main__":
    test_transparency_bug()

This code first highlights what I believe to be #195 (first video has nice, antialiazed borders for white text, but weird borders for the red overlaid text):

test_output.mp4

Then, the code produces another video using nested CompositeVideoClips, highlighting the more prominent transparent issue (notice that the white text is not there, anymore):

test_composed_again.mp4

I hope that your PR #2307 can fix both, fingers crossed. In any way, many thanks for you working on this. Hopefully, my testing code can give another example to check for robustness.

@OsaAjani
Copy link
Collaborator

OsaAjani commented Jan 4, 2025

Well this is my results, it does fix the second problem but not the first one, I will try to take at look at issue #195 when I can !

test_output.mp4
test_composed_again.mp4

@claell
Copy link

claell commented Jan 5, 2025

Great! Many thanks for testing. Now, I am really looking forward to seeing the release with the transparency fix. 🙂

Also, thanks for trying to look into #195!

@OsaAjani
Copy link
Collaborator

Fixed with v2.1.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issues that report (apparent) bugs. text Issues dealing with TextClip, SubtitlesClip, or handling of text in general. v2.x Issues based on MoviePy version 2.0 and upwards
Projects
None yet
Development

No branches or pull requests

6 participants