Skip to main content

No project description provided

Project description

video_reader-rs

A python module to decode videos based on rust ffmpeg-next, with a focus on ML use cases.

💡 Why yet another library based on ffmpeg ?

When training ML models on videos, it is usefull to load small sub-clips of videos. So decoding the entire video is not necessary.

The great decord library seems to be unmaintained, while having a few issues. The main one (for us) is bad memory management, which makes it crash on large videos. Indeed it allocates memory for the whole video when instantiating a VideoReader object. While in fact you might want to only get a few frames from this video.

So we took great inspiration from this library to rewrite the get_batch function using ffmpeg-next rust bindings. We also added the decode function which is usefull for decoding the entire video or for temporally reducing it using a compression_factor. Option to resize the video while decoding is also added.

NOTE: other functionalities of decord are not implemented (yet?).

Benchmark indicates that video_reader-rs is performing equally or better than decord, while using less memory. At least on the intended ML uses cases where video resolution remains reasonable, eg not 4K videos.

🛠️ Installation

Install via pip

pip install video-reader-rs

Should work with python >= 3.8 on recent linux x86_64, macos and windows.

Manual installation

You need to have ffmpeg installed on your system. Install maturin:

pip install maturin

Activate a virtual-env where you want to use the video_reader library and build the library as follows:

maturin develop --release

maturin develop builds the crate and installs it as a python module directly in the current virtualenv. the --release flag ensures the Rust part of the code is compiled in release mode, which enables compiler optimizations.

⚠️ If you are using a version of ffmpeg >= 6.0 you need to enable the ffmpeg_6_0 feature:

maturin develop --release --features ffmpeg_6_0

💻 Usage

Decoding a video is as simple as:

from video_reader import PyVideoReader

vr = PyVideoReader(filename)
# or if you want to resize and use a specific number of threads
vr = PyVideoReader(filename, threads=8, resize_shorter_side=512)

# decode all frames from the video
frames = vr.decode()
# or decode a subset of frames
frames = vr.decode(start_frame=100, end_frame=300, compression_factor=0.5)
  • filename: path to the video file to decode
  • resize: optional resizing for the video.
  • compression_factor: temporal sampling, eg if 0.25, take 25% of the frames, evenly spaced.
  • threads: number of CPU cores to use for ffmpeg decoding, 0 means auto (let ffmpeg pick the optimal number).
  • start_frame - Start decoding from this frame index
  • end_frame - Stop decoding at this frame index

Returns a numpy array of shape (N, H, W, C).

We can do the same thing if we want grayscale frames, and it will retun an array of shape (N, H, W).

# this method has the same arguments as decode()
frames = vr.decode_gray()

If we only need a sub-clip of the video we can use the get_batch function:

frames = vr.get_batch(indices)
  • indices: list of indices of the frames to get
  • with_fallback: False by default, if True will fallback to iterating over all packets of the video and only decoding the frames that match in indices. It is safer to use when the video contains B-frames and you really need to get the frames exactly corresponding to the given indices. It can also be faster in some use cases if you have many cpu cores available.

We can also get the shape of the raw video

(n, h, w) = vr.get_shape()

Or get a dict with information about the video, returned as Dict[str, str]

info_dict = vr.get_info()
print(info_dict)
# example output:
# {'color_space': 'BT709', 'aspect_ratio': 'Rational(1/1)', 'color_xfer_charac': 'BT709', 'codec_id': 'H264', 'fps_rational': '0/1', 'width': '1280', 'vid_ref': '1', 'duration': '148.28736979166666', 'height': '720', 'has_b_frames': 'true', 'color_primaries': 'BT709', 'chroma_location': 'Left', 'time_base': '0.00006510416666666667', 'vid_format': 'YUV420P', 'bit_rate': '900436', 'fps': '33.57669643068823', 'start_time': '0', 'color_range': 'MPEG', 'intra_dc_precision': '0', 'frame_count': '4979'}

We can encode the video with h264 codec

from video_reader import save_video
save_video(frames, "video.mp4", fps=15, codec="h264")

NOTE: currently only work if the frames shape is a multiple of 32.

⚠️ Dealing with High Res videos

If you are dealing with High Resolution videos such as HD, UHD etc. We recommend using vr.decode_fast() which has the same arguments as vr.decode() but will return a list of frames. It uses async conversion from yuv420p to RGB to speed things up.

If you have some memory limitations that wont let you decode the entire video at once, you can decode by chunk like so:

from video_reader import PyVideoReader

videoname = "/path/to/your/video.mp4"
vr = PyVideoReader(videoname)

chunk_size = 800 # adjust to fit within your memory limit
video_length = vr.get_shape()[0]

for i in range(0, video_length, chunk_size):
    end = min(i + chunk_size, video_length)
    frames = vr.decode_fast(
        start_frame=i,
        end_frame=end,
    )
    # do something with this chunk of 800 `frames`

🚀 Performance comparison

Decoding a video with shape (2004, 1472, 1472, 3). Tested on a laptop (12 cores Intel i7-9750H CPU @ 2.60GHz), 15Gb of RAM with Ubuntu 22.04.

Options:

  • f: compression factor
  • r: resize shorter side
  • g: grayscale
Options OpenCV decord* vr.decode vr.decode_fast
f 1.0 65s 18s 9.3s 6.2s
f 0.5 33.96s 14.6s 5.5s 4.2s
f 0.25 7.16s 14.03s 4.2s 3.8s
f 0.25, r 512 6.5s 13.3s 3.92s 3.5s
f 0.25, g 20.2s 25.7s 6.6s N/A

* decord was tested on a machine with more RAM and CPU cores because it was crashing on the laptop with only 15Gb. See below.

💥 Crash test

Tested on a laptop with 15Gb of RAM, with ubuntu 22.04 and python 3.10. Run this script:

from video_reader import PyVideoReader
from time import time

def bench_video_decode(filename, compress_factor, resize):
    start =  time()
    vr = PyVideoReader(filename, resize_shorter_side=resize, threads=0)
    vid = vr.decode(compression_factor=compress_factor)
    duration = time() - start
    print(f"Duration {duration:.2f}sec")
    return vid

vid = bench_video_decode("sample.mp4", 0.25)
print("video shape:", vid.shape)

# Terminal output:
# Duration 4.81sec
# video shape: (501, 1472, 1472, 3)

And then run this script:

from decord import VideoReader

vr = VideoReader("sample.mp4")

# Terminal output:
# terminate called after throwing an instance of 'std::bad_alloc'
#  what():  std::bad_alloc
# [1]    9636 IOT instruction (core dumped)

🌠 Credits

  • decord for showing how to get_batch efficiently.
  • ffmpeg-next for the Rust bindings to ffmpeg.
  • video-rs for the nice high level api which makes it easy to encode videos and for the code snippet to convert ffmpeg frames to ndarray ;-)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

video_reader_rs-0.2.1.tar.gz (30.7 kB view details)

Uploaded Source

Built Distributions

video_reader_rs-0.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl (11.7 MB view details)

Uploaded PyPy manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.1-cp312-none-win_amd64.whl (702.8 kB view details)

Uploaded CPython 3.12 Windows x86-64

video_reader_rs-0.2.1-cp312-cp312-manylinux_2_28_x86_64.whl (11.7 MB view details)

Uploaded CPython 3.12 manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.1-cp312-cp312-macosx_11_0_arm64.whl (756.4 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

video_reader_rs-0.2.1-cp312-cp312-macosx_10_12_x86_64.whl (842.1 kB view details)

Uploaded CPython 3.12 macOS 10.12+ x86-64

video_reader_rs-0.2.1-cp311-none-win_amd64.whl (702.6 kB view details)

Uploaded CPython 3.11 Windows x86-64

video_reader_rs-0.2.1-cp311-cp311-manylinux_2_28_x86_64.whl (11.7 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.1-cp311-cp311-macosx_11_0_arm64.whl (755.9 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

video_reader_rs-0.2.1-cp311-cp311-macosx_10_12_x86_64.whl (842.3 kB view details)

Uploaded CPython 3.11 macOS 10.12+ x86-64

video_reader_rs-0.2.1-cp310-none-win_amd64.whl (702.8 kB view details)

Uploaded CPython 3.10 Windows x86-64

video_reader_rs-0.2.1-cp310-cp310-manylinux_2_28_x86_64.whl (11.7 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.1-cp310-cp310-macosx_11_0_arm64.whl (756.2 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

video_reader_rs-0.2.1-cp39-none-win_amd64.whl (703.3 kB view details)

Uploaded CPython 3.9 Windows x86-64

video_reader_rs-0.2.1-cp39-cp39-manylinux_2_28_x86_64.whl (11.7 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.1-cp39-cp39-macosx_11_0_arm64.whl (756.6 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

video_reader_rs-0.2.1-cp38-none-win_amd64.whl (702.9 kB view details)

Uploaded CPython 3.8 Windows x86-64

video_reader_rs-0.2.1-cp38-cp38-manylinux_2_28_x86_64.whl (11.7 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.28+ x86-64

File details

Details for the file video_reader_rs-0.2.1.tar.gz.

File metadata

  • Download URL: video_reader_rs-0.2.1.tar.gz
  • Upload date:
  • Size: 30.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.4

File hashes

Hashes for video_reader_rs-0.2.1.tar.gz
Algorithm Hash digest
SHA256 0eea0935defd34edd3fbb7aabbbc0c013acd196ef79c949a7081e7c353c4a8e2
MD5 c2b5995d0d121ee940e75e2142695696
BLAKE2b-256 d89a52c63ad1793986fb39c2ecb2e82ad772ca1804f23270ba3a586de2c3a11e

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 aa8a3a7641d3b7727c62035ad8df9379f547e61769e814239ed4d7083a884ac3
MD5 192498029e123007de9b8cc28d1bff00
BLAKE2b-256 63d648a37e9c79085922ac5d89901b07667cc97b73ce227306d19203f3fde231

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp312-none-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp312-none-win_amd64.whl
Algorithm Hash digest
SHA256 1901a64a86e659ee74acdc4c635a956321c07facfbfb20ac726f2afbc3eec87e
MD5 01603d15cf3bf08d051f0d8852e1222a
BLAKE2b-256 5c454c8b654f5e93910c33dd1af5f351a98c219227ceb7722818c3159916849a

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6641a86c41172922eb10c048ab4066b1d6d3a66d0e33d838ad88807907141f60
MD5 1c740d505062887a786e6e4f5dc53076
BLAKE2b-256 8d6bdd7b4244e817e99a21ce3866cc8e708105378ac654054f14a1d558a9b6ab

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6fa576a206d02dfd02de814d9a577181a06679294c26ab128be2b825c8214613
MD5 a614ff76c36abc8606b1ae12d6200c83
BLAKE2b-256 491a7e1a6415aad13ac5c1e45a14e8e386d4c6602d0ecaefaaf3daf67b5a8c96

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f601b8fa9c989b9ef6728de9c437e53ef562ebb369546c177326d6cace151240
MD5 9919feb9f3379dd86de956fc0caf4c17
BLAKE2b-256 d64e6a85cc16b680b61601f4efccab6819aebf69d86d1618cb1e74658dec450e

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp311-none-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp311-none-win_amd64.whl
Algorithm Hash digest
SHA256 75e2771820f9dc7ea88e7a31f2a70a4e0d3266340e3565596e6725bf25f53c19
MD5 039a68b54968a946c8d1f1f9ca0ea86d
BLAKE2b-256 2236bed7506bbdd494c0da1dd8008ba054aaf86cd11467ebd77ee9dc16c4caba

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 11a952074097c70c94212d2a0d58fc7203a26951ae22295699c68e81aad1565e
MD5 144422c48e820a4e604cd23ad7349681
BLAKE2b-256 b13d71b8886bec6b68545e9e124dab60d3dbe8e90cdd6bf0ec1a97555b9cba37

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a95633d2128a2e0a6c75e32cd05e6413bc4cb26b2504c5ce872634d15a0d298d
MD5 43bfc83b968e68dde28f9f68f288b9fa
BLAKE2b-256 6e4dbc7579ca61a69d5f7111d30eea4b7ffaf72de0cd41c6248461ad2baabd06

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0dc2acb46e9a83c42f496f2b50965454e7c45742a86a314aeb56095d424cdf70
MD5 3d0acff7f851ce1b6d0a8b812f669cf0
BLAKE2b-256 bda79e97959ad0cbfd1f56df4d6c165e9a09eece832d0306029fc40846b76f81

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp310-none-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp310-none-win_amd64.whl
Algorithm Hash digest
SHA256 b4ed113af880770087bbfbb93bb9fbd326cbf6c1e9ab45b39f2ad81b494a3dd3
MD5 3964c7adef8eb24cd19d7f699d81be08
BLAKE2b-256 56ee231b3ca3ba09f8fb4435cba8837f8012fa4c5b65d57825705128c3a4b390

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 17e560d65d71831a367a302051ab8596149a0eb9a8a88f0e65a52c3859359266
MD5 b0ee551a365eee42da45fb9ac756d202
BLAKE2b-256 da36f04c4deb252198cf4851d9dcb3eb79b56de23861b2b64649cf0559a50975

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d515160eb3fdab07008f1c3aecfe57d151d2dcdaddde404c017c845892610a75
MD5 4573c496a349ee7e28db12b80846b740
BLAKE2b-256 47c3bbf5fd72056d15fa77c865b2ec51b9317a105857d2934bee9a7eb479ec22

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp39-none-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp39-none-win_amd64.whl
Algorithm Hash digest
SHA256 9d1d55bd7e498a6831ed35e6b8ab8f345b5cd79fe1841e6bef057fb581f3f6d4
MD5 d51061678316fba6f2aac72f7654cb2f
BLAKE2b-256 4f9f514cbe2b8c2986a869f9c864451dba7154b88fa22fd58db3c00913c11b83

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp39-cp39-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 040d1c51bbe0551d4f908103c5db68f9e6ab485dd9968fd3acd5d013567af4fd
MD5 44efe926257b656fe65c2b13dbf039a8
BLAKE2b-256 c75c43a96ce41aba877a3b0b3377f6f275186a039b5ac869bf9d2a1e4d7c7e5e

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fd5b3937b53dc2b9ebf94a33d9b3458b9408263050972c3b74c9312cc1524d9a
MD5 c9458746763db2df5f3168ca64c12848
BLAKE2b-256 b305580c19b6b129c9c11c79aa16a22e94ed8713b24c01d5e71ca498ef6b188e

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp38-none-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp38-none-win_amd64.whl
Algorithm Hash digest
SHA256 4cf228729304c6e3b12e6489ef7071bcb914f8daae53b530ae6b03ea3f5e3e4d
MD5 4c4111ff2342cc9bac933e2bb91617ad
BLAKE2b-256 a6f37b8633498cf7ab4577d376876cffce6214763b8527dfac36a0fbcda0dad8

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.1-cp38-cp38-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.1-cp38-cp38-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 856bdaf6e13ff82329f01f2ae59dd4c4ce90ad30d81b837e5886386100d10841
MD5 09008219b5ff4bc79126525aceae7958
BLAKE2b-256 72ba3f77f52d645a4951736e687913f8b51ed9da431effa9954bc95de5aa75d1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page