Ffmpeg videostream - High speed video frame access in Python, using FFmpeg and FFshow

Overview

FFmpeg VideoStream

High speed video frame access in Python, using FFmpeg and FFshow

This script requires:

Basic Usage

from ffmpeg_videostream import VideoStream

video = VideoStream("my_video.mp4")
video.open_stream()
while True:
    eof, frame = video.read()
    if eof: break

Methods

VideoStream (path, color, bytes_per_pixel)

  • path : The path to your video file as a string : '/videos/my_video.mp4'
  • color : The pixel format you are requesting from FFmpeg : By default 'yuv420p' (recommended)
  • bytes_per_pixel : The number of bytes (not bits) that your pixel format uses to store a pixel : By default 1.5 (as per 'yuv420p')

Note: By setting color and bytes_per_pixel you can ingest video into any pixel format ffmpeg supports. However, most source files and use cases will benefit by using the default configuration and converting the pixel data to other formats as needed. (See 'Examples')


.config (start_hms, end_hms, crop_rect, output_resolution)

  • start_hms : Read frames starting from this time* in the video : ("seek" equivalent)
  • end_hms : Stop reading frames at this time* in the video
  • crop_rect : Accepts a list / tuple as [x, y, width, height] for cropping the video's input
  • output_resolution : Accepts a list / tuple as [width, height] declaring the final scaling of the video, forcing the output to match this resolution

Note: When crop_rect is set, it overrides the .shape() of the final output resolution. This is only important to note if you were to request the crop in a separate call to .config(), AFTER requesting the output_resolution be changed in a previous call. For example...

video.config(output_resolution=(1280, 720))
video.config(crop_rect=(0,0,720,480))
# Hey, just don't do it that way... huh?

.open_stream (showinfo, loglevel, hide_banner, silence_even_test)

  • showinfo : When True invokes ffmpeg's 'showinfo' filter providing details about each frame as it is read.
  • loglevel : Sets ffmpeg's 'stderr' output to include/exclude certain data being printed to console.
  • hide_banner : Shows/hides ffmpeg's startup banner.
    • Note: Various 'loglevel' settings implicitly silence this banner. When 'showinfo' is invoked no 'loglevel' output will be printed to console.
  • silence_even_test : When True suppresses console warnings that an invalid resolution has been requested.

Note: Invoking 'showinfo' reduces the maximum speed raw frame data can ingest. In most rendering instances the speed reduction is immeasurable due to other blocking processes. But for the raw acquisition of frames it can be significant.


.read ()

Returns an end-of-file boolean flag, followed by a single frame's worth of the raw bytestream from the video. The bytestream data returned is in no way prepared, decoded, or shaped into an array structure. A simple example for converting YUV420p to BGR using numpy and OpenCV is provided:

    eof, frame = video.read()
    arr = np.frombuffer(frame, np.uint8).reshape(video.shape[1] * 1.5, video.shape[0])
    bgr = cv2.cvtColor(arr, cv2.COLOR_YUV2BGR_I420)

Note: The VideoStream class can be initialized to request BGR output directly from ffmpeg, but it is slower to acquire a 24-bit RGB / BGR encoded frame than to acquire the 12-bit YUV pixels and convert them.


.shape () : Returns the final output resolution of the video in a list : [width, height]


.eof () : Boolean indicating whether the end of the file has been reached


.close () : Closes the open stream


.showinfo (key)

current_frame_number = video.showinfo("n")

Note: All requests return None if showinfo=True was not set during open_stream()


.inspect (attrib)

  • Returns a dict() containing all data found in the 'video' stream of ffprobe if no attrib declared.
  • .inspect("something") returns the value of "something" from the dict() or None if not found.

Examples

Timing raw frame access speed

from ffmpeg_videostream import VideoStream
from time import time

video = VideoStream("my_video.mp4")
video.open_stream()
frames = 0

print("\r\nReading VideoStream...")
timer = time()
while True:
    eof, frame = video.read()
    if eof: break
    frames += 1
timer = time() - timer

print(f"\r\nRead {frames} frames at {video.shape()} resolution from '{video.path}' in {round(timer, 3)} seconds.")
print(f"Effective read rate of {round(frames / timer)} frames per second.")

Rendering output to PyGame

from ffmpeg_videostream import VideoStream
import numpy as np
import cv2
import pygame

path = 'my_video.mp4'

video = VideoStream(path)
video.open_stream()

pygame.init()
screen = pygame.display.set_mode(video.shape())

while True:
    eof, frame = video.read()
    # Shape bytestream into YUV 4:2:0 numpy array, then use OpenCV to convert from YUV to BGR.
    arr = np.frombuffer(frame, np.uint8).reshape(video.shape()[1] * 3//2, video.shape()[0])
    img = cv2.cvtColor(arr, cv2.COLOR_YUV2BGR_I420)

    img = pygame.image.frombuffer(img, video.shape(), "BGR")
    screen.blit(img, (0, 0))    # Copy img onto the screen at coordinates: x=0, y=0
    pygame.display.update()
    pygame.event.pump()     # Makes pygame's window draggable / non-blocking.
    if eof:
        break
You might also like...
A GUI based glitch tool that uses FFMPEG to create motion interpolated glitches in your videos.
A GUI based glitch tool that uses FFMPEG to create motion interpolated glitches in your videos.

FF Dissolve Glitch This is a GUI based glitch tool that uses FFmpeg to create awesome and wierd motion interpolated glitches in videos. I call it FF d

 Extracting frames from video and create video using frames
Extracting frames from video and create video using frames

Extracting frames from video and create video using frames This program uses opencv library to extract the frames from video and create video from ext

High-performance cross-platform Video Processing Python framework powerpacked with unique trailblazing features :fire:
High-performance cross-platform Video Processing Python framework powerpacked with unique trailblazing features :fire:

Releases | Gears | Documentation | Installation | License VidGear is a High-Performance Video Processing Python Library that provides an easy-to-use,

Terminal-Video-Player - A program that can display video in the terminal using ascii characters

Terminal-Video-Player - A program that can display video in the terminal using ascii characters

MoviePy is a Python library for video editing,  can read and write all the most common audio and video formats
MoviePy is a Python library for video editing, can read and write all the most common audio and video formats

MoviePy is a Python library for video editing: cutting, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects. See the gallery for some examples of use.

Your own movie streaming service. Easy to install, easy to use. Download, manage and watch your favorite movies conveniently from your browser or phone. Install it on your server, access it anywhere and enjoy.
Your own movie streaming service. Easy to install, easy to use. Download, manage and watch your favorite movies conveniently from your browser or phone. Install it on your server, access it anywhere and enjoy.

Vigilio Your own movie streaming service. Easy to install, easy to use. Download, manage and watch your favorite movies conveniently from your browser

Text2Video's purpose is to help people create videos quickly and easily by simply typing out the video’s script and a description of images to include in the video.
Text2Video's purpose is to help people create videos quickly and easily by simply typing out the video’s script and a description of images to include in the video.

Text2Video Text2Video's purpose is to help people create videos quickly and easily by simply typing out the video’s script and a description of images

Takes a video as an input and creates a video which is suitable to upload on Youtube Shorts and Tik Tok (1080x1920 resolution).

Shorts-Tik-Tok-Creator Takes a video as an input and creates a video which is suitable to upload on Youtube Shorts and Tik Tok (1080x1920 resolution).

A youtube video link or id to video thumbnail python package.

Youtube-Video-Thumbnail A youtube video link or id to video thumbnail python package. Made with Python3

Comments
  • Read frames and frame info simultaneously

    Read frames and frame info simultaneously

    Hi, thank you for this useful script. I was wondering if you found a way to read frames and their info at the same time.

    Currently my code is as follows:

    video = VideoStream("rtsp://username:[email protected]:554")
    video.open_stream(showinfo=True)
    frames = 0
    
    print("\r\nReading VideoStream...")
    
    while True:
        eof, frame = video.read()
        print(video.showinfo())
        if eof:
            break
    
        frames += 1
    
    print(f"\r\nRead {frames} frames at {video.shape()} resolution from '{video.path}'")
    

    The code seems to work at the beginning, but after about 9 frames, it freezes. I added a print statement each time it reads showinfo.

    if self._si_active:
        print("showinfo")
        self._read_showinfo()
    

    and the output is as follows:

    Reading VideoStream...
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   0 pts:      0 pts_time:0       pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:1 type:I checksum:3F602568 plane_checksum:[3F602568] mean:[93] stdev:[65.1]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   1 pts:-114300 pts_time:-1.27   pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:318612CA plane_checksum:[318612CA] mean:[93] stdev:[65.1]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   2 pts: -89100 pts_time:-0.99   pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:2DAD38F4 plane_checksum:[2DAD38F4] mean:[93] stdev:[65.1]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   3 pts: -67500 pts_time:-0.75   pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:18CC4C1C plane_checksum:[18CC4C1C] mean:[93] stdev:[65.1]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   4 pts: -45900 pts_time:-0.51   pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:FEA81DA2 plane_checksum:[FEA81DA2] mean:[93] stdev:[65.0]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   5 pts: -24300 pts_time:-0.27   pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:2A53D294 plane_checksum:[2A53D294] mean:[93] stdev:[65.0]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   6 pts:    900 pts_time:0.01    pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:E8E50C81 plane_checksum:[E8E50C81] mean:[93] stdev:[65.1]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   7 pts:  22500 pts_time:0.25    pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:F73CF0E8 plane_checksum:[F73CF0E8] mean:[93] stdev:[65.1]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   8 pts:  44100 pts_time:0.49    pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:1 type:I checksum:8788376C plane_checksum:[8788376C] mean:[93] stdev:[65.1]
    
    showinfo
    [Parsed_showinfo_2 @ 0x55720530eb00] n:   9 pts:  65700 pts_time:0.73    pos:       -1 fmt:bgr24 sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:10FD111A plane_checksum:[10FD111A] mean:[93] stdev:[65.1]
    
    showinfo
    
    

    My assumption is that it tries to read from stderr but it doesn't have anything to read so it blocks for ever. Is there already a solution to this? thanks

    opened by Happy-hub 2
  • _even_test() returns True when .shape() is a tuple.

    _even_test() returns True when .shape() is a tuple.

    @bml1g12 reports:

    In _even_test(), the variable out is formed as a list from the values of self._shape, then tested for its equality against self._shape.

    # ...
    w, h = self._shape
    if w % 2 > 0: w -= 1
    if h % 2 > 0: h -= 1
    out = [w, h]
    if out != self._shape:
    # ...
    

    Because the user can pass a new self._shape in through .config(output_resolution=) , if that value is of the type tuple() it will not be equal to the list() type out.

    (1920, 1080) != [1920, 1080]
    # True
    

    The simple solution is to just force the type of self._shape during _even_test()'s comparison. So let's not do that!

    Instead, the unnecessarily comprehensive solution I'm going to push eliminates lists in the VideoStream object entirely. Having been forced to consider it in this issue, there's just no reason to invoke the read-write list() type in these variables when the read-only tuple() type will do. (and is theoretically faster and smaller)

    So in the coming commit, self._shape and self._crop initialize as tuples; The .config() method forces the pertinent arguments into tuple types; And _even_test() now reads out = (w, h) before comparison.

    opened by roninpawn 0
Owner
null
A tool to fuck a video/audio quality using FFmpeg

Media quality fucker A tool to fuck a video/audio quality using FFmpeg How to use Download the source Download Python Extract FFmpeg Put what you want

Maizena 8 Jan 25, 2022
Splat a video into a mosaic by sampling a frame at regular intervals

Splat a video into a mosaic by sampling a frame at regular intervals. Useful for seeing the changes over time of an entire video or movie.

Ryan Fox 4 Oct 16, 2022
A simple Telegram bot to extract hard-coded subtitle from videos using FFmpeg & Tesseract.

Video Subtitle Extractor Bot A simple Telegram bot to extract hard-coded subtitle from videos using FFmpeg & Tesseract. Note that the accuracy of reco

null 14 Oct 28, 2022
Stream music with ffmpeg and python

youtube-stream Stream music with ffmpeg and python original Usage set the KEY in stream.sh run server.py run stream.sh (You can use Git bash or WSL in

Giyoung Ryu 14 Nov 17, 2021
Python based script to operate FFMPEG.

FMPConvert Python based script to operate FFMPEG. Ver 1.0 -- 2022.02.08 Feature ✅ Maximum compatibility: Third-party dependency libraries unused ✅ Che

cybern000b 1 Feb 28, 2022
A wrapper around ffmpeg to make it work in a concurrent and memory-buffered fashion.

Media Fixer Have you ever had a film or TV show that your TV wasn't able to play its audio? Well this program is for you. Media Fixer is a program whi

Halit Şimşek 3 May 4, 2022
video streaming userbot (vsu) based on pytgcalls for streaming video trought the telegram video chat group.

VIDEO STREAM USERBOT ✨ an another telegram userbot for streaming video trought the telegram video chat. Environmental Variables ?? API_ID : Get this v

levina 6 Oct 17, 2021
A Telegram bot to convert videos into x265/x264 format via ffmpeg.

Video Encoder Bot A Telegram bot to convert videos into x265/x264 format via ffmpeg. Configuration Add values in environment variables or add them in

Adnan Ahmad 82 Jan 3, 2023
PyAV is a Pythonic binding for the FFmpeg libraries.

PyAV is a Pythonic binding for the FFmpeg libraries. We aim to provide all of the power and control of the underlying library, but manage the gritty details as much as possible.

PyAV 1.8k Jan 1, 2023
A Telegram bot to convert videos into x265/x264 format via ffmpeg.

Video Encoder Bot A Telegram bot to convert videos into x265/x264 format via ffmpeg. Configuration Add values in environment variables or add them in

null 1 Mar 8, 2022