SALES: 1-800-867-1380

Creating a Thumbnail for a Video

Updated: June 3, 2014

In Media Services, one of the common processing tasks is generating thumbnail image files from a video file.

Currently, Media Services does not support creating a thumbnail for an asset that was created as a part of a live streaming workflow.

You have an option of creating a custom XML configuration file to customize the settings (for example, the size of the image and the position of timeline) and use it when creating a task:

  1. Create a file named MediaEncoder_Thumbnails.xml on your local computer and paste the following code in the file.

    <?xml version="1.0" encoding="utf-8"?>
    <Thumbnail Size="100%,*" Type="Jpeg" Filename="{OriginalFilename}_{Size}_{ThumbnailTime}_{ThumbnailIndex}_{Date}_{Time}.{DefaultExtension}">
            <Time Value="10%" Step="10%" Stop="95%"/>
  2. Reference this file as a configuration preset when you create Media Services tasks to generate thumbnail images by using Media Encoder.

    string configuration = File.ReadAllText(Path.GetFullPath(configFilePath + @"\MediaEncoder_Thumbnails.xml")); ;
    ITask task = job.Tasks.AddNew("My thumbnail task",

Alternatively, you can use the Thumbnails preset provided by Media Services, as shown in the following example:

ITask task = job.Tasks.AddNew("My thumbnail task",

It is recommended to create a custom XML configuration.

For more information, see the Task Preset for Thumbnail Generation topic.

The following example shows how to create thumbnail images from a video file using a custom preset defined in the MediaEncoder_Thumbnails.xml file.

Make sure to update the _singleMP4File and _configurationXMLFiles variables to point to the folders where your input MP4 and MediaEncoder_Thumbnails.xml files are located.

For information on how to access or download the generated files, see Delivering Assets with the Media Services SDK for .NET.

using Microsoft.WindowsAzure.MediaServices.Client;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CreatingThumbnail
    class Program
        // Paths to support files (within the above base path). You can use 
        // the provided sample media files from the "SupportFiles" folder, or 
        // provide paths to your own media files below to run these samples.

        private static readonly string _mediaFiles =

        private static readonly string _singleMP4File =
            Path.Combine(_mediaFiles, @"SingleMP4\BigBuckBunny.mp4");

        // XML Configruation files path.
        private static readonly string _configurationXMLFiles = @"../..\Configurations\";

        private static MediaServicesCredentials _cachedCredentials = null;
        private static CloudMediaContext _context = null;

        // Media Services account information.
        private static readonly string _mediaServicesAccountName =
        private static readonly string _mediaServicesAccountKey =

        static void Main(string[] args)
            // Create and cache the Media Services credentials in a static class variable.
            _cachedCredentials = new MediaServicesCredentials(
            // Used the chached credentials to create CloudMediaContext.
            _context = new CloudMediaContext(_cachedCredentials);
            IAsset asset = CreateAssetAndUploadSingleFile(AssetCreationOptions.None, _singleMP4File);
            IAsset thumbnailAsset = CreateThumbnails(asset);

            // Get the SAS locator from where the thumbnail could be downloaded.
            IAccessPolicy accessPolicy = _context.AccessPolicies.Create("File Download Policy",
                                TimeSpan.FromDays(30), AccessPermissions.Read);

            ILocator locator = _context.Locators.CreateLocator(LocatorType.Sas, thumbnailAsset, accessPolicy);

            var jpgFiles = thumbnailAsset.AssetFiles.ToList().
               Where(f => f.Name.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase));

            // As a result, a set of thumbnails at 10%, 20%, …, 90% along 
            // the source timeline were generated.
            foreach (var jpg in jpgFiles)
                UriBuilder ub = new UriBuilder(locator.Path);
                ub.Path += "/" + jpg.Name;

        static public IAsset CreateAssetAndUploadSingleFile(AssetCreationOptions assetCreationOptions, string singleFilePath)
            var assetName = "UploadSingleFile_" + DateTime.UtcNow.ToString();
            var asset = _context.Assets.Create(assetName, assetCreationOptions);
            var fileName = Path.GetFileName(singleFilePath);
            var assetFile = asset.AssetFiles.Create(fileName);

            Console.WriteLine("Created assetFile {0}", assetFile.Name);
            Console.WriteLine("Upload {0}", assetFile.Name);

            Console.WriteLine("Done uploading of {0}", assetFile.Name);

            return asset;


        public static IAsset CreateThumbnails(IAsset asset)
            // Declare a new job.
            IJob job = _context.Jobs.Create("My Thumbnail job");
            // Get a media processor reference, and pass to it the name of the 
            // processor to use for the specific task.
            IMediaProcessor processor = GetLatestMediaProcessorByName("Azure Media Encoder");

            string configThumbnails = File.ReadAllText(Path.Combine(_configurationXMLFiles,

            ITask task = job.Tasks.AddNew("My thumbnail task",
            // Specify the input asset to be encoded.
            // Add an output asset to contain the results of the job.
            task.OutputAssets.AddNew("Output asset",

            // Use the following event handler to check job progress.  
            job.StateChanged += new

            // Launch the job.

            // Check job execution and wait for job to finish. 
            Task progressJobTask = job.GetExecutionProgressTask(CancellationToken.None);

            // If job state is Error, the event handling 
            // method for job progress should log errors.  Here we check 
            // for error state and exit if needed.
            if (job.State == JobState.Error)
                throw new Exception("Exiting method due to job error.");

            return job.OutputMediaAssets[0];

        private static void StateChanged(object sender, JobStateChangedEventArgs e)
            Console.WriteLine("Job state changed event:");
            Console.WriteLine("  Previous state: " + e.PreviousState);
            Console.WriteLine("  Current state: " + e.CurrentState);

            switch (e.CurrentState)
                case JobState.Finished:
                    Console.WriteLine("Job is finished.");
                    Console.WriteLine("Please wait while local tasks or downloads complete...");
                case JobState.Canceling:
                case JobState.Queued:
                case JobState.Scheduled:
                case JobState.Processing:
                    Console.WriteLine("Please wait...\n");
                case JobState.Canceled:
                case JobState.Error:
                    // Cast sender as a job.
                    IJob job = (IJob)sender;
                    // Display or log error details as needed.
        private static IMediaProcessor GetLatestMediaProcessorByName(string mediaProcessorName)
            // The possible strings that can be passed into the 
            // method for the mediaProcessor parameter:
            //   Azure Media Encoder
            //   Azure Media Packager
            //   Azure Media Encryptor
            //   Storage Decryption

            var processor = _context.MediaProcessors.Where(p => p.Name == mediaProcessorName).
                ToList().OrderBy(p => new Version(p.Version)).LastOrDefault();

            if (processor == null)
                throw new ArgumentException(string.Format("Unknown media processor", mediaProcessorName));

            return processor;

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
© 2014 Microsoft