How can I pipe openCV images to ffmpeg (running ffmpeg as a subprocess)? (I am using spyder/anaconda)
I am reading frames from a video file and do some processing on each frame.
import cv2
cap = cv2.VideoCapture(self.avi_path)
img = cap.read()
gray = cv2.cvtColor(img[1], cv2.COLOR_BGR2GRAY)
bgDiv=gray/vidMed #background division
then, to pipe the processed frame to ffmpeg, I found this command in a related question:
sys.stdout.write( bgDiv.tostring() )
next, I am trying to run ffmpeg as a subprocess:
cmd='ffmpeg.exe -f rawvideo -pix_fmt gray -s 2048x2048 -r 30 -i - -an -f avi -r 30 foo.avi'
sp.call(cmd,shell=True)
(this also from the mentioned post) However, this fills my IPython console with cryptic hieroglyphs and then crashes it. any advice?
ultimately, I would like to pipe out 4 streams and have ffmpeg encode those 4 streams in parallel.
I'm Kind of late, But my powerful VidGear Python Library automates the process of pipelining OpenCV frames into FFmpeg on any platform. Here's a basic python example:
How to use opencv-python with various codecs without re-compiling opencv ! FFMPEG must be installed on your system. By default OpenCV is shipped with royalty free codecs only. For using non free codecs, you can compile OpenCV yourself (which takes time) or you can pipe OpenCV with FFMPEG .。 In this example we will use the VP8 codec.
If you can get OpenCV to read from a pipe rather than trying to write to a file or read frame by frame, you'll avoid a lot of complexity + overhead.
By default OpenCV is shipped with royalty free codecs only. For using non free codecs, you can compile OpenCV yourself (which takes time) or you can pipe OpenCV with FFMPEG .。 In this example we will use the VP8 codec.
I had similar problem once. I opened an issue on Github, turns out it may be a platform issue.
Related to your question, you can as well pipe OpenCV images to FFMPEG. Here's a sample code:
# This script copies the video frame by frame
import cv2
import subprocess as sp
input_file = 'input_file_name.mp4'
output_file = 'output_file_name.mp4'
cap = cv2.VideoCapture(input_file)
ret, frame = cap.read()
height, width, ch = frame.shape
ffmpeg = 'FFMPEG'
dimension = '{}x{}'.format(width, height)
f_format = 'bgr24' # remember OpenCV uses bgr format
fps = str(cap.get(cv2.CAP_PROP_FPS))
command = [ffmpeg,
'-y',
'-f', 'rawvideo',
'-vcodec','rawvideo',
'-s', dimension,
'-pix_fmt', 'bgr24',
'-r', fps,
'-i', '-',
'-an',
'-vcodec', 'mpeg4',
'-b:v', '5000k',
output_file ]
proc = sp.Popen(command, stdin=sp.PIPE, stderr=sp.PIPE)
while True:
ret, frame = cap.read()
if not ret:
break
proc.stdin.write(frame.tostring())
cap.release()
proc.stdin.close()
proc.stderr.close()
proc.wait()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With