How do I create Video from Bitmaps in memory

Topics: Developer Forum, User Forum
Apr 25, 2011 at 9:15 PM
I am trying to create a Video from bitmaps in memory. I am new to Splicer and am using the sample provided.
All the bitmaps are of same height and width. Each bitmap is supposed to represent a single frame. 
Even if I set the Frame Rate (for e.g. frame rate is 31 fps and number of frames is 23, this should give me a video of duration 0.72sec) the files being created are of longer duration.
The files are of length e.g., 27 secs for frame rate 31fps and 23 frames. How do I actually add image frames so that the frame rate is achieved.

public bool CreateVideo(List<CustomBitmap> bitmaps, string outputFile, double durationOfVideo, double Fps, int width, int height)
        {
            try
            {                
                using (ITimeline timeline = new DefaultTimeline(Fps))
                {                    
                    IGroup group = timeline.AddVideoGroup(32, width, height);
                    ITrack videoTrack = group.AddTrack();
                    int i = 0;
                    foreach (var bmp in bitmaps)
                    {
                        System.Diagnostics.Debug.WriteLine(++i);
                        IClip clip = videoTrack.AddImage(bmp.BitmapImage);
                    }
                    timeline.AddAudioGroup();
                    IRenderer renderer =
                          new WindowsMediaRenderer(timeline, outputFile, WindowsMediaProfiles.HighQualityVideo);
                    {
                        renderer.Render();
                    }
                    return true;
                }
            }
            catch { return false; }
        }

Apr 26, 2011 at 8:17 AM
Edited Apr 26, 2011 at 8:17 AM

If you try stepping through your code, you will find that this overload of Track.AddImage() actually adds a clip of duration DefaultImageDisplayDuration seconds to your timeline.  I think you need to use one of the overloads that allows you to specify clipStart and clipEnd.  But I am not sure since I'm a newbie, too.

Please report back if you find a solution, as this will help others.

Apr 26, 2011 at 1:20 PM
Edited Apr 26, 2011 at 1:26 PM

peter, I know about the overloaded methods but was not sure how to approach the timeline as the documentation is not extensive ... I am using trial and error method and the following code provides a movie which is nearer to what I am expecting ...

I modified the code to create files but I am not 100% sure if this piece of code is correct

public bool CreateVideo(List<CustomBitmap> bitmaps, string outputFile, double durationOfVideo, double Fps, int width, int height)
        {
            if (bitmaps == null || bitmaps.Count == 0) return false;
            try
            {
                using (ITimeline timeline = new DefaultTimeline(Fps))
                {
                    IGroup group = timeline.AddVideoGroup(32, width, height);
                    ITrack videoTrack = group.AddTrack();
                    int i = 0;
                    double miniDuration = durationOfVideo / bitmaps.Count;
                    foreach (var bmp in bitmaps)
                    {
                        IClip clip = videoTrack.AddImage(bmp.BitmapImage, 0, i * miniDuration, (i + 1) * miniDuration);
                        System.Diagnostics.Debug.WriteLine(++i);
                    }
                    timeline.AddAudioGroup();
                    IRenderer renderer = new WindowsMediaRenderer(timeline, outputFile, WindowsMediaProfiles.HighQualityVideo);
                    renderer.Render();
                    return true;
                }
            }
            catch { return false; }
        }
Apr 27, 2011 at 9:48 AM

In your case, durationOfVideo need not be passed as input argument; it depends on Fps and bitmaps.Count.  Your variable miniDuration can be calculated as 1.0 / Fps.  I haven't created a video from bitmaps yet, but I think the code should work fine.

Apr 27, 2011 at 2:58 PM

Thanks for your feedback. You are right that I do not need to send the durationOfVideo and can calculate it on the fly (which I am actually doing outside this piece of code as [1 / Fps * bitmaps.Count] and that is the reason why the miniDuration is being calculated as [durationOfVideo / bitmaps.Count] rather than [1 / Fps]. In some scenarios I actually have the durationOfVideo available without calculating it and that is the reason I am sending it as a parameter rather than calculating it every time).

Anyways it seems that the piece of code is providing me with a good enough image playback.