Search code examples
c#imagevideomjpeg

Creating an MJPEG video from still images using C#


I am trying to create a timelapse from JPEG images. I've read that the structure of M-JPEG is fairly simple, essentially just concatenated JPEG images that most browsers can play.

var result = new List<byte>();
var converter = new ImageConverter();

foreach (var file in Directory.GetFiles(srcFolder, "*.jpg", SearchOption.TopDirectoryOnly)) {
      using (var image = Image.FromFile(file) as Bitmap) {
          var bytes = converter.ConvertTo(image, typeof(byte[])) as byte[];
          result.AddRange(bytes);
          image.Dispose();
      }
}

File.WriteAllBytes($"{destFolder}video.mjpeg", result.ToArray());

However, it does not work. The resulting video cannot be played by any browser. It can be played in VLC, showing the correct first image, but then does not change to any proceeding image in its ten second duration.

Can someone say what I'm doing wrong? Also, is it possible to adjust the frame rate via headers?

Update: Thanks to the suggestions, I got it working properly in VLC. Still does not play in browsers, but it is at least step in the right direction.

var result = new List<byte>();
var converter = new ImageConverter();

var header = "HTTP/1.1 200 OK\r\n" +
             "Content-Type: multipart/x-mixed-replace; boundary=" +
             "--boundary" +
             "\r\n";
result.AddRange(Encoding.ASCII.GetBytes(header));

foreach (var file in Directory.GetFiles(srcFolder, "*.jpg", SearchOption.TopDirectoryOnly)) {
    using (var image = Image.FromFile(file) as Bitmap) {
        var bytes = converter.ConvertTo(image, typeof(byte[])) as byte[];

        StringBuilder sb = new StringBuilder();

        sb.AppendLine();
        sb.AppendLine("--boundary");
        sb.AppendLine("Content-Type: image/jpeg");
        sb.AppendLine("Content-Length: " + image.Size.ToString());
        sb.AppendLine();
        result.AddRange(Encoding.ASCII.GetBytes(sb.ToString()));
        result.AddRange(bytes);
        result.AddRange(Encoding.ASCII.GetBytes("\r\n"));
        image.Dispose();
    }
}

File.WriteAllBytes($"{destFolder}hat.mjpeg", result.ToArray());

Solution

  • Checking Google, found this:

    https://www.codeproject.com/Articles/371955/Motion-JPEG-Streaming-Server

    This article is about streaming, but I believe it may help you with your project. There is a downloadable code example.