理解如何让库识别我有所需的依赖项
我开始了一个项目,需要使用一个叫做MuJoCo的开源软件,这是MuJoCo的文档。这个软件是用来做物理模拟的,特别适合强化学习(RL)。因为我正在开发一个人工智能应用,所以我选择用Python来编程,这样比较方便。
我遇到的问题是,MuJoCo使用一个叫做'mediapy'的库来显示视频帧序列,而这个库又依赖于另一个叫做'ffmpeg'的库。问题是'mediapy'没有识别到我的电脑上已经安装了'ffmpeg'(我用的是Mac,Intel处理器)。我深入查看了源代码,想找出问题所在,发现'mediapy'是通过运行以下代码来检查'ffmpeg'是否安装的:
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
然后我找到了我所有安装的库所在的文件夹,路径是opt/anaconda3/envs/myenv/lib/python3.10/site-packages,发现里面有一个'ffmpeg'的文件夹,里面的内容和其他库是一样的。所以它显然是存在的。但是当我运行上面的代码时,返回的结果是'None'。我明显漏掉了什么,但就是找不到。
为了参考,这段代码引发了这个问题:
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)
接下来是出现的错误信息:
{
"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'."
}
任何帮助都非常感谢。
我尝试过更改'shutil.which'命令搜索的文件名。我也尝试过重新安装这些库,还试过不同的库(似乎有两个'ffmpeg-python',一个是0.2版本,另一个是'ffmpeg',在我的目录中显示为'imageio_ffmpeg',版本是0.4.9,但在pip网站上显示是1.4)。
1 个回答
moviepy
这个工具需要用到ffmpeg
这个命令行工具,而不是ffmpeg-python
这个Python库或者imageio_ffmpeg
这个Python库,所以去查找site-packages
是没有用的。
shutil.which()
也不是用来查找库的,它是用来查找命令的,所以在这里做任何修改也没有帮助。
你可以通过在命令行输入ffmpeg
来检查你是否安装了ffmpeg
。
如果你有Homebrew,可以用下面的命令来安装这个工具:
brew install ffmpeg
或者你也可以通过ffmpeg.org来安装。