Issues using ImageMagick to create subtitles using moviepy

Question:
I’m getting consistent errors when generating subtitles using moviepy, pointing to imagemagick not being installed correctly. Here’s an example of the error text:

2023-11-28 20:27:17.902 Uncaught app exception
Traceback (most recent call last):
  File "/home/runner/Subtitle-Tool/venv/lib/python3.10/site-packages/moviepy/video/VideoClip.py", line 1137, in __init__
    subprocess_call(cmd, logger=None)
  File "/home/runner/Subtitle-Tool/venv/lib/python3.10/site-packages/moviepy/tools.py", line 54, in subprocess_call
    raise IOError(err.decode('utf8'))
OSError: convert: unable to read font `Sans' @ warning/annotate.c/RenderType/1015.
convert: unable to read font `Sans' @ error/annotate.c/RenderFreetype/1616.
convert: no images defined `PNG32:/tmp/tmpjqqzhipu.png' @ error/convert.c/ConvertImageCommand/3342.


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/runner/Subtitle-Tool/venv/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 565, in _run_script
    exec(code, module.__dict__)
  File "/home/runner/Subtitle-Tool/main.py", line 20, in <module>
    final_video = create_video(video_file, caption_file)
  File "/home/runner/Subtitle-Tool/funcs.py", line 107, in create_video
    subtitles = SubtitlesClip(subtitle_temp_path,
  File "/home/runner/Subtitle-Tool/venv/lib/python3.10/site-packages/moviepy/video/tools/subtitles.py", line 86, in __init__
    hasmask = bool(self.make_textclip('T').mask)
  File "/home/runner/Subtitle-Tool/funcs.py", line 108, in <lambda>
    make_textclip=lambda txt: custom_text_clip(txt))
  File "/home/runner/Subtitle-Tool/funcs.py", line 81, in custom_text_clip
    return TextClip(txt.upper(),
  File "/home/runner/Subtitle-Tool/venv/lib/python3.10/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:

convert: unable to read font `Sans' @ warning/annotate.c/RenderType/1015.
convert: unable to read font `Sans' @ error/annotate.c/RenderFreetype/1616.
convert: no images defined `PNG32:/tmp/tmpjqqzhipu.png' @ error/convert.c/ConvertImageCommand/3342.
.

.This error can be due to the fact that ImageMagick is not installed on your computer, or (for Windows users) that you didn't specify the path to the ImageMagick binary in file conf.py, or that the path you specified is incorrect

Here is where the error is triggered in my code:

# subtitle styling
def custom_text_clip(txt,
                     txt_color='white',
                     font_size=24,
                     font='Sans',
                     shadow_color='black'):
  # Create a TextClip with the specified style
  return TextClip(txt.upper(),
                  fontsize=font_size,
                  font=font,
                  color=txt_color,
                  stroke_color=shadow_color,
                  stroke_width=1)

I have added imagemagick to my nix file but it is not solving the problem, here is my replit.nix:

{ pkgs }: {
  deps = [
    pkgs.python310Full
    pkgs.replitPackages.prybar-python310
    pkgs.replitPackages.stderred
    pkgs.imagemagick
  ];
  env = {
    PYTHON_LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
      # Needed for pandas / numpy
      pkgs.stdenv.cc.cc.lib
      pkgs.zlib
      # Needed for pygame
      pkgs.glib
      # Needed for matplotlib
      pkgs.xorg.libX11
    ];
    PYTHONHOME = "${pkgs.python310Full}";
    PYTHONBIN = "${pkgs.python310Full}/bin/python3.10";
    LANG = "en_US.UTF-8";
    STDERREDBIN = "${pkgs.replitPackages.stderred}/bin/stderred";
    PRYBAR_PYTHON_BIN = "${pkgs.replitPackages.prybar-python310}/bin/prybar-python310";
  };
}

Has anyone else successfully used moviepy to burn subtitles onto a video within Replit?

Hey @flixr!

Can you please provide a link to the repl? This way it is easier for staff and members of the community to help you!

Also see this guide on how to share your code:

I think there are two solutions:

1 .
Move your code to a newer repl if possible because the configuration and installation of packages is often more stable.
A recently made packager feature should auto install the relevant system dependencies for moviepy when you install it with the Packages tab or poetry add <pkg>
You could also maybe manually install all dependencies.

2 .
Inside your replit.nix, you should replace the pkgs.imagemagick with pkgs.python310Packages.moviepy . Then, open .replit and insert disableGuessImports = true near the top, because the packager doesn’t see this package. (I think you should still move your code to a new repl.)

1 Like

@SalladShooter
Sure, here it is: https://replit.com/@flixr/MagicSubs#funcs.py

@NuclearPasta0 thx for suggestions. I moved to a new repl and made those changes but still get the same error unfortunately.

Okay. It actually seems like the relevant system dependencies were not automatically installed. (the feature must be buggy or something)
Try this:
On the new repl (or a fork), using the System Dependencies tool, search “moviepy” and install the python 3.10 version. (If there is no search in the tool, you’ll use a different method.)
Test the package to make sure it works. Print out the package’s __file__ attribute to make sure it is somewhere in /nix/store, not .pythonlibs.
Do note that this version of the package will not be seen by the package manager, poetry.

1 Like

And what is this method? It was not mentioned.

The method is just creating the nix file, using the “template” nix found in older repls, and filling deps. But it shouldn’t be necessary anymore because you can now search and install via System Dependencies tool (it used to be readonly or not exist).

1 Like