Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to write lossless video in Python

OpenCV does a reasonable job of reading videos from file or webcams. It's simple and mostly works. When it comes to writing videos, it however leaves a lot to be desired. There is little control over the codecs and it is almost impossible to know which codecs are installed. It also wants to know things like the frame size at intailisation. This isn't always a problem, but if you don't know it yet it means you have to set up the video writer inside your main processing loop.

To make something as cross-platform compatible as possible it would be nice to use FFmpeg. There are a few python wrappers around, but as far as I can tell they are mainly used for transcoding type applications. One solution is run FFmpeg as a subprocess and set its input to accept a pipe. Then every video frame is passed through the pipe. You write this yourself, in fact it's only a few lines of code. However, the scikit-video package will do this for us, with some nice boilerplate to make life easier.

The steps are:

  1. install FFmpeg -- if you running on Linux use your system's package manager if it's not already installed. If you're unlucky enough to be using Windows you need to download the zip file from here, and add the bin directory to your system's path.
  2. install scikit-video --I tried installing scikit-video via pip on my Anaconda distro but the version was too old. Instead, I cloned the github version and installed that. Instructions are provided on github.

Below is a simple example the grabs from your webcam and records lossless video.

#test recording of video
import cv2
import skvideo.io


capture=cv2.VideoCapture(0) #open the default webcam
outputfile = "test.mp4"   #our output filename
writer = skvideo.io.FFmpegWriter(outputfile, outputdict={
  '-vcodec': 'libx264',  #use the h.264 codec
  '-crf': '0',           #set the constant rate factor to 0, which is lossless
  '-preset':'veryslow'   #the slower the better compression, in princple, try 
                         #other options see https://trac.ffmpeg.org/wiki/Encode/H.264
}) 
while True:
    ret,frame=capture.read()
    if ret==False:
        print("Bad frame")
        break
    cv2.imshow('display',frame)
    writer.writeFrame(frame[:,:,::-1])  #write the frame as RGB not BGR
    ret=cv2.waitKey(10)
    if ret==27: #esc
        break

writer.close() #close the writer
capture.release()
cv2.destroyAllWindows()
@supriya1010

This comment has been minimized.

Copy link

@supriya1010 supriya1010 commented Apr 19, 2020

hello ,
i want to do same thing on video which already saved
could you pls help me

@PHDPeter

This comment has been minimized.

Copy link

@PHDPeter PHDPeter commented Jun 25, 2020

hello ,
i want to do same thing on video which already saved
could you pls help me

at
capture=cv2.VideoCapture(0) #open the default webcam
rather the 0 add the path to the video file you want to load

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment