mediapy icon indicating copy to clipboard operation
mediapy copied to clipboard

Read from bytes directly

Open yuvalkirstain opened this issue 1 year ago • 5 comments

Hello, sometimes we have video bytes rather than a file or URL. Will be great to have mediapy support reading video bytes directly.

yuvalkirstain avatar Oct 17 '24 15:10 yuvalkirstain

Would decompress_video work for you?

https://google.github.io/mediapy/mediapy.html#decompress_video

rmbrualla avatar Oct 17 '24 18:10 rmbrualla

Yes, thank you! why do you call it decompress_video?

Also, perhaps checking if read_video is bytes and then using the decompress_video if it is will be more intuitive for users.

yuvalkirstain avatar Oct 20 '24 02:10 yuvalkirstain

The argument to read_video is a os.PathLike, which is often a str, but it could be pathlib.Path, bytes, or some other path-like object. See https://docs.python.org/3/library/os.html#os.PathLike .

hhoppe avatar Oct 20 '24 05:10 hhoppe

From ChatGPT:

Can an os.PathLike be a bytes object? ChatGPT said: Yes, an os.PathLike object can be a bytes object in Python.

In Python, paths can be represented as either str (Unicode) or bytes objects. When interacting with the filesystem, Python accepts paths in both formats. The os.PathLike protocol was introduced in Python 3.6, allowing objects that implement the fspath method to be passed as file paths. This method should return either a str or a bytes object.

If a bytes object is returned by fspath, it will be treated as a file path in the form of raw bytes. However, this is typically used in situations where dealing with non-ASCII or locale-specific file systems.

For example, when working with file operations like open, you can pass a path in bytes, and it will be handled correctly:

hhoppe avatar Oct 20 '24 05:10 hhoppe

Yea, it doesn't work as I get filename too long error. decompress_video does work, so perhaps my suggestion from above is relevant.

OSError                                   Traceback (most recent call last)
Cell In[46], line 1
----> 1 video = mediapy.read_video(example["output_video"])

File [/packages/xlformers_emu_conda_dev/conda/lib/python3.10/site-packages/mediapy/__init__.py:1726](http://127.0.0.1:8555/packages/xlformers_emu_conda_dev/conda/lib/python3.10/site-packages/mediapy/__init__.py#line=1725), in read_video(path_or_url, **kwargs)
   1705 def read_video(path_or_url: _Path, **kwargs: Any) -> _VideoArray:
   1706   """Returns an array containing all images read from a compressed video file.
   1707 
   1708   >>> video = read_video('[/tmp/river.mp4](http://127.0.0.1:8555/tmp/river.mp4)')
   (...)
   1724     metadata attribute is lost in most subsequent `numpy` operations.
   1725   """
-> 1726   with VideoReader(path_or_url, **kwargs) as reader:
   1727     return _VideoArray(np.array(tuple(reader)), metadata=reader.metadata)

File [/packages/xlformers_emu_conda_dev/conda/lib/python3.10/site-packages/mediapy/__init__.py:1352](http://127.0.0.1:8555/packages/xlformers_emu_conda_dev/conda/lib/python3.10/site-packages/mediapy/__init__.py#line=1351), in VideoReader.__enter__(self)
   1349 # pylint: disable-next=no-member
   1350 tmp_name = self._read_via_local_file.__enter__()
-> 1352 self.metadata = _get_video_metadata(tmp_name)
   1353 self.num_images, self.shape, self.fps, self.bps = self.metadata
   1354 pix_fmt = self._get_pix_fmt(self.dtype, self.output_format)

File [/packages/xlformers_emu_conda_dev/conda/lib/python3.10/site-packages/mediapy/__init__.py:1207](http://127.0.0.1:8555/packages/xlformers_emu_conda_dev/conda/lib/python3.10/site-packages/mediapy/__init__.py#line=1206), in _get_video_metadata(path)
   1205 def _get_video_metadata(path: _Path) -> VideoMetadata:
   1206   """Returns attributes of video stored in the specified local file."""
-> 1207   if not pathlib.Path(path).is_file():
   1208     raise RuntimeError(f"Video file '{path}' is not found.")
   1209   command = [
   1210       _get_ffmpeg_path(),
   1211       '-nostdin',
   (...)
   1220       '-',
   1221   ]

File [/packages/xlformers_emu_conda_dev/conda/lib/python3.10/pathlib.py:1322](http://127.0.0.1:8555/packages/xlformers_emu_conda_dev/conda/lib/python3.10/pathlib.py#line=1321), in Path.is_file(self)
   1317 """
   1318 Whether this path is a regular file (also True for symlinks pointing
   1319 to regular files).
   1320 """
   1321 try:
-> 1322     return S_ISREG(self.stat().st_mode)
   1323 except OSError as e:
   1324     if not _ignore_error(e):

File [/packages/xlformers_emu_conda_dev/conda/lib/python3.10/pathlib.py:1097](http://127.0.0.1:8555/packages/xlformers_emu_conda_dev/conda/lib/python3.10/pathlib.py#line=1096), in Path.stat(self, follow_symlinks)
   1092 def stat(self, *, follow_symlinks=True):
   1093     """
   1094     Return the result of the stat() system call on this path, like
   1095     os.stat() does.
   1096     """
-> 1097     return self._accessor.stat(self, follow_symlinks=follow_symlinks)

OSError: [Errno 36] File name too long:

yuvalkirstain avatar Oct 20 '24 16:10 yuvalkirstain