5
\$\begingroup\$

I wrote a simple, yet disgusting video thumbnail image generator method—which uses the MediaToolkit .NET library.

The code is not self-explanatory whatsoever, and it's extremely inefficient.

It accepts a video byte array & MIME type—and writes it to a video file. Then, it obtains the video file's duration, stores the middle frame, and writes it to an image file. Finally, it retrieves the image file bytes and returns them ... after deleting the video & image file.

How can I make it more efficient?

    public static byte[] GetVideoThumbnail(byte[] bytes, string mediaType)
    {
        var video = new MediaFile
        {
            Filename = Path.GetTempPath() + Guid.NewGuid() + MimeTypeMap.GetExtension(mediaType)
        };
        var image = new MediaFile { Filename = Path.GetTempPath() + Guid.NewGuid() + ".jpg" };
        File.WriteAllBytes(video.Filename, bytes);
        using (var engine = new Engine())
        {
            engine.GetMetadata(video);
            engine.GetThumbnail(video, image,
                new ConversionOptions { Seek = TimeSpan.FromSeconds(video.Metadata.Duration.TotalSeconds / 2) });
        }
        var thumbnail = File.ReadAllBytes(image.Filename);
        File.Delete(video.Filename);
        File.Delete(image.Filename);
        return thumbnail;
    }
\$\endgroup\$
9
  • 1
    \$\begingroup\$ Have you read answers in this SO post ? stackoverflow.com/questions/15702031/… especially answer withFFMpeg usage ? Problems and inefficient of your code is caused by MediaToolkit. \$\endgroup\$ Oct 9, 2017 at 10:44
  • \$\begingroup\$ @AramKocharyan FFmpeg is even more inefficient for doing this than MediaToolkit is. \$\endgroup\$
    – Owen
    Oct 12, 2017 at 1:23
  • \$\begingroup\$ What is inefficient here ? nrecosite.com/video_converter_net.aspx \$\endgroup\$ Oct 12, 2017 at 10:31
  • \$\begingroup\$ Have you tried to use asynchronous operations? I have no experience whatsoever with MediaToolkit, but from what I can see you can run var image = new MediaFile { Filename = Path.GetTempPath() + Guid.NewGuid() + ".jpg" };, File.WriteAllBytes(video.Filename, bytes); and other read/write/delete operations in new threads. \$\endgroup\$ Oct 12, 2017 at 15:49
  • \$\begingroup\$ @AramKocharyan I'll look into NReco right now. I found it last week and dismissed it. \$\endgroup\$
    – Owen
    Oct 12, 2017 at 16:03

1 Answer 1

3
\$\begingroup\$

The most inefficient thing in your code is usage of byte[] to hold video or image data. There is a concept of Large Object Heap in .NET which is not compacted unless explicitly otherwise made-to starting .Net 4.5.1.

Red Gate's Explanation of Large Object Heap

Latest behavior of Large Object Heap

All your objects with a size of more that 85000 bytes are allocated on large object heap. These are not collected like mentioned in .Net garbage collection and dealt with separately. You can read better in the links above.

As a sidenote, You can cross-check if you do need engine.GetMetadata(video); to generate the thumbnail.

The answer to your question would be

  1. Like you are returning image as a byte array, you can choose to return a image url from the disk. Some part of byte array will be reduced.

  2. With .net 4.5.1, you can call .net LOH compaction programmatically.

  3. You can also do this processing in completely separate appdomain in memory, and then unloading it.

  4. Or you can generate thumbnails from a completely separate windows service or console application, you simply restart them.

Read few more things on Large Object Heap

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.