Matlab - combine two videos into a single split-screen video

7.2k views Asked by At

I have 2 videos I would like to play side by side in a split screen. They are same duration and dimensions. I found a code developed few years back to do the job. The problem is, it is full of errors maybe due to the fact I am using a newer Matlab version (2014a). The errors start from (%name of the new avi file) onward.

Can anyone please try and fix it:

% select two files:
[filename1,pathname1] = uigetfile('.avi','pick first AVI file');
[filename2,pathname2] = uigetfile('.avi','pick second AVI file');
file1 = fullfile(pathname1,filename1);
file2 = fullfile(pathname2,filename2);  
pdMovie1 = aviread(file1);
pdMovie2 = aviread(file2);
fileinfo1 = aviinfo(file1);
fileinfo2 = aviinfo(file2);

% check if AVI files have the same length and height:
if fileinfo1.NumFrames~=fileinfo2.NumFrames || ...
    fileinfo1.Height~=fileinfo2.Height
errordlg('files are not compatible!')
else
% inspired by Herbert Ramoser in Message-ID:
% <[email protected]>
for i=1:size(pdMovie1,2)
  output(i).cdata = [pdMovie1(i).cdata, pdMovie2(i).cdata];
  output(i).colormap = pdMovie1(i).colormap;
end;

% name of the new avi file:
[pathstr,name,ext,versn] = fileparts(filename1);
newmoviename = [pathname1,name,'_combined', ...
                num2str(fileinfo1.FramesPerSecond;),ext];

% create the avi file:
movie2avi(output, newmoviename, ...
          'fps', fileinfo1.FramesPerSecond;, ...
          'compression', 'none');
close
end
2

There are 2 answers

3
SamuelNLP On BEST ANSWER

If it is just for playing the videos side-by-side, this simplker code will work,

close all
clc
clear

vid1 = vision.VideoFileReader('video1.avi');
vid2 = vision.VideoFileReader('video2.avi');
vidP = vision.VideoPlayer;

while ~isDone(vid1)
   frame1 = step(vid1);
   frame2 = step(vid2);

   frame = horzcat(frame1, frame2);

   step(vidP,frame);
end

release(vid1);
release(vid2);
release(vidP);

UPDATE: I'm assuming both input videos have the same length and frame dimension.

Ok, now if you want to record a new video from the first 2, with the same frame rate of the previous, it is better to use the following code,

close all
clc
clear

vid1 = VideoReader('video1.avi');
vid2 = VideoReader('video2.avi');

videoPlayer = vision.VideoPlayer;

% new video
outputVideo = VideoWriter('newvideo.avi');
outputVideo.FrameRate = vid1.FrameRate;
open(outputVideo);

while hasFrame(vid1) && hasFrame(vid2)
    img1 = readFrame(vid1);
    img2 = readFrame(vid2);

    imgt = horzcat(img1, img2);

    % play video
    step(videoPlayer, imgt);

    % record new video
    writeVideo(outputVideo, imgt);
end

release(videoPlayer);
close(outputVideo);
0
Linh Tran On

If you have two video clips with different frame rates and resolutions or you would like to join/cut pairs of video clips, use the code below.

For example: My dashcam is able to record video in the front and the rear of the car at the same time. But the front and rear videos come in separate files. I want to show them side by side as well as to join 6 files (3 pairs) into a single file.

%Read video
clc
clear
vidObj_f = VideoReader('video1.mp4');
FrameRate_f = vidObj_f.FrameRate;
vidObj_b = VideoReader('video2.mp4');
FrameRate_b = vidObj_b.FrameRate;

%New video
outputVideo = VideoWriter('combinedvideo.avi');
outputVideo.FrameRate = 24;
open(outputVideo);

skip = 95; %first seconds
j=skip*24;
try
while 1
    front = read(vidObj_f,1+round(j*FrameRate_f*1/24));
    back = read(vidObj_b,1+round(j*FrameRate_b*1/24));
    front = imresize(front,[720 1280]);
    videoframe = [front;back];
    writeVideo(outputVideo, videoframe);
    j = j+1;
end
catch
    disp('...end 1');
end

vidObj_f = VideoReader('video3.mp4');
FrameRate_f = vidObj_f.FrameRate;
vidObj_b = VideoReader('video4.mp4');
FrameRate_b = vidObj_b.FrameRate;

skip = 0; %first seconds
j=skip*24;
try
while 1
    front = read(vidObj_f,1+round(j*FrameRate_f*1/24));
    back = read(vidObj_b,1+round(j*FrameRate_b*1/24));
    front = imresize(front,[720 1280]);
    videoframe = [front;back];
    writeVideo(outputVideo, videoframe);
    j = j+1;
end
catch
    disp('...end 2');
end

vidObj_f = VideoReader('video5.mp4');
FrameRate_f = vidObj_f.FrameRate;
vidObj_b = VideoReader('video6.mp4');
FrameRate_b = vidObj_b.FrameRate;

skip = 0; %first seconds
j=skip*24;
cut = 30; %after playing 'cut' seconds
try
while 1
    front = read(vidObj_f,1+round(j*FrameRate_f*1/24));
    back = read(vidObj_b,1+round(j*FrameRate_b*1/24));
    front = imresize(front,[720 1280]);
    videoframe = [front;back];
    writeVideo(outputVideo, videoframe);
    if j>cut*24
        disp('...end 3 (cut)');
        break
    end
    j = j+1;

end
catch
    disp('...end 3');
end

close(outputVideo);