Skip to content

Proposal to remove env from call to Popen#62

Closed
anthonyjclark wants to merge 1 commit intogoogle:mainfrom
anthonyjclark:fix/ffmpeg-proc-env
Closed

Proposal to remove env from call to Popen#62
anthonyjclark wants to merge 1 commit intogoogle:mainfrom
anthonyjclark:fix/ffmpeg-proc-env

Conversation

@anthonyjclark
Copy link

The current version of _run_ffmpeg calls Popen with an empty environment:

env: Any = {}
...
return subprocess.Popen(
    ...
    env=env,
  )

This causes a difficult-to-understand error on my machine:

---------------------------------------------------------------------------
BrokenPipeError                           Traceback (most recent call last)
File ~/research/wmr/Transformable-Leg-Wheel-Robot/.venv/lib/python3.11/site-packages/mediapy/__init__.py:1851, in write_video(path, images, **kwargs)
   1850 for image in images:
-> 1851   writer.add_image(image)

File ~/research/wmr/Transformable-Leg-Wheel-Robot/.venv/lib/python3.11/site-packages/mediapy/__init__.py:1755, in VideoWriter.add_image(self, image)
   1754 assert stdin is not None
-> 1755 if stdin.write(data) != len(data):
   1756   self._proc.wait()

BrokenPipeError: [Errno 32] Broken pipe

During handling of the above exception, another exception occurred:

RuntimeError                              Traceback (most recent call last)
Cell In[1], line 32
     29 print(f"Final position: {state.data.qpos[0:3]}")
     31 frames = env.render(rollout)
---> 32 media.show_video(frames, fps=1.0 / env.dt)

File ~/research/wmr/Transformable-Leg-Wheel-Robot/.venv/lib/python3.11/site-packages/mediapy/__init__.py:1961, in show_video(images, title, **kwargs)
   1938 def show_video(
   1939     images: Iterable[_NDArray], *, title: str | None = None, **kwargs: Any
   1940 ) -> str | None:
   1941   """Displays a video in the IPython notebook and optionally saves it to a file.
   1942 
   1943   See `show_videos`.
   (...)   1959     html string if `return_html` is `True`.
   1960   """
-> 1961   return show_videos([images], [title], **kwargs)

File ~/research/wmr/Transformable-Leg-Wheel-Robot/.venv/lib/python3.11/site-packages/mediapy/__init__.py:2043, in show_videos(videos, titles, width, height, downsample, columns, fps, bps, qp, codec, ylabel, html_class, return_html, **kwargs)
   2041   video = [resize_image(image, (h, w)) for image in video]
   2042   first_image = video[0]
-> 2043 data = compress_video(
   2044     video, metadata=metadata, fps=fps, bps=bps, qp=qp, codec=codec
   2045 )
   2046 if title is not None and _config.show_save_dir:
   2047   suffix = _filename_suffix_from_codec(codec)

File ~/research/wmr/Transformable-Leg-Wheel-Robot/.venv/lib/python3.11/site-packages/mediapy/__init__.py:1880, in compress_video(images, codec, **kwargs)
   1878 with tempfile.TemporaryDirectory() as directory_name:
   1879   tmp_path = pathlib.Path(directory_name) / f'file{suffix}'
-> 1880   write_video(tmp_path, images, codec=codec, **kwargs)
   1881   return tmp_path.read_bytes()

File ~/research/wmr/Transformable-Leg-Wheel-Robot/.venv/lib/python3.11/site-packages/mediapy/__init__.py:1849, in write_video(path, images, **kwargs)
   1847   dtype = np.dtype(np.uint16)
   1848 kwargs = {'metadata': getattr(images, 'metadata', None), **kwargs}
-> 1849 with VideoWriter(path, shape=shape, dtype=dtype, **kwargs) as writer:
   1850   for image in images:
   1851     writer.add_image(image)

File ~/research/wmr/Transformable-Leg-Wheel-Robot/.venv/lib/python3.11/site-packages/mediapy/__init__.py:1716, in VideoWriter.__exit__(self, *_)
   1715 def __exit__(self, *_: Any) -> None:
-> 1716   self.close()

File ~/research/wmr/Transformable-Leg-Wheel-Robot/.venv/lib/python3.11/site-packages/mediapy/__init__.py:1773, in VideoWriter.close(self)
   1771   assert stderr is not None
   1772   s = stderr.read().decode('utf-8')
-> 1773   raise RuntimeError(f"Error writing '{self.path}': {s}")
   1774 self._popen.__exit__(None, None, None)
   1775 self._popen = None

RuntimeError: Error writing '/tmp/tmpe9a42is1/file.mp4': Diagnostic { message: "environment variable not found" }
NOTE: If you're looking for the fancy error reports, install miette with the `fancy` feature, or write your own and hook it up with miette::set_hook().

I tracked down the error, and it happens because I used pixi to install ffmpeg. This will install a stub at ~/.pixi/bin/ffmpeg. The _get_ffmpeg_path function will find the stub just fine, but the stub cannot find the actual exectuable when the environment is clobbered.

This is easiest to replicate in bash:

❯ /home/ajc/.pixi/bin/ffmpeg
ffmpeg version 8.0 Copyright (c) 2000-2025 the FFmpeg developers
...
❯ env -i bash --norc
bash-5.1$ printenv
PWD=/home/ajc/research/wmr/Transformable-Leg-Wheel-Robot/packages/twmr/assets
SHLVL=1
_=/usr/bin/printenv
bash-5.1$ ffmpeg
bash: ffmpeg: command not found
bash-5.1$ /home/ajc/.pixi/bin/ffmpeg
Diagnostic { message: "environment variable not found" }
NOTE: If you're looking for the fancy error reports, install miette with the `fancy` feature, or write your own and hook it up with miette::set_hook().

I had a few options:

  1. Set the correct path to the executable: media.set_ffmpeg("/home/ajc/.pixi/envs/ffmpeg/bin/ffmpeg")
  2. Remove env={} from the call to Popen

I think the second choice is better. The first requires a full, hard-coded path (or resolving from the home directory, which I suppose it OK, but hard to remember after a few months).

I searched through the history of the _run_ffmpeg function and I did not find a reason for clobbering the environment. Please let me know if I am mistaken!

@hhoppe
Copy link
Contributor

hhoppe commented Jan 30, 2026

The _run_ffmpeg function may have been introduced to allow customization within Google's code tree.
I agree that the default (non-customized) behavior should be to let the environment be preserved for the call to ffmpeg.
Hopefully someone at Google can have a look.

@Conchylicultor
Copy link
Member

Thank you for reporting! As @hhoppe said, this was needed due to Google internal only configuration.

I sent a fix in #63 which should be merged soon. Closing this one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants