Questions? Feedback? powered by Olark live chat software
Přeskočit navigaci

Announcing Hyperlapse for Azure Media Services

Publikováno dne 14 května, 2015

Program Manager, Azure Media Services

  Over the past five years, the introduction of drone cameras and action cameras have massively disrupted the landscape of video capture devices.  Increasingly smaller lenses and camera hardware, in conjunction with the rise of social media and multimedia sharing opened the door for amateur videographers everywhere.  Now, one can affordably take high framerate and field-of-view footage of their action sports, as well to take their cameras to the skies and capture previously impossible shots to immediately share with the world. With this technology, however, came new challenges.  For example, as a news organization with a fleet of drones covering a major event, how does one properly condense the long, sometimes boring catalog of slow-moving video into something usable and exciting?  When recording a 15 minute downhill mountain bike ride, how does one create a consumable and sharable version of the footage? These past few months we have been working closely with our peers in Microsoft Research to answer this problem by bringing Microsoft Hyperlapse to the cloud on Azure Media Services.  Today marks the beginning of our free public preview of Hyperlapse for Azure Media Services! This release is in conjunction with  Hyperlapse Mobile and Hyperlapse Pro, and is focused on offering Microsoft Hyperlapse as a service to developers and media companies.  Microsoft Hyperlapse is now available in all public Azure Datacenters!  

What is Microsoft Hyperlapse?

Microsoft Hyperlapse is a result of over 20 years of computer vision research at MSR, combining video stabilization and time lapsing to create quick, consumable, beautiful videos from your long-form content. Want to share helmet-cam footage of a snowboarding run?  Use Microsoft Hyperlapse to smooth out the bumps with video stabilization and speed up your content into a consumable clip, without losing any of the action!  Microsoft Hyperlapse gives your content the polished feel of a professionally-recorded run with specialized stabilization hardware/cameras. Take a look at the following videos (in Azure Media Player) demonstrating the smooth experience you can expect from Microsoft Hyperlapse.  

  Microsoft Hyperlapse generates smooth timelapses. In particular pay attention to the trees in the normal time lapse in comparison with those in the Hyperlapse video.  Traditional time lapse technology accentuates the jerks and bumps of amateur videography, but with Hyperlapse we can process away the motion into the smooth end result you see here. Hyperlapse for Azure Media Services is the integration of Microsoft Hyperlapse technology into a media processor on Azure Media Services.  We invite you all to take advantage of the synergy between this incredible technology and the ultrascale and global presence of the Azure cloud by trying out Hyperlapse today! With Azure Media Services, you can schedule scalable batch processing of your Hyperlapse tasks, parallelizing as many jobs as you need by virtually scaling up your hardware!  

Free Public Preview

For the purposes of this public preview offering, we are offering Microsoft Hyperlapse to all Azure Media Services accounts for free!

Note: We will be limiting hyperlapse jobs to 10,000 frames of video during preview.

Getting Started

Easily integrate Hyperlapse technology into your web or app offering using our REST API/SDKs or with Azure Media Services Explorer, today! The following is a sample C# program and configuration XML that will get you started with your first Hyperlapse job.  This code requires both the Azure Media Services C# SDK and SDK Extensions packages (available on NuGet).  

Sample Program

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.WindowsAzure.MediaServices.Client;
using System.Configuration;
using System.IO;
using System.Threading;


namespace MyFirstHyperlapseJob
{
    class Program
    {
        
        // declare constants and globals
        private static CloudMediaContext _context = null;
        private static readonly string _accountName = {ACCOUNT_NAME};
        private static readonly string _accountKey = {ACCOUNT_KEY};

        private const string _mpName = "Azure Media Hyperlapse";
        private static readonly string _inputFile = {INPUT_FILE_PATH};	
	private static readonly string _outputFolder = {OUTPUT_FOLDER_PATH};
        private const string _hyperlapseConfiguration = {PATH_TO_CONFIG};

        static void Main(string[] args)
        {
            _context = new CloudMediaContext(_accountName, _accountKey);
            RunHyperlapseJob(_inputFile, _outputFolder, _hyperlapseConfiguration);
        }

        static void RunHyperlapseJob(string input, string output, string hyperConfig)
        {
            // create asset with input file
            IAsset asset = _context
                           .Assets
                           .CreateFromFile(input, AssetCreationOptions.None);

            // grab instance of Azure Media Hyperlapse MP
            IMediaProcessor mp = _context
                                 .MediaProcessors
                                 .GetLatestMediaProcessorByName(_mpName);

            // create Job with hyperlapse task
            IJob job = _context
                       .Jobs
                       .Create(String.Format("Hyperlapse {0}", input));

            if (!String.IsNullOrEmpty(hyperConfig))
            {
                hyperConfig = File.ReadAllText(hyperConfig);
            }
            ITask hyperlapseTask = job.Tasks.AddNew("Hyperlapse task", 
                                                    mp,
                                                    hyperConfig, 
                                                    TaskOptions.None);
            hyperlapseTask.InputAssets.Add(asset);
            hyperlapseTask.OutputAssets.AddNew("Hyperlapse output", 
                                                AssetCreationOptions.None);


            job.Submit();

            // Create progress printing and querying tasks
                Task progressPrintTask = new Task(() =>
                {

                    IJob jobQuery = null;
                    do
                    {
                        var progressContext = _context;
                        jobQuery = progressContext.Jobs
                                                  .Where(j => j.Id == job.Id)
                                                  .First();
                        Console.WriteLine(string.Format("{0}\t{1}\t{2}", 
                                          DateTime.Now, 
                                          jobQuery.State, 
                                          jobQuery.Tasks[0].Progress));
                        Thread.Sleep(10000);
                    }
                    while (jobQuery.State != JobState.Finished &&
                           jobQuery.State != JobState.Error &&
                           jobQuery.State != JobState.Canceled);
                });
                progressPrintTask.Start();

                Task progressJobTask = job.GetExecutionProgressTask(
                                                     CancellationToken.None);
                progressJobTask.Wait();

                // 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)
                {
                    ErrorDetail error = job.Tasks.First().ErrorDetails.First();
                    Console.WriteLine(string.Format("Error: {0}. {1}", 
                                                    error.Code, 
                                                    error.Message));                    
                }

            DownloadAsset(job.OutputMediaAssets.First(), output);
        }

        static void DownloadAsset(IAsset asset, string outputDirectory)
        {
            foreach (IAssetFile file in asset.AssetFiles)
            {
                file.Download(Path.Combine(outputDirectory, file.Name));
            }
        }

        // event handler for Job State
        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();
                    Console.WriteLine("Job finished.");
                    break;
                case JobState.Canceling:
                case JobState.Queued:
                case JobState.Scheduled:
                case JobState.Processing:
                    Console.WriteLine("Please wait...\n");
                    break;
                case JobState.Canceled:
                    Console.WriteLine("Job is canceled.\n");
                    break;
                case JobState.Error:
                    Console.WriteLine("Job failed.\n");
                    break;
                default:
                    break;
            }
        }
    }
}

 

Configuration XML

<?xml version="1.0" encoding="utf-16"?>
<Preset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.0" xmlns="http://www.windowsazure.com/media/encoding/Preset/2014/03">
  <Sources>
    <Source StartFrame="0" NumFrames="10000">
      <InputFiles />
    </Source>
  </Sources>
  <Options>
    <Speed>8</Speed>
  </Options>
</Preset>

  Have any questions or comments?  Need help getting started?  Send an email to amshyperlapse@microsoft.com.