Code to create animated plot and capture/write as AVI movie returns no errors but only a single frame AVI file.

21 views (last 30 days)
This code is a "scale model" of a larger plotting code for a 10x10 matrix of audio measurements. I wish to write the animated plot as an *.AVI file (or *.MOV or *.MP4, etc.) for digital submission. I thought I'd cracked it with this code, as no errors were prodcued, but the video file written contains only a single frame (I assume the first). The same result occurs with the video writing lines inside and outside the 'for' loop - I tried it "writing whilst generating" and "writing once generated" (if that makes sense). Should this process be put in a nested 'for' loop? The commented-out code for writing a GIF animation works fine, but including a GIF to AVI process seems like "double-handling" and rather inefficient.
With no error message displayed by MATLAB, I'm not sure where to go. There doesn't appear to be anything already on MATLAB Answers that matches this kind of result. I found a question thread that I thought addressed the same issue, but it turned out to be playing too quickly, rather than only writing one frame. To test if this was the case I tried adding:
VideoObj.FrameRate = 1;
But it was clear that only a single frame had been written to the AVI file.
Thanks.
Here is the main code:
% "SCALE MODEL" of 10x10 PLOTTING CODE
% Build random matrices for example purposes - 5 "channels" of audio, each
% 20 "samples" long. Each five channel signal "played" from five
% positions, resulting in a 5 x 5 matrix of microphones/measurements/audio
% vectors.
fs = 5; % Otherwise 48000 for audio measurements.
a = -1; % Generate values between -1 and 1 to simulate audio signals.
b = 1;
Position1 = a + (b - a) .* rand(20,5); % Would call audio data here.
Position2 = a + (b - a) .* rand(20,5); % Format: Pos01audio = Pos01audiodata.audio(:,1:10);
Position3 = a + (b - a) .* rand(20,5); % Should audio vectors be tranposed into rows?
Position4 = a + (b - a) .* rand(20,5);
Position5 = a + (b - a) .* rand(20,5);
[NumSamples] = size(Position1(:,1)); % Get length of audio vectors from any; all measurements are the same length; 4secs or 4*fs.
NumSamples = NumSamples(1,1);
for i = 1 : NumSamples % Length of audio file in samples.
PlotMatrix = [Position1(i,:); Position2(i,:); Position3(i,:); Position4(i,:); Position5(i,:)]; % Concatenate arrays into matrix to be rewritten in 'for' loop.
OutputPlot = surf(PlotMatrix);
grid on
pause(1/fs) % Make pause equivalent to sample rate.
drawnow
PlotHandle = gcf;
ImageFrames = getframe(PlotHandle);
im = frame2im(ImageFrames);
[imind, cm] = rgb2ind(im,256);
end
% Write AVI video file
VideoObj = VideoWriter('AnimatedPlot.avi');
open(VideoObj);
writeVideo(VideoObj, ImageFrames);
% % Write GIF file
% if i == 1
% imwrite(imind, cm, 'AnimatedFigure.gif', 'gif', 'Loopcount', inf);
% else
% imwrite(imind, cm, 'AnimatedFigure.gif', 'gif', 'WriteMode', 'append');
% end

Accepted Answer

Ameer Hamza
Ameer Hamza on 14 Oct 2020
Edited: Ameer Hamza on 14 Oct 2020
You are just saving a single frame inside for-loop. Change the lines to
ImageFrames(i) = getframe(PlotHandle); % save an array of frames
im = frame2im(ImageFrames(i));
at the end, close the VideoWriter object
close(VideoObj)
  5 Comments
Ameer Hamza
Ameer Hamza on 15 Oct 2020
You mean you get video loops when you add the line
writeVideo(VideoObj, ImageFrames)
inside the for-loop. Right? Outside the for-loop this will work fine.

Sign in to comment.

More Answers (0)

Products


Release

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!