1

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.

Daniel M
  • 105
  • 2
  • 11
  • Is it possible to use a camera as input source for NReco ffmpeg wrapper? You can do that if camera is accessible as DirectShow device or if stream is provided by URL. This will be most efficient way to transcode video and save to the file. – Vitaliy Fedorchenko Dec 02 '16 at 07:05
  • I don't think so. especially since I still need to be able to use the camera for parallel image analysis in Aforge and a live-preview for the user. With the solution I provided I think the best option has been given for this particular use-case. – Daniel M Dec 02 '16 at 11:02
  • 1
    If you have frames as images in C# (Bitmap objects) you also can push them directly to ffmpeg input using ConvertLiveMedia method (with special "raw_video" format). – Vitaliy Fedorchenko Dec 02 '16 at 11:05
  • that I can try - instead of sending it through sharpavi I could then directly send them to convertLivemedia. Will let you know on Monday. However I only have them as WPF BitmapSources - not Forms Bitmaps. Don't know if the conversion will eliminate any benefits this method would have. – Daniel M Dec 02 '16 at 17:03
  • Hi Daniel can you please send the code to save BitmapSources as an AVI file. – Sanjay Gupta May 17 '18 at 12:37

1 Answers1

1

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.

Daniel M
  • 105
  • 2
  • 11
  • My issue now is, I'm using the AviWriter MemoryStream method but I'm not sure how to make NReco to do the converting right away instead of waiting to SharpAvi to finish recording. so I'm doing this in my main after recording done I do `rec.Dispose(); byte[] file = File.ReadAllBytes(outfile); MemoryStream aStream = new MemoryStream(file); aStream.Position = 0; var task = conv.ConvertLiveMedia(aStream, "avi", outfile, "mp4", s); task.Start(); task.Wait();` – 0x2bad Jun 13 '17 at 14:03
  • I am not sure I understand what your problem is. You obviously have to wait for sharpavi to finish before you can pass the stream to nreco (or ffmpeg) as it needs to represent an entire file as a whole. – Daniel M Jun 25 '17 at 17:04