I have started a project where I need to use an open source software called MuJoCo Mujoco Documentation. It is a physics simulation software that leans towards RL (reinforcement learning). Since the application I'm working on is to create an AI I also work in python for convinience.
The problem I have is that MuJoCo uses a library called 'mediapy' to visualize sequences of frames (video), and that library in turn uses a library called 'ffmpeg'. The issue is that mediapy dosen't recognize that 'ffmpeg' is installed on my computer (Mac, Intel). When I dove down into the source code to try and find the issue I found that 'mediapy' checks for the installation of 'ffmpeg' by running:
import shutil
import typing
import os
_Path = typing.Union[str, 'os.PathLike[str]']
class _Config:
ffmpeg_name_or_path: _Path = 'ffmpeg'
show_save_dir: _Path | None = None
_config = _Config()
def _search_for_ffmpeg_path() -> str | None:
"""Returns a path to the ffmpeg program, or None if not found."""
if filename := shutil.which(_config.ffmpeg_name_or_path):
return str(filename)
return None
I then navigated to the folder where all of my installed libraries is located opt/anaconda3/envs/myenv/lib/python3.10/site-packages and found that 'ffmpeg' folder containing everything that all other libraries contained. So it clearly exists there. However when I run the above code I get a return of 'None'. Im clearly missing something obvious but I can't seem to find it.
For reference this is the code that prompted the issue:
tippe_top = """
<mujoco model="tippe top">
<option integrator="RK4"/>
<asset>
<texture name="grid" type="2d" builtin="checker" rgb1=".1 .2 .3"
rgb2=".2 .3 .4" width="300" height="300"/>
<material name="grid" texture="grid" texrepeat="8 8" reflectance=".2"/>
</asset>
<worldbody>
<geom size=".2 .2 .01" type="plane" material="grid"/>
<light pos="0 0 .6"/>
<camera name="closeup" pos="0 -.1 .07" xyaxes="1 0 0 0 1 2"/>
<body name="top" pos="0 0 .02">
<freejoint/>
<geom name="ball" type="sphere" size=".02" />
<geom name="stem" type="cylinder" pos="0 0 .02" size="0.004 .008"/>
<geom name="ballast" type="box" size=".023 .023 0.005" pos="0 0 -.015"
contype="0" conaffinity="0" group="3"/>
</body>
</worldbody>
<keyframe>
<key name="spinning" qpos="0 0 0.02 1 0 0 0" qvel="0 0 0 0 1 200" />
</keyframe>
</mujoco>
"""
model = mujoco.MjModel.from_xml_string(tippe_top)
renderer = mujoco.Renderer(model)
data = mujoco.MjData(model)
duration = 7 # (seconds)
framerate = 60 # (Hz)
# Simulate and display video.
frames = []
mujoco.mj_resetDataKeyframe(model, data, 0) # Reset the state to keyframe 0
while data.time < duration:
mujoco.mj_step(model, data)
if len(frames) < data.time * framerate:
renderer.update_scene(data, "closeup")
pixels = renderer.render()
frames.append(pixels)
media.show_video(frames, fps=framerate)
Followed by the resulting error message:
{
"name": "RuntimeError",
"message": "Program 'ffmpeg' is not found; perhaps install ffmpeg using 'apt install ffmpeg'.",
"stack": "---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[4], line 14
11 pixels = renderer.render()
12 frames.append(pixels)
---> 14 media.show_video(frames, fps=framerate)
File ~/opt/anaconda3/envs/Exjobb/lib/python3.10/site-packages/mediapy/__init__.py:1858, in show_video(images, title, **kwargs)
1835 def show_video(
1836 images: Iterable[_NDArray], *, title: str | None = None, **kwargs: Any
1837 ) -> str | None:
1838 \"\"\"Displays a video in the IPython notebook and optionally saves it to a file.
1839
1840 See `show_videos`.
(...)
1856 html string if `return_html` is `True`.
1857 \"\"\"
-> 1858 return show_videos([images], [title], **kwargs)
File ~/opt/anaconda3/envs/Exjobb/lib/python3.10/site-packages/mediapy/__init__.py:1940, in show_videos(videos, titles, width, height, downsample, columns, fps, bps, qp, codec, ylabel, html_class, return_html, **kwargs)
1938 video = [resize_image(image, (h, w)) for image in video]
1939 first_image = video[0]
-> 1940 data = compress_video(
1941 video, metadata=metadata, fps=fps, bps=bps, qp=qp, codec=codec
1942 )
1943 if title is not None and _config.show_save_dir:
1944 suffix = _filename_suffix_from_codec(codec)
File ~/opt/anaconda3/envs/Exjobb/lib/python3.10/site-packages/mediapy/__init__.py:1777, in compress_video(images, codec, **kwargs)
1775 with tempfile.TemporaryDirectory() as directory_name:
1776 tmp_path = pathlib.Path(directory_name) / f'file{suffix}'
-> 1777 write_video(tmp_path, images, codec=codec, **kwargs)
1778 return tmp_path.read_bytes()
File ~/opt/anaconda3/envs/Exjobb/lib/python3.10/site-packages/mediapy/__init__.py:1747, in write_video(path, images, **kwargs)
1745 dtype = np.dtype(np.uint16)
1746 kwargs = {'metadata': getattr(images, 'metadata', None), **kwargs}
-> 1747 with VideoWriter(path, shape=shape, dtype=dtype, **kwargs) as writer:
1748 for image in images:
1749 writer.add_image(image)
File ~/opt/anaconda3/envs/Exjobb/lib/python3.10/site-packages/mediapy/__init__.py:1567, in VideoWriter.__enter__(self)
1566 def __enter__(self) -> 'VideoWriter':
-> 1567 ffmpeg_path = _get_ffmpeg_path()
1568 input_pix_fmt = self._get_pix_fmt(self.dtype, self.input_format)
1569 try:
File ~/opt/anaconda3/envs/Exjobb/lib/python3.10/site-packages/mediapy/__init__.py:1167, in _get_ffmpeg_path()
1165 path = _search_for_ffmpeg_path()
1166 if not path:
-> 1167 raise RuntimeError(
1168 f\"Program '{_config.ffmpeg_name_or_path}' is not found;\"
1169 \" perhaps install ffmpeg using 'apt install ffmpeg'.\"
1170 )
1171 return path
RuntimeError: Program 'ffmpeg' is not found; perhaps install ffmpeg using 'apt install ffmpeg'."
}
Any help is well appreciated.
I have tried changing the names of the files the 'shutil.which' command is searching for. I have tried reinstalling the libraries as well as try a different library (there seem to be two 'ffmpeg-python', version 0.2 and ffmpeg (which shows up in my directory as 'imageio_ffmpeg') version 0.4.9 (but it said 1.4 on the pip website)).
moviepy
requires the ffmpeg
command-line tool, not the ffmpeg-python
Python library or the imageio_ffmpeg
Python library, so looking in site-packages
is useless.
shutil.which()
doesn't look for libraries either, it looks for commands, so changing things there doesn't do you any good either.
You can find out if you have ffmpeg
installed by typing ffmpeg
on your command line.
If you have Homebrew, you can install the tool with
brew install ffmpeg
or otherwise via ffmpeg.org.