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 and macos.

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=480)
# similar but by resizing longer side
vr = PyVideoReader(filename, threads=8, resize_longer_side=640)
# or to use GPU decoding:
vr = PyVideoReader(filename, device='cuda')

# 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)
# alternatively one can iterate over frames
for frame in vr:
    # do something with a single frame
    print("top left red pixel value:", frame[0, 0, 0])
  • 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.

It is also possible to directly use slicing or indexing:

last_frame = vr[-1]
n = vr.get_shape()[0]
odd_frames = vr[1::2]
sub_clip = vr[128:337]

We can also get the shape of the raw video

# (number of frames, height, width)
(n, h, w) = vr.get_shape()
# if we only want the number of frames
n = len(vr)

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'}

⚠️ 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`

🧪 Experimental support for Hardware Acceleration

You need to install video-reader-rs from source by cloning this repo and running maturin develop -r or maturin develop -r --features ffmpeg_6_0 if you have ffmpeg >= 6.0. Your ffmpeg installation should have support for cuda. Check with ffmpeg -version | grep cuda for example.

from video_reader import PyVideoReader

videoname = "/path/to/your/video.mp4"
vr = PyVideoReader(videoname, device='cuda')

You can also pass your own ffmpeg filter if you feel adventurous enough. For example, this would be the default filter used when specifying devide='cuda' and resize_shorter_side=512.

vr = PyVideoReader(videoname, device='cuda', filter='scale_cuda:h=512:w=-1:passthrough=0,hwdownload,format=nv12', resize_shorter_side=512)

In theory any hwaccel should work if you provide the correct filters, ie qsv, vaapi, vdpau, etc. It has not been tested though. Feel free to report.

Another example with VAAPI hardware acceleration:

vr = PyVideoReader(videoname, device='vaapi', filter='hwmap,format=nv12')

🚀 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.8.tar.gz (2.4 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

video_reader_rs-0.2.8-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl (11.8 MB view details)

Uploaded PyPymanylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl (11.8 MB view details)

Uploaded PyPymanylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.8-cp314-cp314-manylinux_2_28_x86_64.whl (11.8 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.8-cp313-cp313-win_amd64.whl (63.0 MB view details)

Uploaded CPython 3.13Windows x86-64

video_reader_rs-0.2.8-cp313-cp313-manylinux_2_28_x86_64.whl (11.8 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.8-cp313-cp313-macosx_14_0_arm64.whl (33.1 MB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

video_reader_rs-0.2.8-cp313-cp313-macosx_13_0_x86_64.whl (38.4 MB view details)

Uploaded CPython 3.13macOS 13.0+ x86-64

video_reader_rs-0.2.8-cp312-cp312-win_amd64.whl (63.0 MB view details)

Uploaded CPython 3.12Windows x86-64

video_reader_rs-0.2.8-cp312-cp312-manylinux_2_28_x86_64.whl (11.8 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.8-cp312-cp312-macosx_14_0_arm64.whl (33.1 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

video_reader_rs-0.2.8-cp312-cp312-macosx_13_0_x86_64.whl (38.4 MB view details)

Uploaded CPython 3.12macOS 13.0+ x86-64

video_reader_rs-0.2.8-cp311-cp311-win_amd64.whl (63.0 MB view details)

Uploaded CPython 3.11Windows x86-64

video_reader_rs-0.2.8-cp311-cp311-manylinux_2_28_x86_64.whl (11.8 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.8-cp311-cp311-macosx_14_0_arm64.whl (33.1 MB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

video_reader_rs-0.2.8-cp311-cp311-macosx_13_0_x86_64.whl (38.4 MB view details)

Uploaded CPython 3.11macOS 13.0+ x86-64

video_reader_rs-0.2.8-cp310-cp310-win_amd64.whl (63.0 MB view details)

Uploaded CPython 3.10Windows x86-64

video_reader_rs-0.2.8-cp310-cp310-manylinux_2_28_x86_64.whl (11.8 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

video_reader_rs-0.2.8-cp39-cp39-win_amd64.whl (63.0 MB view details)

Uploaded CPython 3.9Windows x86-64

video_reader_rs-0.2.8-cp39-cp39-manylinux_2_28_x86_64.whl (11.8 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ x86-64

File details

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

File metadata

  • Download URL: video_reader_rs-0.2.8.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.8.6

File hashes

Hashes for video_reader_rs-0.2.8.tar.gz
Algorithm Hash digest
SHA256 3c3de3b746b7a4cd2b341801d839075d627a46f6ca76d225e10e20d18c30bd73
MD5 50816db39f7eceb6db80ede1128ad50f
BLAKE2b-256 f90fff911536620cfbe764f6947b743cce78161fbf6a72ecf39039a71b798fc9

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1b20d1c85b8802f443e562f188698ffa6bfcbceb8fb8757d464a8179a5861bbb
MD5 844b3b46b5af49c5afd568e9f637d849
BLAKE2b-256 e4f481c99b2ee871de2988a3957d89c5f52e92e31404dcb0b13a4effb157aecd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c836f4454adfe695ad13a8c4ad2437816c6af3fc766105694ac12626b8c8131b
MD5 1a0f0974b0168ac886a30735340ee2ff
BLAKE2b-256 5e50fd55e3e9544a04c6e83a6dbe9370384daece27c08ccd6214e2abe012774f

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 47599d1cd2a2bf97a04f38369365d7ac32afb3ae397122c69c1c1996bee5bb5c
MD5 be0a38b80aad4f1c6745c32e6a253256
BLAKE2b-256 e3398324fdc1c54ac1ac4a394140cc0e6b0ec3dac9afda3db93f5c1944093fe2

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 440a64ee881037272847591388d0c3b93cd96a6f957fac852efc034714bab71e
MD5 cde02915a08d6223574ef0cbd95fa285
BLAKE2b-256 4d68d0d6b59bc42f31e61576609f84f7e01f7cb5312dd4be7df97170386e0bb8

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4facc24e2f03d6a1a6b724bdb76861c3c195a0b618f13b70de0ab9d938c85371
MD5 bc6dc0f804adb2f4d05ab38d6ae5be09
BLAKE2b-256 25afaaa8528315c9b5fdf57e186df347050459ca2876cf0bfaaa87f6c80884c8

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 7289831e68cc9f9ff93cc54ba794894198a04ed05e9c788365b9d69081407d3f
MD5 861ec4a0a531d316a760b29524d31347
BLAKE2b-256 37e115bcd21a99413ab09705ce97a3c9ae7f048a1ef07ee9eccc77be85f35d65

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp313-cp313-macosx_13_0_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp313-cp313-macosx_13_0_x86_64.whl
Algorithm Hash digest
SHA256 2a30dfabb312bbae37da3fd015006e9db7e52fbc534a5db8881a08c8b0a06e1b
MD5 672fd714a70b3eb8e7f5bc0fb2c471cc
BLAKE2b-256 b5940fd434c89343956c5507f37dfe5ec313f169e7a1119c0b7e962f8440152c

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 356ad295dd380516bbdfb6d6802f21eda451904cd5f9f4133e5f20b0f34de865
MD5 ea15b7cde5e89f1b2c2a2f89850ca9e9
BLAKE2b-256 3f00a909b2d6b0bc95de0933cfc203c5688cdd1a58c7edd99439f27e783fe69e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 935dbe4ae40da88ac45a06fcf1218e3835e4f9d55d0f1ff51d3d175cd0ba77bc
MD5 47b2120e91f372a4b38bc946c75b9bb9
BLAKE2b-256 81a2f1c64a80182914f349fc61c9f0f55a102081428e8cce72ceaa7a13aef497

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 bccc6639d0697726032a7bbd9caa7fcd86bf2c98873bb59f95aa39d3e86c25f2
MD5 5a84f81f017574b213c992d7add35531
BLAKE2b-256 261f1c45400864e17b719b6ef812cb896eed318e26f9896ca8a4ed3397957b4f

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp312-cp312-macosx_13_0_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp312-cp312-macosx_13_0_x86_64.whl
Algorithm Hash digest
SHA256 91b236b07d2ec3b2ca9b8eb2569d0676d7fac2b5969e8416856aad4836d23027
MD5 258e25bffecbc96a6961d220179f96d7
BLAKE2b-256 4370f83e4ec88e9dcaa690d2265e9fe661922ec00232988ed182925c860dd259

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 34ab25fd8849c5251ab01fe78869ec901f1a8f1f902ee1a835da30c8e456eb9b
MD5 ca3b05792b7f57b41811c4638063a254
BLAKE2b-256 2a4c5576aaaa3ce6a812d28c99744597efc69994d30e69a10ab486fd6078ad9a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c99ed72361136c447e53a21f8cb00cdfc7fdf4ce55a827cf1846e221d926e405
MD5 cb372e50b38bca3bbf21bb010e57b823
BLAKE2b-256 0350ce0d14c070248e370f04d0cbed5f6f25a7ab3ae41b8f5e116590bc1b728f

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 19d87f9bc0f6df956b2db67bc50efa3c663c1bcb6ae95bdc0b1e78afa4e8e2ae
MD5 e1c698f6863576de6206d6032ee5ab90
BLAKE2b-256 fcb176c7751b539f633aff45ef38d825f8fc8b906ec89a22e9c67adb4bb32841

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp311-cp311-macosx_13_0_x86_64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp311-cp311-macosx_13_0_x86_64.whl
Algorithm Hash digest
SHA256 e3f7ef5600b47db2c2aced4f2bd99ab96371a7d116a7c4ca2cc9def9f3767583
MD5 c949cc53ec3a7b26b420ce2adf5e1526
BLAKE2b-256 af5d1250640b11551ed3f90a4dfc82504e95b1bce0f4dfd62ca4dd1ed3970632

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 e9776f811a8ed7dc8c5c960517ccaeb0c30ae362d7cc26503a6b9f620d8a177e
MD5 a98585b29280ecba5de42f82e1a3485e
BLAKE2b-256 46f735e4bedc5947620ee39bc2f9adca347cb6c63b1645daa71b5a85aaabb431

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a3a12a922a76d4817ac1bf5b08eb4b904594b8273c3055ee3484dd21ef312b28
MD5 ccd9c66965be996c09ea18b7588c6650
BLAKE2b-256 5b9a584397ca61992eb698b5bd5efe469d7315dd0e981e1249a9e7904fe92363

See more details on using hashes here.

File details

Details for the file video_reader_rs-0.2.8-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 fe3134a3199b0310443c4c66bb87acf3e5f9e9491078913216fd641a822b6c31
MD5 ae4c5b79583e76a055692170ca9e4e0f
BLAKE2b-256 a528db683fc47d64fcc856c014c8d413ebe38ded21ba50b903954303ee7a8325

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for video_reader_rs-0.2.8-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 69efaa99645b999f49e3081a2d48ede2724af98c51edaaacd3e14fb586d4e7d2
MD5 4293c737b05a44d588ad9bd13bf1785c
BLAKE2b-256 bf8334465668f295fddc095a01c97a40f3e24a00dc87b088f9b84663f9a37684

See more details on using hashes here.

Supported by

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