Search code examples
c#wpfffmpegavibitmapsource

Save WPF BitmapSources as h264 encoded video directly from Memory


Currently I am utilizing a List-variable to store BitmapSources provided by a camera and save them as an AVI file with the help of SharpAvi. In a second step I then encode the saved file via Nrecos ffmpeg wrapper to decrease file size. Finally I delete the original AVI file and only keep the encoded one.

To me this seems poorly designed and might cause harmful write-cycles to the SSD the application is running on (I'll probably create up to a TB a day in unencoded video), which is why I want to change it to a more integrated solution utilizing the PC's RAM. SharpAvi as well as Nreco however rely on creating and reading actual files. Nreco does have the ConvertLiveMedia method that accepts a stream - however in my experiments it simply did not create a file while giving me no error warnings.


Solution

  • Ok I think I solved it: I changed the SharpAvi code so that the AviWriter has an additional constructor accepting a MemoryStream instead of just a string. This MemoryStream is then passed to the BinaryWriter and no FileStream is created.

    Also the close Method had to be changed so that the MemoryStream stays alive even when the BinaryWriter is closed.fileWriter.Closeis replaced with

    if (fileWriter.BaseStream is MemoryStream)
        fileWriter.Flush();
    else
        fileWriter.Close();
    

    This leaves me with a usable MemoryStream in my main application.

    memstream.Position = 0; //crucial or otherwise ffmpeg will not work
    var task = nrecoconverter.ConvertLiveMedia(memstream, "avi", filepath, "avi", settings);
    task.Start();
    task.Wait();
    

    Edit: SharpAvi has officially been changed on github to allow the use of Streams now.