Hot questions for Using Azure in azure media services

Top Java Programmings / Azure / azure media services

Question:

When I run Microsoft Azure Media Services code written using Java in local it is working but when I deploy the same code in dev environment , I am unable to access the Azure and its throwing java.net.HostNotFoundException.

What is the best approach to use network proxy to connect to Azure

Below is the code I am using via java and using azure-java-sdk

import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.util.EnumSet;

import com.microsoft.windowsazure.Configuration;
import com.microsoft.windowsazure.exception.ServiceException;
import com.microsoft.windowsazure.services.media.MediaConfiguration;
import com.microsoft.windowsazure.services.media.MediaContract;
import com.microsoft.windowsazure.services.media.MediaService;
import com.microsoft.windowsazure.services.media.WritableBlobContainerContract;
import com.microsoft.windowsazure.services.media.models.AccessPolicy;
import com.microsoft.windowsazure.services.media.models.AccessPolicyInfo;
import com.microsoft.windowsazure.services.media.models.AccessPolicyPermission;
import com.microsoft.windowsazure.services.media.models.Asset;
import com.microsoft.windowsazure.services.media.models.AssetFile;
import com.microsoft.windowsazure.services.media.models.AssetFileInfo;
import com.microsoft.windowsazure.services.media.models.AssetInfo;
import com.microsoft.windowsazure.services.media.models.Job;
import com.microsoft.windowsazure.services.media.models.JobInfo;
import com.microsoft.windowsazure.services.media.models.JobState;
import com.microsoft.windowsazure.services.media.models.ListResult;
import com.microsoft.windowsazure.services.media.models.Locator;
import com.microsoft.windowsazure.services.media.models.LocatorInfo;
import com.microsoft.windowsazure.services.media.models.LocatorType;
import com.microsoft.windowsazure.services.media.models.MediaProcessor;
import com.microsoft.windowsazure.services.media.models.MediaProcessorInfo;
import com.microsoft.windowsazure.services.media.models.Task;


public class HelloMediaServices
{
    // Media Services account credentials configuration
    private static String mediaServiceUri = "https://media.windows.net/API/";
    private static String oAuthUri = "https://wamsprodglobal001acs.accesscontrol.windows.net/v2/OAuth2-13";
    private static String clientId = "account name";
    private static String clientSecret = "account key";
    private static String scope = "urn:WindowsAzureMediaServices";
    private static MediaContract mediaService;

    // Encoder configuration
    private static String preferedEncoder = "Media Encoder Standard";
    private static String encodingPreset = "H264 Multiple Bitrate 720p";

    public static void main(String[] args)
    {

        try {
            // Set up the MediaContract object to call into the Media Services account
            Configuration configuration = MediaConfiguration.configureWithOAuthAuthentication(
            mediaServiceUri, oAuthUri, clientId, clientSecret, scope);
            mediaService = MediaService.create(configuration);


            // Upload a local file to an Asset
            AssetInfo uploadAsset = uploadFileAndCreateAsset("BigBuckBunny.mp4");
            System.out.println("Uploaded Asset Id: " + uploadAsset.getId());


            // Transform the Asset
            AssetInfo encodedAsset = encode(uploadAsset);
            System.out.println("Encoded Asset Id: " + encodedAsset.getId());

            // Create the Streaming Origin Locator
            String url = getStreamingOriginLocator(encodedAsset);

            System.out.println("Origin Locator URL: " + url);
            System.out.println("Sample completed!");

        } catch (ServiceException se) {
            System.out.println("ServiceException encountered.");
            System.out.println(se.toString());
        } catch (Exception e) {
            System.out.println("Exception encountered.");
            System.out.println(e.toString());
        }

    }

    private static AssetInfo uploadFileAndCreateAsset(String fileName)
        throws ServiceException, FileNotFoundException, NoSuchAlgorithmException {

        WritableBlobContainerContract uploader;
        AssetInfo resultAsset;
        AccessPolicyInfo uploadAccessPolicy;
        LocatorInfo uploadLocator = null;

        // Create an Asset
        resultAsset = mediaService.create(Asset.create().setName(fileName).setAlternateId("altId"));
        System.out.println("Created Asset " + fileName);

        // Create an AccessPolicy that provides Write access for 15 minutes
        uploadAccessPolicy = mediaService
            .create(AccessPolicy.create("uploadAccessPolicy", 15.0, EnumSet.of(AccessPolicyPermission.WRITE)));

        // Create a Locator using the AccessPolicy and Asset
        uploadLocator = mediaService
            .create(Locator.create(uploadAccessPolicy.getId(), resultAsset.getId(), LocatorType.SAS));

        // Create the Blob Writer using the Locator
        uploader = mediaService.createBlobWriter(uploadLocator);

        File file = new File("BigBuckBunny.mp4"); 

        // The local file that will be uploaded to your Media Services account
        InputStream input = new FileInputStream(file);

        System.out.println("Uploading " + fileName);

        // Upload the local file to the asset
        uploader.createBlockBlob(fileName, input);

        // Inform Media Services about the uploaded files
        mediaService.action(AssetFile.createFileInfos(resultAsset.getId()));
        System.out.println("Uploaded Asset File " + fileName);

        mediaService.delete(Locator.delete(uploadLocator.getId()));
        mediaService.delete(AccessPolicy.delete(uploadAccessPolicy.getId()));

        return resultAsset;
    }

    // Create a Job that contains a Task to transform the Asset
    private static AssetInfo encode(AssetInfo assetToEncode)
        throws ServiceException, InterruptedException {

        // Retrieve the list of Media Processors that match the name
        ListResult<MediaProcessorInfo> mediaProcessors = mediaService
                        .list(MediaProcessor.list().set("$filter", String.format("Name eq '%s'", preferedEncoder)));

        // Use the latest version of the Media Processor
        MediaProcessorInfo mediaProcessor = null;
        for (MediaProcessorInfo info : mediaProcessors) {
            if (null == mediaProcessor || info.getVersion().compareTo(mediaProcessor.getVersion()) > 0) {
                mediaProcessor = info;
            }
        }

        System.out.println("Using Media Processor: " + mediaProcessor.getName() + " " + mediaProcessor.getVersion());

        // Create a task with the specified Media Processor
        String outputAssetName = String.format("%s as %s", assetToEncode.getName(), encodingPreset);
        String taskXml = "<taskBody><inputAsset>JobInputAsset(0)</inputAsset>"
                + "<outputAsset assetCreationOptions=\"0\"" // AssetCreationOptions.None
                + " assetName=\"" + outputAssetName + "\">JobOutputAsset(0)</outputAsset></taskBody>";

        Task.CreateBatchOperation task = Task.create(mediaProcessor.getId(), taskXml)
                .setConfiguration(encodingPreset).setName("Encoding");

        // Create the Job; this automatically schedules and runs it.
        Job.Creator jobCreator = Job.create()
                .setName(String.format("Encoding %s to %s", assetToEncode.getName(), encodingPreset))
                .addInputMediaAsset(assetToEncode.getId()).setPriority(2).addTaskCreator(task);
        JobInfo job = mediaService.create(jobCreator);

        String jobId = job.getId();
        System.out.println("Created Job with Id: " + jobId);

        // Check to see if the Job has completed
        checkJobStatus(jobId);
        // Done with the Job

        // Retrieve the output Asset
        ListResult<AssetInfo> outputAssets = mediaService.list(Asset.list(job.getOutputAssetsLink()));
        return outputAssets.get(0);
    }


    public static String getStreamingOriginLocator(AssetInfo asset) throws ServiceException {
        // Get the .ISM AssetFile
        ListResult<AssetFileInfo> assetFiles = mediaService.list(AssetFile.list(asset.getAssetFilesLink()));
        AssetFileInfo streamingAssetFile = null;
        for (AssetFileInfo file : assetFiles) {
            if (file.getName().toLowerCase().endsWith(".ism")) {
                streamingAssetFile = file;
                break;
            }
        }

        AccessPolicyInfo originAccessPolicy;
        LocatorInfo originLocator = null;

        // Create a 30-day readonly AccessPolicy
        double durationInMinutes = 60 * 24 * 30;
        originAccessPolicy = mediaService.create(
                AccessPolicy.create("Streaming policy", durationInMinutes, EnumSet.of(AccessPolicyPermission.READ)));

        // Create a Locator using the AccessPolicy and Asset
        originLocator = mediaService
                .create(Locator.create(originAccessPolicy.getId(), asset.getId(), LocatorType.OnDemandOrigin));

        // Create a Smooth Streaming base URL
        return originLocator.getPath() + streamingAssetFile.getName() + "/manifest";
    }

    private static void checkJobStatus(String jobId) throws InterruptedException, ServiceException {
        boolean done = false;
        JobState jobState = null;
        while (!done) {
            // Sleep for 5 seconds
            Thread.sleep(5000);

            // Query the updated Job state
            jobState = mediaService.get(Job.get(jobId)).getState();
            System.out.println("Job state: " + jobState);

            if (jobState == JobState.Finished || jobState == JobState.Canceled || jobState == JobState.Error) {
                done = true;
            }
        }
    }

}

Answer:

For others who face issue like me we can connect to azure mediaservices using network proxy by using below code

 // Set up the MediaContract object to call into the Media Services account
  Configuration configuration = MediaConfiguration.configureWithOAuthAuthentication(
                    mediaServiceUri, oAuthUri, clientId, clientSecret, scope);
  configuration.getProperties().put(Configuration.PROPERTY_HTTP_PROXY_HOST, "Hostvalue");
  configuration.getProperties().put(Configuration.PROPERTY_HTTP_PROXY_PORT, "Portvalue");
  configuration.getProperties().put(Configuration.PROPERTY_HTTP_PROXY_SCHEME, "http");
  MediaContract mediaService = MediaService.create(configuration);

Now use the mediaService to perform other operations.

Question:

The Windows Azure documentation provides a task preset to create thumbnails and sample code in C#: https://msdn.microsoft.com/en-us/library/azure/hh973624.aspx

I am trying to do this using the java SDK http://azure.microsoft.com/en-us/develop/java/ and getting an error 400 from the server.

The relevant excerpt from my code is:

JobInfo jobInfo = mediaService
            .create(Job
                    .create()
                    .setName(
                            "Encoding " + assetToEncode.getName() + " to "
                                    + encodingPreset
                                    + " and Packaging to HLS")
                    .addInputMediaAsset(assetToEncode.getId())
                    // Thumbnails see
                    // https://msdn.microsoft.com/en-us/library/azure/hh973624.aspx
                     .addTaskCreator(
                     Task.create(
                     mediaProcessor.getId(),
                     "<?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%\"/>" +
                     "</Thumbnail>").setConfiguration( "Thumbnails")
                     .setOptions(
                     TaskOption.ProtectedConfiguration).setName(
                     "Thumbnails"))

Does anyone have a working example using this task with java?


Answer:

Short Answer:

This answer is for azure-media maven package versions 0.6.0 to 0.8.x

You should use the usual XML on create method and set the thumbnail XML via setConfiguration like this example:

// Create the Thumbnail task
String xmlThumbnail = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + 
       "<Thumbnail Size=\"" + size + "\" Type=\"Jpeg\" " + 
       "Filename=\"{OriginalFilename}_{Size}_{ThumbnailTime}_{ThumbnailIndex}_{Date}_{Time}.{DefaultExtension}\">" + 
       "<Time Value=\"" + time + "\"/></Thumbnail>";

Task.CreateBatchOperation task = Task
            .create(mediaProcessor.getId(), 
                    "<taskBody><inputAsset>JobInputAsset(0)</inputAsset><outputAsset>JobOutputAsset(0)</outputAsset></taskBody>")
            .setConfiguration(xmlThumbnail)
            .setName("MakeThumbnailTask");
Complete Example:

Usage:

MakeThumbnail(mediaService, "50%,*", "10%"); 

Code:

private void MakeThumbnail(MediaContract mediaService, String size, String time) throws ServiceException, InterruptedException, MalformedURLException {

        // Use the Azure Media Encoder, by specifying it by name.
        ListResult<MediaProcessorInfo> mediaProcessors = mediaService
                .list(MediaProcessor.list().set("$filter", "Name eq 'Azure Media Encoder'"));

        // Use the latest version of the media processor.
        MediaProcessorInfo mediaProcessor = null;
        for (MediaProcessorInfo info : mediaProcessors) {
            if (null == mediaProcessor || info.getVersion().compareTo(mediaProcessor.getVersion()) > 0) {
                mediaProcessor = info;
            }
        }

        // Create the Thumbnail task
        String xmlThumbnail = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + 
           "<Thumbnail Size=\"" + size + "\" Type=\"Jpeg\" " + 
           "Filename=\"{OriginalFilename}_{Size}_{ThumbnailTime}_{ThumbnailIndex}_{Date}_{Time}.{DefaultExtension}\">" + 
           "<Time Value=\"" + time + "\"/></Thumbnail>";

        Task.CreateBatchOperation task = Task
                .create(mediaProcessor.getId(), 
                        "<taskBody><inputAsset>JobInputAsset(0)</inputAsset><outputAsset>JobOutputAsset(0)</outputAsset></taskBody>")
                .setConfiguration(xmlThumbnail)
                .setName("MakeThumbnailTask");

        // Create a job creator that specifies the asset, priority and task for the job.
        Job.Creator jobCreator = Job.create().setName("MakeThumbnailTask").addInputMediaAsset("nb:cid:UUID:ec25435d-1500-80c3-dd89-f1e528b02207").setPriority(2)
                .addTaskCreator(task);

        JobInfo jobInfo = mediaService.create(jobCreator);
        String jobId = jobInfo.getId();

        // Check to see if the job has completed.
        CheckJobStatus(jobId);
        // Done with the job.

        // Retrieve the output asset.
        ListResult<AssetInfo> outputAssets = mediaService.list(Asset.list(jobInfo.getOutputAssetsLink()));
        AssetInfo thumbnailAsset = outputAssets.get(0);

        AccessPolicyInfo downloadAccessPolicy = null;
        double t100years = 100.0 * 365.0 * 24.0 * 60.0;
        downloadAccessPolicy = mediaService
                .create(AccessPolicy.create("Public Thumbnail Policy", t100years, EnumSet.of(AccessPolicyPermission.READ)));

        LocatorInfo downloadLocator = null;
        downloadLocator = mediaService
                .create(Locator.create(downloadAccessPolicy.getId(), thumbnailAsset.getId(), LocatorType.SAS));

        // Lookup the output asset file
        ListResult<AssetFileInfo> assetFiles = mediaService.list(AssetFile.list(thumbnailAsset.getAssetFilesLink()));
        AssetFileInfo jpegFile = null;
        for (AssetFileInfo outputAssetFile : assetFiles) {
            // check if primary output.
            if (outputAssetFile.getIsPrimary())  {
                jpegFile = outputAssetFile;
            }
        }

        // Adding the file name to the URL
        String imageUrl = downloadLocator.getPath().replaceAll("\\?", "/" + jpegFile.getName() + "?");

        System.out.println("Created Thumbnail JPEG URL: " + imageUrl);

 }

Question:

getting one thumbnail works well, but to get series of thumbnails,the exception occured. code like this:

  String taskXml = new StringBuilder(StringUtils.EMPTY)//
            .append("<taskBody>")//
            .append(" <inputAsset>JobInputAsset(0)</inputAsset>")//
            .append(" <outputAsset assetCreationOptions=\"0\" assetName=\"" + outputAssetName
                    + "\">JobOutputAsset(0)</outputAsset>")//
            .append("</taskBody>").toString();//

    String preset = new StringBuilder(StringUtils.EMPTY)//
            .append("<Preset xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" Version=\"1.0\" xmlns=\"http://www.windowsazure.com/media/encoding/Preset/2014/03\">")
            .append("<Encoding>")//
            .append(" <PngImage Start=\"{Best}\">") //  get one thumbnail 
            // .append(" <PngImage Start=\"5%\" Step=\"10%\" Range=\"96%\">") //  get series of  thumbnails
            .append("       <PngLayers>")//
            .append("           <PngLayer>")//
            .append("               <Width>100%</Width>")//
            .append("               <Height>100%</Height>")//
            .append("           </PngLayer>")//
            .append("       </PngLayers>")//
            .append("   </PngImage>")//
            .append("</Encoding>")//
            .append("<Outputs>")//
            .append("  <Output FileName=\"{Basename}_{Index}{Extension}\">")//
            .append("       <PngFormat />")//
            .append("   </Output>")//
            .append("</Outputs>")//
            .append("</Preset>")//
            .toString();
    Task.CreateBatchOperation task =
            Task.create(mediaProcessorInfo.getId(), taskXml).setConfiguration(preset).setName("Thumbnails");

"<PngImage Start=\"{Best}\">" works well,and "<PngImage Start=\"5%\" Step=\"10%\" Range=\"96%\">" exception happened("An error has occurred. Stage: ApplyEncodeCommand. Code: 0x00000001.").

by the way,can I get series of thumbnails with the same pic just different size ?


Answer:

I didn't reproduce your exception An error has occurred. Stage: ApplyEncodeCommand. Code: 0x00000001. when I tried to get thumbnail with the code from here and encoding code you offered.

public static void test(AssetInfo assetToEncode) throws ServiceException, InterruptedException {

        String preset = new StringBuilder(StringUtils.EMPTY)//
                .append("<Preset xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" Version=\"1.0\" xmlns=\"http://www.windowsazure.com/media/encoding/Preset/2014/03\">")
                .append("<Encoding>")//
//              .append(" <PngImage Start=\"{Best}\">") // get one thumbnail
                 .append(" <PngImage Start=\"5%\" Step=\"10%\" Range=\"96%\">") // get series of thumbnails
                .append("       <PngLayers>")//
                .append("           <PngLayer>")//
                .append("               <Width>100%</Width>")//
                .append("               <Height>100%</Height>")//
                .append("           </PngLayer>")//
                .append("       </PngLayers>")//
                .append("   </PngImage>")//
                .append("</Encoding>")//
                .append("<Outputs>")//
                .append("  <Output FileName=\"{Basename}_{Index}{Extension}\">")//
                .append("       <PngFormat />")//
                .append("   </Output>")//
                .append("</Outputs>")//
                .append("</Preset>")//
                .toString();

        // Retrieve the list of Media Processors that match the name
        ListResult<MediaProcessorInfo> mediaProcessors = mediaService
                .list(MediaProcessor.list().set("$filter", String.format("Name eq '%s'", preferedEncoder)));

        // Use the latest version of the Media Processor
        MediaProcessorInfo mediaProcessor = null;
        for (MediaProcessorInfo info : mediaProcessors) {
            if (null == mediaProcessor || info.getVersion().compareTo(mediaProcessor.getVersion()) > 0) {
                mediaProcessor = info;
            }
        }

        System.out.println("Using Media Processor: " + mediaProcessor.getName() + " " + mediaProcessor.getVersion());


        // Create a task with the specified Media Processor
        String outputAssetName = String.format("%s as %s", assetToEncode.getName(), preset);

        String taskXml = new StringBuilder(StringUtils.EMPTY)//
                .append("<taskBody>")//
                .append(" <inputAsset>JobInputAsset(0)</inputAsset>")//
                .append(" <outputAsset assetCreationOptions=\"0\" assetName=\"" + outputAssetName
                        + "\">JobOutputAsset(0)</outputAsset>")//
                .append("</taskBody>").toString();//


        Task.CreateBatchOperation task = Task.create(mediaProcessor.getId(), taskXml).setConfiguration(preset)
                .setName("Thumbnails");

        // Create the Job; this automatically schedules and runs it.
        Job.Creator jobCreator = Job.create()
                .setName(String.format("Encoding %s to %s", assetToEncode.getName(), preset))
                .addInputMediaAsset(assetToEncode.getId()).setPriority(2).addTaskCreator(task);
        JobInfo job = mediaService.create(jobCreator);

        String jobId = job.getId();
        System.out.println("Created Job with Id: " + jobId);

        // Check to see if the Job has completed
        checkJobStatus(jobId);
    }

It's great you hava already resolved the issue. It turned out to be an unormal video file.

Thanks for your share.

Question:

I am trying to create an Asset on Azure Media Services using REST API from Android. I am following this documentation and this is my code to connect with AMS endpoint from Android,

urlConnection = (HttpURLConnection) this._url.openConnection();
    urlConnection.setRequestProperty("Content-Type", String.valueOf("application/json"));
    urlConnection.setRequestProperty("DataServiceVersion", String.valueOf("1.0;NetFx"));
    urlConnection.setRequestProperty("MaxDataServiceVersion", String.valueOf("3.0;NetFx"));
    urlConnection.setRequestProperty("Accept", String.valueOf("application/json"));
    urlConnection.setRequestProperty("Accept-Charset", String.valueOf("UTF-8"));
    urlConnection.setRequestProperty("Authorization", String.format(Locale.ENGLISH, "Bearer %s", _token));
    urlConnection.setRequestProperty("x-ms-version", String.valueOf(2.11));
    urlConnection.setRequestProperty("x-ms-client-request-id", UUID.randomUUID().toString());
    urlConnection.setRequestProperty("Host", this._host);
    urlConnection.setRequestProperty("Content-Length", String.valueOf(this._postData.length));
    urlConnection.setRequestProperty("Expect", String.valueOf("100-continue"));

    urlConnection.setConnectTimeout(CONNECTION_TIME_OUT);
    urlConnection.setReadTimeout(CONNECTION_READ_TIME_OUT);
    urlConnection.setInstanceFollowRedirects(true);
    urlConnection.setRequestMethod("POST");
    urlConnection.setUseCaches(false);
    urlConnection.setDoOutput(true);
    urlConnection.setDoInput(true);

    OutputStream wr= urlConnection.getOutputStream();
    wr.write(_postData);
    wr.flush();
    wr.close();

And my _postData variable is byte array which I am converting from json,

_fileName = _fileName.replace(" ", "-");

    JSONObject jo = new JSONObject();
    jo.put("Name", _fileName+".mp4");
    jo.put("Options", String.valueOf(0));

    this._postData = jo.toString().getBytes("UTF-8");

I have tried using Google Chrome's REST api client extension to check the post request and It works fine. I got the response I was expecting from chrome's REST api client extension but using Android, I am not getting the same response. I am getting this response from this code which is the step I have already performed before running this code. I have used both endpoints https://media.windows.net/ and https://wamsbayclus001rest-hs.cloudapp.net/ but it is not working from Android. I believe that Android is changing Headers or something is wrong with headers that AMS not parsing properly. Can anyone guide me how to achieve this using Android HttpUrlConnection?

Thanks.


Answer:

I fixed it by changing OutputStream to DataOutputStream

DataOutputStream wrr = new DataOutputStream(urlConnection.getOutputStream());
        wrr.write(this._postData);
        wrr.flush();
        wrr.close();

and changed my json array to string,

String s = "{\"Name\":\"" + _fileName + ".mp4\", \"Options\":\"0\"}";

and it worked fine.