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"
# must set pixel_format to "yuv420" to be able to use `decode_fast()`
vr = PyVideoReader(videoname, pixel_format="yuv420")

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.0.tar.gz (30.8 kB view details)

Uploaded Source

Built Distributions

video_reader_rs-0.2.0-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.0-cp312-none-win_amd64.whl (702.2 kB view details)

Uploaded CPython 3.12 Windows x86-64

video_reader_rs-0.2.0-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.0-cp312-cp312-macosx_11_0_arm64.whl (755.8 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

video_reader_rs-0.2.0-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.0-cp311-none-win_amd64.whl (702.1 kB view details)

Uploaded CPython 3.11 Windows x86-64

video_reader_rs-0.2.0-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.0-cp311-cp311-macosx_11_0_arm64.whl (755.7 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

video_reader_rs-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl (842.1 kB view details)

Uploaded CPython 3.11 macOS 10.12+ x86-64

video_reader_rs-0.2.0-cp310-none-win_amd64.whl (702.4 kB view details)

Uploaded CPython 3.10 Windows x86-64

video_reader_rs-0.2.0-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.0-cp310-cp310-macosx_11_0_arm64.whl (756.1 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

video_reader_rs-0.2.0-cp39-none-win_amd64.whl (702.8 kB view details)

Uploaded CPython 3.9 Windows x86-64

video_reader_rs-0.2.0-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.0-cp39-cp39-macosx_11_0_arm64.whl (756.5 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

video_reader_rs-0.2.0-cp38-none-win_amd64.whl (702.6 kB view details)

Uploaded CPython 3.8 Windows x86-64

video_reader_rs-0.2.0-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.0.tar.gz.

File metadata

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

File hashes

Hashes for video_reader_rs-0.2.0.tar.gz
Algorithm Hash digest
SHA256 906cbffd8eca8d978802b93706b25ce98cfdc05a598292a5ea1eec53cb593ec5
MD5 03d6e9e34a48b121f02147bb2b750ad0
BLAKE2b-256 40100127866094e20dd30774bbfc9cfe333c7c79f8b4e53bd84e36192a11ca0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 395be48dbfcefdc42fbaf860103bb7af7a4f7415b591ace1ccb3b961aef91552
MD5 26331da83d67bf1f856a55513530abd2
BLAKE2b-256 21a7608e240ecfc1d952a2318fc08afed6f3427915e8a857497261b009c94417

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp312-none-win_amd64.whl
Algorithm Hash digest
SHA256 c991e9041b064133af1e464a022dc4f8b4e08d6bc7fa4db9b7844f23d4621e24
MD5 d9e5046c43680ef2a8231c928dff66e2
BLAKE2b-256 aadaf7a306dbf97379cb56b437d4ee428bc1d647d6d09ccfe7e75a607ea0eca0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e2e4e79cab82484384baa1f8cc93d0a1a86b25725444232b4908c5ed00c5f332
MD5 0fb000fcd383b6db671e631f7b955aba
BLAKE2b-256 f8bc79da9a2e2cfea64267a62cbfe9cd6075cb50b7793ff9b06ad36e09573699

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a129e034d16923557e6b9ee6a4d7f95961d7a18eb1cb9c963a3048cbca179a10
MD5 be9cf2f13490225ddfed1a0ec81d32e4
BLAKE2b-256 98adb855ac301c621d89952c69290c7ea71e1d9fa9379dc96651bf19af6b5e8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 89f0dc6d3ef16de5ebb7e409bcadc39e984d856245f829664ebd330fe75de2f6
MD5 e94ba311a6edec1ce74ebf2df519d644
BLAKE2b-256 1bd9dcb26a75d6c437336209b040f05df9d099e0124cd1941a14db3820b53ad8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp311-none-win_amd64.whl
Algorithm Hash digest
SHA256 47f1d82dcecb29ce89e16c231cefa8caacfb74a27bdd87f9862afaae7fa6b372
MD5 5f602942f2d3d93f5e2d7e7595e1d76f
BLAKE2b-256 e83e0a096fa874c3618abd3ac2e83ed230faa0df4f74faba6160b580286c0cc4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d111d8d007ae7c1b6550ebc43873876b1eb75e6afcb6d6cff82c3292801eb844
MD5 e4c12f1fecc33ce7f49b1fc53e2ab821
BLAKE2b-256 127f517d9aa26e0edec8d3ad1f2123a83c765593e426c6cda7afe4f28f19a32c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 33b9a2109c39a5d805777fd191dca2faeb121a6d4a42a2d47c0ac5bfa9147d92
MD5 74d0f9f2e221e1e9df677d72d7d4649c
BLAKE2b-256 ae35f6b5eaf6847170232221ae0095c47dc57461ebb3cab91b6cb8180aafec4e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 cab0af1dc26b1ff7a27e79107af5e12e11a32f77c98a3386e9c50b23021d5207
MD5 13116e54a3a01a79b632f8f5fc76db21
BLAKE2b-256 9aef5bac93002f564f54a748ad6ee11df58eebfb33b71b5dbb1db3ee4de48a48

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp310-none-win_amd64.whl
Algorithm Hash digest
SHA256 54e57b3459599bab8c3c889eace96ebf09ba2312fb30d01bac142f9fc497ae67
MD5 87ef6080ac06c67b5e88a5265062a753
BLAKE2b-256 015ea09737425bc7c0ccc22f4950925842b66663529f1e56f1b3ce6a54eb71d9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d5adc8595c92001d8f84eb5f5668b989c643233f71c3854a1fc3a1085895a3c4
MD5 0731fefb2eabae319df5d49516a7c9e3
BLAKE2b-256 1654869d2ead8bb73d9025676b76b712418fff86cb449cfb955faf6b13e6c8bf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2af8d87e891907a4bd970b5a8957da550f7646acb027a2992b2a57cff6eb0223
MD5 f2892877ec39ef503c21de637779dfc5
BLAKE2b-256 0ccc011d4e5e5dc1e8e1ba08d6f2c71836317ebd981165cb1f319838be446288

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp39-none-win_amd64.whl
Algorithm Hash digest
SHA256 8813f53aff6c20e54285a57649629088a5e0092ae4dbdb9a818ad948786d622f
MD5 e2a07b8424fd70a5aea41388674e945d
BLAKE2b-256 909201f11a08dfa3dc5a36c2b8437529b2f49af3a312fc924f0215f54cd767fe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ed9da9d07697a317c269213693cd42f2a43f655eccdb4d561074939a975169c9
MD5 04a423ff0d27be2318dc9f9484e09562
BLAKE2b-256 393037209052071624222edc8383f7a0d428ee57c9a55df2e43834e7b2a07d31

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9248026bd63a9626c8c6c8bcd038a52f7c2d9199db557f40547db30fe750c442
MD5 13d80f4290c971cd80831ba5d483e2d3
BLAKE2b-256 499ee5be82e932eecc227738ebe70c3226d2266d7b4690479a3178e3bbfe759f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp38-none-win_amd64.whl
Algorithm Hash digest
SHA256 5e900d39af2385161ad9d08003133e46c94e2fa4784e29457832cf77776f5abf
MD5 4f9abd21f2f324c0f8e95805f4e1a65f
BLAKE2b-256 51275baedff25df4d2331721ca54a5b2e098560a853d18c43183c4c6ad5752cf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.0-cp38-cp38-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d27f8cd22e676b118b0a0cc9556c85f3ec13cbebb965791ec4e79dd8b7444050
MD5 7825639948b7329f5e49d6cc76d2e08b
BLAKE2b-256 aec517f0bdd4b52d40e79a8d9df2274cdc5fa75d5779c1bd2cc48bc24d3a00c2

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