Concatenate 2 videos into 1 using Python

Question:

I want to write a program that monitors and tracks objects in 2 different videos using openCV in python (cv2).

I would like to Merge the two videos into 1 video then run a program on that video to track objects.

Could someone please show and explain the instructions behind merging them?

My code here doesn’t Work. It launches video 2 after the first frame of video 1

import cv2


capture = cv2.VideoCapture('p1a_tetris_1.mp4') #tell open cv to use the following video file as input


while capture.isOpened():


        ret, frame = capture.read() #capture each frame from the video . 
                                #ret is a boolean to indicate if the 

        if ret == True :    
            grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # apply gray frame to current frame


            cv2.imshow('video Part 1', grayFrame) # shows video in grascale 


        else : 
            capture = cv2.VideoCapture('p1a_tetris_2.mp4')

            while capture.isOpened():
                try:      
                    ret, frame = capture.read()
                    print(ret)

                    if ret == True :    
                        grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # apply gray frame to current frame

                        cv2.imshow('Video Part 2', grayFrame) # shows video in grascale 

                        if cv2.waitKey(1) == 27:
                            break
                    else : 

                        break
                except :
                    print("error occured")

capture.release()
cv2.destroyAllWindows()

Asked By: 0xD1x0n

||

Answers:

FFMPEG was not my solution…

I used moviepy instead (much simpler btw)

from moviepy.editor import VideoFileClip, concatenate_videoclips


clip_1 = VideoFileClip("p1b_tetris_1.mp4")
clip_2 = VideoFileClip("p1b_tetris_2.mp4")
final_clip = concatenate_videoclips([clip_1,clip_2])
final_clip.write_videofile("final.mp4")
Answered By: 0xD1x0n

moviepy has mostly yielded corrupted files for me so here is a just as fast approach with cv2:

# A list of the paths of your videos
videos = ["v1.mp4", "v2.mp4"]

# Create a new video
video = cv2.VideoWriter("new_video.mp4", cv2.VideoWriter_fourcc(*"MPEG"), fps, resolution)

# Write all the frames sequentially to the new video
for v in videos:
    curr_v = cv2.VideoCapture(v)
    while curr_v.isOpened():
        # Get return value and curr frame of curr video
        r, frame = curr_v.read()
        if not r:
            break
        # Write the frame
        video.write(frame)

# Save the video
video.release()

A function for easy copy-pasting:

def concatenate_videos(new_video_path, *videos):
    video = cv2.VideoWriter(new_video_path, cv2.VideoWriter_fourcc(*"MPEG"), fps, resolution)

    for v in videos:
        curr_v = cv2.VideoCapture(v)
        while curr_v.isOpened():
            r, frame = curr_v.read()
            if not r:
                break
            video.write(frame)

    video.release()
Answered By: SaladHead
    import cv2
    import numpy as np

    def merge_video(video1, video2):

    camera = cv2.VideoCapture(video1)
    cv2.namedWindow("detection", cv2.WINDOW_AUTOSIZE)


    sz = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)),
        int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    fourcc = cv2.VideoWriter_fourcc(*'mpeg')


    vout = cv2.VideoWriter()
    vout.open(os.path.join("output.mp4"), fourcc, 20, sz, True)

    while True:
        res, frame = camera.read()

        if not res:
            break

        cv2.imshow("detection", frame)

        # Save the video frame by frame
        vout.write(frame)

        if cv2.waitKey(110) & 0xff == 27:
                break

    camera = cv2.VideoCapture(video2)
    cv2.namedWindow("detection", cv2.WINDOW_AUTOSIZE)


    while True:
        res, frame = camera.read()

        if not res:
            break

        cv2.imshow("detection", frame)

        # Save the video frame by frame
        vout.write(frame)

        if cv2.waitKey(110) & 0xff == 27:
                break
    vout.release()
    camera.release()
Answered By: maydin

Using numpy.hstack() may be more efficient.

import cv2
import numpy as np
 
INPUT_FILE1 = 'im.avi'
INPUT_FILE2 = 'bg.avi'
OUTPUT_FILE = 'merge.avi'
 
reader1 = cv2.VideoCapture(INPUT_FILE1)
reader2 = cv2.VideoCapture(INPUT_FILE2)
width = int(reader1.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(reader1.get(cv2.CAP_PROP_FRAME_HEIGHT))
writer = cv2.VideoWriter(OUTPUT_FILE,
              cv2.VideoWriter_fourcc('I', '4', '2', '0'),
              30, # fps
              (width, height//2)) # resolution
 
print(reader1.isOpened())
print(reader2.isOpened())
have_more_frame = True
c = 0
while have_more_frame:
    have_more_frame, frame1 = reader1.read()
    _, frame2 = reader2.read()
    frame1 = cv2.resize(frame1, (width//2, height//2))
    frame2 = cv2.resize(frame2, (width//2, height//2))
    img = np.hstack((frame1, frame2))
    cv2.waitKey(1)
    writer.write(img)
    c += 1
    print(str(c) + ' is ok')
 
 
writer.release()
reader.release()
cv2.destroyAllWindows()
Answered By: yanzhen xu