Skip to content

Instantly share code, notes, and snippets.

@vadimkantorov
Last active May 3, 2022 16:40
Show Gist options
  • Select an option

  • Save vadimkantorov/8faebf8c074b1d4774f771e474663e17 to your computer and use it in GitHub Desktop.

Select an option

Save vadimkantorov/8faebf8c074b1d4774f771e474663e17 to your computer and use it in GitHub Desktop.
Simple python FFmpeg pipe wrapper for reading videos
# print(next(iter(FFmpeg('video.mp4')))[0].shape)
# (480, 640, 3)
# print(next(iter(FFmpeg('video.mp4')))[1])
# 0.0799333
import subprocess
import json
import re
import numpy as np
class FFmpeg(object):
def __init__(self, file_path, begin_time_stamp = '00:00:00', depth = 3, pipe_buffer_size = 10 ** 8):
self.file_path = file_path
self.begin_time_stamp = begin_time_stamp
self.pipe_buffer_size = pipe_buffer_size
self.height, self.width, self.depth = list(map(json.loads(subprocess.check_output(['ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_streams', self.file_path]).decode('utf-8'))['streams'][0].get, ['height', 'width'])) + [depth]
def __iter__(self):
pipe = subprocess.Popen(['ffmpeg', '-nostats', '-hide_banner', '-ss', self.begin_time_stamp, '-i', self.file_path, '-vf', 'showinfo', '-an', '-f', 'image2pipe', '-pix_fmt', 'rgb24', '-vcodec', 'rawvideo', '-'], bufsize = self.pipe_buffer_size, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
while pipe.poll() is None:
raw_image = pipe.stdout.read(self.height * self.width * self.depth)
frame = np.fromstring(raw_image, dtype = np.uint8).reshape((self.height, self.width, self.depth))
pipe.stdout.flush()
pts_time = next(float(match.group(1)) for line in iter(pipe.stderr.readline, '') for match in [re.search(b'pts_time:(\d+\.?\d*) ', line)] if match is not None)
pipe.stderr.flush()
yield frame, pts_time
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment