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

Moviepy on centos server generates the video but the texts aren't visible. #1647

Closed
thankblitz opened this issue Aug 21, 2021 · 12 comments
Closed
Labels
bug Issues that report (apparent) bugs. lib-ImageMagick Issues pertaining to dependency ImageMagick.

Comments

@thankblitz
Copy link

thankblitz commented Aug 21, 2021

Expected Behavior

The code mentioned the steps to reproduce section works fine on my macbook and generates the video as expected. Whereas when I run the same code on a centos7 server, while the movie is getting generated the text portion isn't visible at all. It is displayed as white dots as you can see in the attachment.

Actual Behavior

The code works on centos7 server and generates the mp4 file but the texts aren't rendered as can be seen in the screenshot below
moviepy-not-working-screenshot

Steps to Reproduce the Problem

Run the code below with the following testinput. You might need any background image and audio file in a res folder.

testInput = [
    {
    #"imageURL" : "res/testImage1.jpg",
    "greeting" : {
        "from" : "Anna",
        "to" : "Alex",
        "message" : "test message 1"
        }
    }]

def generateVideo(clipConfigurations):
    clips = []
    for clipConfig in clipConfigurations:
        clip = generateClip(clipConfig)
        if clip != None:
            clips.append(clip)

    output = concatenate_videoclips(clips, method="compose")

    audio = AudioFileClip("res/audio.mp3")

    output.audio = audio
    output = output.set_duration(5 * len(clips))

    output.write_videofile("output.mp4", audio_codec="aac", fps=24)

    return None


"""
    Generate a single clip containing one greeting card and message
"""
def generateClip(clipConfiguration):
    if (clipConfigurationCorrect(clipConfiguration)):
        imageURL = clipConfiguration.get("imageUrl")

        image = ImageClip(imageURL)
        image = image.set_duration(5)

        image = image.resize(height=600, width=600)
        image = image.set_position((50, "center"))

        fromText = TextClip("From: " + clipConfiguration.get("from"), fontsize=70, color="white")
        fromText = fromText.set_position((800, 320))
        fromText = fromText.set_duration(5)

        toText = TextClip("To: " + clipConfiguration.get("to"), fontsize=70, color="white")
        toText = toText.set_position((800, 390))
        toText = toText.set_duration(5)

        message = TextClip(clipConfiguration.get("message"), fontsize=70, color="white", method="caption", align="West", size=(1000, None))
        message = message.set_position((800, 610))
        message = message.set_duration(5)

        backgroundImage = ImageClip("res/background.png")
        backgroundImage = backgroundImage.set_duration(5)

        return CompositeVideoClip([backgroundImage, image, fromText, toText, message])

    return None



def clipConfigurationCorrect(input):
    keysToCheck = ["imageUrl","from", "to", "message"]
    hasError = False
    for key in keysToCheck:
        if key in input:
            print("key: " + "'" + key + "'" + "exists")
        else:
            print("key: " + "'" + key + "'" + " does not exist in input dictionary")
            hasError = True

    if hasError:
        print("====input=====")
        print(input)
        return False

    return True

generateVideo(testInput)

Specifications

  • Python Version: Python 3.6.8
  • Moviepy Version: moviepy==1.0.3
  • Platform Name: Centos7
  • Platform Version:
@thankblitz thankblitz added the bug Issues that report (apparent) bugs. label Aug 21, 2021
@thankblitz
Copy link
Author

I have also tried this same on amazon linux image and still the same issue :(

@thankblitz
Copy link
Author

I have narrowed it down to just the text rendering. I have simplified the code as below.

from moviepy.editor import *

image = ImageClip("res/pagan.png")
image = image.set_duration(5)
image = image.set_position((50, "center"))

backgroundImage = ImageClip("res/background.png")
backgroundImage = backgroundImage.set_duration(5)

fromText = TextClip("From: " , fontsize=70, color="white")
fromText = fromText.set_position((800, 320))
fromText = fromText.set_duration(5)

comp =  CompositeVideoClip([backgroundImage, image, fromText])

output = comp.set_duration(5)
output.write_videofile("tmp.mp4", audio_codec="aac", fps=24)

The same on mac returns this video below

tmp.mp4

Whereas the same on amazon linux or centos returns the following

tmp_from_nonmac.mp4

And I am completely clueless!

@thankblitz
Copy link
Author


text_clip = TextClip(txt="Python is Awesome!",
                     fontsize=40,
                     color="black",     # Font color
                     bg_color="aqua")   # Background color
text_clip.save_frame("out.png")

The above code is rendered as follows on amazon linux

out

Definitely something wrong with the TextClip.

@thankblitz
Copy link
Author

I tried debugging further debugging with PIL. The PIL ImageDraw works perfectly fine with the following code

from PIL import Image, ImageDraw, ImageFont

# create an image
out = Image.new("RGB", (150, 100), (255, 255, 255))

# get a font
fnt = ImageFont.truetype("DejaVuSans-BoldOblique.ttf", 40)
# get a drawing context
d = ImageDraw.Draw(out)

# draw multiline text
d.multiline_text((10,10), "Hello\nWorld", font=fnt, fill=(0, 0, 0))

im1 = out.save("geeks.jpg")

Not sure which part of the PIL with TextClip is not rendering :(

geeks

@thankblitz
Copy link
Author

I think the issue is with the convert function (Imagemagick). With print_cmd = True, I was able to replicate the behaviour with the following command

convert -background transparent -fill white -font AvantGarde-Book -pointsize 70 -gravity center label:@/tmp/tmptxt -type truecolormatte PNG32:/tmp/tmpnhr3on5x.png

Something to do with imagemagick. Version below

$ convert -version
Version: ImageMagick 6.9.10-68 Q16 x86_64 2021-02-02 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP(4.5) 
Delegates (built-in): bzlib cairo fontconfig freetype gslib jng jp2 jpeg lcms ltdl lzma openexr pangocairo png ps rsvg tiff wmf x xml zlib

@mondeja
Copy link
Collaborator

mondeja commented Aug 23, 2021

Please, compare ImageMagick installations in both platforms.

@thankblitz
Copy link
Author

Yup I did just now. My mac was running 7.1.0. So I tried installing the 7.1.0 and the following command works via commandline

[ec2-user@ip-172-31-42-30 ~]$ magick convert -background transparent -fill white -font /usr/share/fonts/urw-base35/Z003-MediumItalic.otf -pointsize 70 -gravity center label:@/tmp/tmptxt -type truecolormatte PNG32:/tmp/tmpnhr3on5x.png ^C
[ec2-user@ip-172-31-42-30 ~]$ magick -version
Version: ImageMagick 7.1.0-6 Q16 x86_64 2021-08-22 https://imagemagick.org
Copyright: (C) 1999-2021 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5) 
Delegates (built-in): bzlib freetype jng jpeg png tiff x zlib
[ec2-user@ip-172-31-42-30 ~]$ 

As you can see I had to use magick convert instead of convert which seems to work but I have to supply full path to the font atleast via commandline. How can I make moviepy use imagemagick as above?

@mondeja
Copy link
Collaborator

mondeja commented Aug 23, 2021

How can I make moviepy use imagemagick as above?

Are you referring to use magick convert or to supply the full path to the font?

@thankblitz
Copy link
Author

Actually both. I tried something like this export IMAGEMAGICK_BINARY=/usr/local/bin/magick which didn't work.

/usr/local/bin/magick -background transparent -fill white -font AvantGarde-Book -pointsize 70 -gravity center label:@/tmp/tmptxt -type truecolormatte PNG32:/tmp/tmpvjua5chs.png
Traceback (most recent call last):
  File "/home/ec2-user/.local/lib/python3.7/site-packages/moviepy/video/VideoClip.py", line 1137, in __init__
    subprocess_call(cmd, logger=None)
  File "/home/ec2-user/.local/lib/python3.7/site-packages/moviepy/tools.py", line 54, in subprocess_call
    raise IOError(err.decode('utf8'))
OSError: magick: unable to read font `AvantGarde-Book' @ warning/annotate.c/RenderType/971.
magick: unable to read font `AvantGarde-Book' @ error/annotate.c/RenderFreetype/1425.
magick: unable to read font `AvantGarde-Book' @ warning/annotate.c/RenderType/971.
magick: unable to read font `AvantGarde-Book' @ error/annotate.c/RenderFreetype/1425.


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test2.py", line 13, in <module>
    fromText = TextClip("From: " , fontsize=70, color="white", font="AvantGarde-Book",temptxt='/tmp/tmptxt',print_cmd=True)
  File "/home/ec2-user/.local/lib/python3.7/site-packages/moviepy/video/VideoClip.py", line 1146, in __init__
    raise IOError(error)
OSError: MoviePy Error: creation of None failed because of the following error:

magick: unable to read font `AvantGarde-Book' @ warning/annotate.c/RenderType/971.
magick: unable to read font `AvantGarde-Book' @ error/annotate.c/RenderFreetype/1425.
magick: unable to read font `AvantGarde-Book' @ warning/annotate.c/RenderType/971.
magick: unable to read font `AvantGarde-Book' @ error/annotate.c/RenderFreetype/1425.
.

.This error can be due to the fact that ImageMagick is not installed on 

@mondeja
Copy link
Collaborator

mondeja commented Aug 23, 2021

Use font argument of TextClip to supply the full path to the font. You can create an alias to resolve convert to magick convert, something like alias convert='/usr/local/bin/magick convert' in ~/.bashrc or equivalent file.

@thankblitz
Copy link
Author

Yup that worked. So much difference between the imagemagick versions :) Looks like I need to play around with imagemagick config/policy.xml to find the path for fonts automatically. I think it is worth updating moviepy documentation to use ImageMagick 7.1.0.

@mondeja
Copy link
Collaborator

mondeja commented Aug 23, 2021

I think it is worth updating moviepy documentation to use ImageMagick 7.1.0.

There is a plan to remove ImageMagick in new 2.0.0, discussed in #1472, but it should wait because the current maintainers don't have enough time to work on this. That's the reason because any work related with ImageMagick will be useless after it. If you consider it useful, don't hesitate to open a PR 👍

@mondeja mondeja closed this as completed Aug 23, 2021
@keikoro keikoro added the lib-ImageMagick Issues pertaining to dependency ImageMagick. label Oct 24, 2021
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. lib-ImageMagick Issues pertaining to dependency ImageMagick.
Projects
None yet
Development

No branches or pull requests

3 participants