Skip to content

Instantly share code, notes, and snippets.

@eruffaldi
Last active April 22, 2024 07:17
Show Gist options
  • Select an option

  • Save eruffaldi/1226191b0dd50737e74dafc0ec73caad to your computer and use it in GitHub Desktop.

Select an option

Save eruffaldi/1226191b0dd50737e74dafc0ec73caad to your computer and use it in GitHub Desktop.

Revisions

  1. eruffaldi revised this gist Jan 25, 2017. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions ffmpeg_opencv.py
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,10 @@
    #
    # Reading video from FFMPEG using subprocess - aka when OpenCV VideoCapture fails
    #
    # 2017 note: I have realized that this is similar to moviepy ffmpeg reader with the difference that here we support YUV encoding
    # BUT we lack: bufsize in POpen and creation flags for windows
    # https://github.com/Zulko/moviepy/blob/master/moviepy/video/io/ffmpeg_reader.py
    #
    # Emanuele Ruffaldi 2016
    import cv2
    import subprocess
  2. eruffaldi revised this gist Dec 30, 2016. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions ffmpeg_opencv.py
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #
    # Reading video from FFMPEG using subprocess
    # Reading video from FFMPEG using subprocess - aka when OpenCV VideoCapture fails
    #
    # Emanuele Ruffaldi 2016
    import cv2
    @@ -8,9 +8,10 @@
    import os

    class FFmpegVideoCapture:
    # TODO default width/height or force in output
    # TODO probe width/height
    # TODO enforce width/height
    #
    # mode=gray or yuv420p
    # mode=gray,yuv420p,rgb24,bgr24
    def __init__(self,source,width,height,mode="gray",start_seconds=0,duration=0,verbose=False):

    x = ['ffmpeg']
  3. eruffaldi revised this gist Dec 30, 2016. No changes.
  4. eruffaldi revised this gist Dec 30, 2016. 1 changed file with 54 additions and 5 deletions.
    59 changes: 54 additions & 5 deletions ffmpeg_opencv.py
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,18 @@
    #
    # Reading video from FFMPEG using subprocess
    #
    # Emanuele Ruffaldi 2016
    import cv2
    import subprocess
    import numpy as np
    import os

    class FFmpegVideoCapture:
    # TODO other than grayscale
    # TODO default width/height or force in output
    def __init__(self,source,width,height,start_seconds=0,duration=0,verbose=False):
    #
    # mode=gray or yuv420p
    def __init__(self,source,width,height,mode="gray",start_seconds=0,duration=0,verbose=False):

    x = ['ffmpeg']
    if start_seconds > 0:
    #[-][HH:]MM:SS[.m...]
    @@ -12,17 +23,55 @@ def __init__(self,source,width,height,start_seconds=0,duration=0,verbose=False):
    if duration > 0:
    x.append("-t")
    x.append("%f" % duration)
    x.extend(['-i', source,"-f","rawvideo", "-pix_fmt" ,"gray","-"])
    x.extend(['-i', source,"-f","rawvideo", "-pix_fmt" ,mode,"-"])
    self.nulldev = open(os.devnull,"w") if not verbose else None
    self.ffmpeg = subprocess.Popen(x, stdout = subprocess.PIPE, stderr=subprocess.STDERR if verbose else self.nulldev)
    self.width = width
    self.height = height
    self.fs = width*height
    self.mode = mode
    if self.mode == "gray":
    self.fs = width*height
    elif self.mode == "yuv420p":
    self.fs = width*height*6/4
    elif self.mode == "rgb24" or self.mode == "bgr24":
    self.fs = width*height*3
    self.output = self.ffmpeg.stdout
    def read(self):
    if self.ffmpeg.poll():
    return False,None
    x = self.output.read(self.fs)
    if x == "":
    return False,None
    return True,np.frombuffer(x,dtype=np.uint8).reshape((self.height,self.width))
    if self.mode == "gray":
    return True,np.frombuffer(x,dtype=np.uint8).reshape((self.height,self.width))
    elif self.mode == "yuv420p":
    # Y fullsize
    # U w/2 h/2
    # V w/2 h/2
    k = self.width*self.height
    return True,(np.frombuffer(x[0:k],dtype=np.uint8).reshape((self.height,self.width)),
    np.frombuffer(x[k:k+(k/4)],dtype=np.uint8).reshape((self.height/2,self.width/2)),
    np.frombuffer(x[k+(k/4):],dtype=np.uint8).reshape((self.height/2,self.width/2))
    )
    elif self.mode == "bgr24" or self.mode == "rgb24":
    return True,(np.frombuffer(x,dtype=np.uint8).reshape((self.height,self.width,3)))


    if __name__ == '__main__':
    import sys
    if len(sys.argv) < 5:
    print "filename w h mode\nWhere mode is: gray|yuv420p|bgr24"
    else:
    capture = FFmpegVideoCapture(sys.argv[1],int(sys.argv[2]),int(sys.argv[3]),sys.argv[4])
    while True:
    ret, img = capture.read()
    if not ret:
    print "exit with",ret,img
    break
    if type(img) is tuple:
    cv2.imshow("Y",img[0])
    cv2.imshow("U",img[1])
    cv2.imshow("V",img[2])
    else:
    cv2.imshow("img",img)
    cv2.waitKey(1)
  5. eruffaldi revised this gist Dec 29, 2016. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions ffmpeg_opencv.py
    Original file line number Diff line number Diff line change
    @@ -23,4 +23,6 @@ def read(self):
    if self.ffmpeg.poll():
    return False,None
    x = self.output.read(self.fs)
    if x == "":
    return False,None
    return True,np.frombuffer(x,dtype=np.uint8).reshape((self.height,self.width))
  6. eruffaldi revised this gist Dec 29, 2016. 1 changed file with 16 additions and 26 deletions.
    42 changes: 16 additions & 26 deletions ffmpeg_opencv.py
    Original file line number Diff line number Diff line change
    @@ -1,36 +1,26 @@
    # TODO: automatic width/height
    #
    # This example is specific to grayscale, when gstreamer-opencv is not capable of opening a gray only mp4
    import cv2
    import subprocess
    import numpy as np

    class FFmpegVideoCapture:
    def __init__(self,source,width,height):
    self.ffmpeg = subprocess.Popen(['ffmpeg', '-i', source,"-f","rawvideo", "-pix_fmt" ,"gray","-" ], stdout = subprocess.PIPE)
    # TODO other than grayscale
    # TODO default width/height or force in output
    def __init__(self,source,width,height,start_seconds=0,duration=0,verbose=False):
    x = ['ffmpeg']
    if start_seconds > 0:
    #[-][HH:]MM:SS[.m...]
    #[-]S+[.m...]
    x.append("-accurate_seek")
    x.append("-ss")
    x.append("%f" % start_seconds)
    if duration > 0:
    x.append("-t")
    x.append("%f" % duration)
    x.extend(['-i', source,"-f","rawvideo", "-pix_fmt" ,"gray","-"])
    self.nulldev = open(os.devnull,"w") if not verbose else None
    self.ffmpeg = subprocess.Popen(x, stdout = subprocess.PIPE, stderr=subprocess.STDERR if verbose else self.nulldev)
    self.width = width
    self.height = height
    self.fs = width*height
    self.output = self.ffmpeg.stdout
    def read(self):
    if self.ffmpeg.poll():
    print "done"
    return False,None
    x = self.output.read(self.fs)
    print "read",self.fs,len(x)
    return True,np.frombuffer(x,dtype=np.uint8).reshape((self.height,self.width))


    def main():
    capture = FFmpegVideoCapture("full.mp4",1280,1024)
    while True:
    ret, img = capture.read()
    if not ret:
    print "exit with",ret,img
    break

    cv2.imshow("window",img)
    cv2.waitKey(1)

    if __name__ == '__main__':
    main()
  7. eruffaldi created this gist Dec 28, 2016.
    36 changes: 36 additions & 0 deletions ffmpeg_opencv.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    # TODO: automatic width/height
    #
    # This example is specific to grayscale, when gstreamer-opencv is not capable of opening a gray only mp4
    import cv2
    import subprocess
    import numpy as np

    class FFmpegVideoCapture:
    def __init__(self,source,width,height):
    self.ffmpeg = subprocess.Popen(['ffmpeg', '-i', source,"-f","rawvideo", "-pix_fmt" ,"gray","-" ], stdout = subprocess.PIPE)
    self.width = width
    self.height = height
    self.fs = width*height
    self.output = self.ffmpeg.stdout
    def read(self):
    if self.ffmpeg.poll():
    print "done"
    return False,None
    x = self.output.read(self.fs)
    print "read",self.fs,len(x)
    return True,np.frombuffer(x,dtype=np.uint8).reshape((self.height,self.width))


    def main():
    capture = FFmpegVideoCapture("full.mp4",1280,1024)
    while True:
    ret, img = capture.read()
    if not ret:
    print "exit with",ret,img
    break

    cv2.imshow("window",img)
    cv2.waitKey(1)

    if __name__ == '__main__':
    main()