Code to create animated plot and capture/write as AVI movie returns no errors but only a single frame AVI file.
12 views (last 30 days)
Show older comments
Peter Beringer
on 14 Oct 2020
Commented: Peter Beringer
on 15 Oct 2020
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
0 Comments
Accepted Answer
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
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.
More Answers (0)
See Also
Categories
Find more on Audio and Video Data in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!