Hello,
Thanks for this work, I was looking form something like this. More precisely, I want to make a movie from animated 3D scenes in a TViewport3D in Firemonkey.
So I took your UMultidemo example. I put a Tviewport3D on the form, and in it a TCube, with an associated TFloatanimation making it rotate around an axis for 7 seconds.
With an additional TImagelist on the form, I make a list of bitmaps with
TForm1.FloatAnimation1Process
...
BM:=Viewport3D1.MakeScreenshot;
Imagelist1.Add(BM);
CX:=BM.Size.cx;
CY:=BM.Size.cy;
...
CX and CY being vars of the unit. Yes, they're rewritten each time with the same value, but I can improve that later.
The Imagelist1.Add is taken from the TImageListHelper here :
https://stackoverflow.com/questions/36013186/how-to-insert-images-to-timagelist-in-firemonkey-programmaticaly
adding FMX.ImgList and FMX.MultiResBitmap to "uses".
And then, I just modified TForm1.MakeSlideshow by replacing
// 23 sec of movie
I := 1;
while I < 4 do
begin
if I > 1 then
bme.CrossFade(am, bm, 1000);
bme.AddStillImage(bm, 3000);
bme.CrossFade(bm, am, 1000);
bme.AddStillImage(am, 3000);
inc(I);
end;
// Hold end frame for 2 seconds
bme.Freeze(2000);
with
for j :=0 to Imagelist1.Count-1 do
begin
am.Assign(Imagelist1.Bitmap(TSizef.Create(CX,CY),j));
bme.AddStillImage(am, 17);
end;
Since the Timer on animations is 60 times per second and 1000/60 = 16.6666
And then, I start the animation in TForm1.Create, excute the program, wait till the animation is over, press the "Make a simple slideshow" without changing the options combos and I get a movie with the rotating cube in the viewport.
Exactly what I wanted. ... almost.
I'm supposed to have 60 bitmaps per second, and with an animation lasting 7 seconds Imagelist1.Count is 400 instead of 420. No idea why. Other times it's 397...
But the movie lasts 13 seconds. Yes, the frame rate combo was on 30 frames per second, so I changed for 60, tried again... and another movie lasting 13 seconds.
I tried the other way round by leaving 30 frames per seconds the combo and instead writing in the code :
bme.AddStillImage(am, 8);
The movie still lasted 13 seconds !
Finally, I did both : 8 milliseconds in AddStillImage and 60 frames per second in the combo, and I got a movie lasting 6 seconds.
I suppose there are effects of "round"ing that lead to this uncertainty.
Now for the size. I thought it would be even better having a movie with the same size as the viewport.
So I thought I could replace in MakeSlideshow
Height := MovieHeights[HeightCombo.ItemIndex];
with
Height := CY;
But this time it fails.
By debugging, I found that in TBitmapEncoderM.Create in UBitmaps2VideoM.pas
it's avcodec_open2(c, codec, @CodecSetup.OptionsDictionary); that fails.
and this time it's a function of a dll of FFMPEG, and for the time being, I don't want to dive deep into the specs...
Is there a relatively easy way (other than making my own DLLs and rewriting FFMEG, and from within Delphi, not by using some "MS DOS command line" tricks "ffmpeg -option1 -option2...") to customize the size of my movie to anything like 123 x 456 or should I stick to 720, 540 or 1080 for the height and the predifined aspect ratios ?
And eventually, is there an easy way to write meta data (author, etc.) to the file. I have seen a few things in the comments of FFMPEG.pas, but no syntax guidelines.