13

Is it possible to add (append) new frames to an existing .avi video file using OpenCV, without overwriting the whole file?

I am using OpenCV 2.4.2 on Windows 7, with Qt.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adrian
  • 188
  • 2
  • 10
  • 5
    Nope. You have to load all the video with VideoCapture, and rewrite everything, then add your frames. For more efficient ways to do it, have a look at ffmpeg. It's a command line utility that can split, merge extract frames from video, transcode, etc – Sam Aug 30 '12 at 10:53
  • "OpenCV4adnroid doesn’t support video reading and writing. Save a sequence of images then encode a video from this sequence from java" http://stackoverflow.com/questions/21546906/how-to-open-cvvideowriter-in-android – profimedica Dec 04 '15 at 00:59
  • 1
    Here's how to do it with ffmpeg https://stackoverflow.com/questions/18452058/ffmpeg-concat-videos-and-images – sziraqui Jan 30 '18 at 09:01

3 Answers3

0

If you want to use OpenCV, you have to read and write all the data content.

import cv2
import os

# this two lines are for loading the videos.
# in this case the video are named as: cut1.mp4, cut2.mp4, ..., cut15.mp4
# videofiles = [n for n in os.listdir('.') if n[0]=='c' and n[-4:]=='.mp4']
# videofiles = sorted(videofiles, key=lambda item: int( item.partition('.')[0][3:]))


videofiles = [n for n in os.listdir('.') if n[0]=='c' and n[-4:]=='.avi']
videofiles = sorted(videofiles, key=lambda item: int( item.partition('.')[0][3:]))

video_index = 0
cap = cv2.VideoCapture(videofiles[0])

# video resolution: 1624x1234 px
# out = cv2.VideoWriter("video.avi", 
#                       cv2.cv.CV_FOURCC('F','M','P', '4'), 
#                       15, (1624, 1234), 1)

# fourcc = cv2.VideoWriter_fourcc(*'MP4V')
# out = cv2.VideoWriter('cutout.mp4', fourcc, 20, (640, 480))

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('cutout.avi', fourcc, 20.0, (640, 480))

while(cap.isOpened()):
    ret, frame = cap.read()
    if frame is None:
        print ("end of video " + str(video_index) + " .. next one now")
        video_index += 1
        if video_index >= len(videofiles):
            break
        cap = cv2.VideoCapture(videofiles[ video_index ])
        ret, frame = cap.read()
    cv2.imshow('frame',frame)
    out.write(frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
out.release()
cv2.destroyAllWindows()

print ("end.")
SolessChong
  • 3,370
  • 8
  • 40
  • 67
-1

Open the existing video file using "cv2.VideoCapture". Create a new video file using "cv2.VideoWriter" with a different name. Read frames from the existing video file using "cap.read()". Write the frames to the new video file using writer.write(frame)". After writing all the existing frames, append your new frames to the new video file.

def append_frames_to_video(existing_video_path, new_frames):
    cap = cv2.VideoCapture(existing_video_path)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = cap.get(cv2.CAP_PROP_FPS)
    new_video_path = 'appended_video.avi'
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    writer = cv2.VideoWriter(new_video_path, fourcc, fps, (width, height))
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        writer.write(frame)
    for new_frame in new_frames:
        writer.write(new_frame)
    cap.release()
    writer.release()
    os.remove(existing_video_path)
    os.rename(new_video_path, existing_video_path)
existing_video_path = 'existing_video.avi'
new_frames = []
append_frames_to_video(existing_video_path, new_frames)
-4

Have a look at the VideoWriter class.

flix
  • 609
  • 4
  • 9