/// <summary> /// Run the sample async. /// </summary> /// <param name="config">This param is of type ConfigWrapper, which reads values from local configuration file.</param> /// <returns>A task.</returns> private static async Task RunAsync(ConfigWrapper config) { IAzureMediaServicesClient client; try { client = await CreateMediaServicesClientAsync(config); } catch (Exception e) { Console.Error.WriteLine("TIP: Make sure that you have filled out the appsettings.json file before running this sample."); Console.Error.WriteLine($"{e.Message}"); return; } // Set the polling interval for long running operations to 2 seconds. // The default value is 30 seconds for the .NET client SDK client.LongRunningOperationRetryTimeout = 2; // Creating a unique suffix so that we don't have name collisions if you run the sample // multiple times without cleaning up. string uniqueness = Guid.NewGuid().ToString().Substring(0, 13); string jobName = "job-" + uniqueness; string locatorName = "locator-" + uniqueness; string outputAssetName = "output-" + uniqueness; string assetFilterName = "assetFilter-" + uniqueness; string accountFilterName = "accountFilter-" + uniqueness; string inputAssetName = "input-" + uniqueness; bool stopEndpoint = false; try { // Ensure that you have customized encoding Transform. This is really a one time setup operation. Transform adaptiveEncodeTransform = await GetOrCreateTransformAsync(client, config.ResourceGroup, config.AccountName, adaptiveTransformName); // Create a new input Asset and upload the specified local video file into it. Asset inputAsset = await CreateInputAssetAndUploadVideoAsync(client, config.ResourceGroup, config.AccountName, inputAssetName, InputMP4FileName); // Output from the encoding Job must be written to an Asset, so let's create one. Asset outputAsset = await CreateOutputAssetAsync(client, config.ResourceGroup, config.AccountName, outputAssetName); Console.WriteLine("Creating a job..."); Job job = await SubmitJobAsync(client, config.ResourceGroup, config.AccountName, adaptiveTransformName, jobName, inputAssetName, outputAsset.Name); DateTime startedTime = DateTime.Now; // In this demo code, we will poll for Job status. Polling is not a recommended best practice for production // applications because of the latency it introduces. Overuse of this API may trigger throttling. Developers // should instead use Event Grid. To see how to implement the event grid, see the sample // https://github.com/Azure-Samples/media-services-v3-dotnet/tree/master/ContentProtection/BasicAESClearKey. job = WaitForJobToFinish(client, config.ResourceGroup, config.AccountName, adaptiveTransformName, jobName); TimeSpan elapsed = DateTime.Now - startedTime; Console.WriteLine($"Job elapsed time: {elapsed}"); if (job.State == JobState.Finished) { Console.WriteLine("Job finished."); // Now that the content has been encoded, publish it for Streaming by creating // a StreamingLocator. StreamingLocator locator = await client.StreamingLocators.CreateAsync( config.ResourceGroup, config.AccountName, locatorName, new StreamingLocator { AssetName = outputAsset.Name, StreamingPolicyName = PredefinedStreamingPolicy.ClearStreamingOnly }); StreamingEndpoint streamingEndpoint = await client.StreamingEndpoints.GetAsync(config.ResourceGroup, config.AccountName, DefaultStreamingEndpointName); if (streamingEndpoint != null) { if (streamingEndpoint.ResourceState != StreamingEndpointResourceState.Running) { Console.WriteLine("Streaming Endpoint was Stopped, restarting now.."); await client.StreamingEndpoints.StartAsync(config.ResourceGroup, config.AccountName, DefaultStreamingEndpointName); // Since we started the endpoint, we should stop it in cleanup. stopEndpoint = true; } } IList <string> urls = await GetDashStreamingUrlsAsync(client, config.ResourceGroup, config.AccountName, locator.Name, streamingEndpoint); Console.WriteLine("Creating an asset filter..."); Console.WriteLine(); AssetFilter assetFilter = await CreateAssetFilterAsync(client, config.ResourceGroup, config.AccountName, outputAsset.Name, assetFilterName); Console.WriteLine("Creating an account filter..."); Console.WriteLine(); AccountFilter accountFilter = await CreateAccountFilterAsync(client, config.ResourceGroup, config.AccountName, accountFilterName); Console.WriteLine("We are going to use two different ways to show how to filter content. First, we will append the filters to the url(s)."); Console.WriteLine("Url(s) with filters:"); foreach (var url in urls) { if (url.EndsWith(")")) { Console.WriteLine(Regex.Replace(url, @"\)$", $",filter={assetFilter.Name};{accountFilter.Name})")); } else { Console.WriteLine($"{url}(filter={assetFilter.Name};{accountFilter.Name})"); } } Console.WriteLine(); Console.WriteLine("Copy and paste the streaming URL into the Azure Media Player at 'http://aka.ms/azuremediaplayer'."); Console.WriteLine("Please note that we have used two filters in the url(s), one trimmed the start and the end of the media"); Console.WriteLine("and the other removed high resolution video tracks. To stream the original content, remove the filters"); Console.WriteLine("from the url(s) and update player."); Console.WriteLine("When finished, press ENTER to continue."); Console.WriteLine(); Console.Out.Flush(); Console.ReadLine(); // Create a new StreamingLocator and associate filters with it. Console.WriteLine("Next, we will associate the filters with a new streaming locator."); await client.StreamingLocators.DeleteAsync(config.ResourceGroup, config.AccountName, locatorName); // Delete the old locator. Console.WriteLine("Creating a new streaming locator..."); IList <string> filters = new List <string> { assetFilter.Name, accountFilter.Name }; locator = await client.StreamingLocators.CreateAsync( config.ResourceGroup, config.AccountName, locatorName, new StreamingLocator { AssetName = outputAsset.Name, StreamingPolicyName = PredefinedStreamingPolicy.ClearStreamingOnly, Filters = filters }); urls = await GetDashStreamingUrlsAsync(client, config.ResourceGroup, config.AccountName, locator.Name, streamingEndpoint); Console.WriteLine("Since we have associated filters with the new streaming locator, No need to append filters to the url(s):"); foreach (string url in urls) { Console.WriteLine(url); } Console.WriteLine(); Console.WriteLine("Copy and paste the Streaming URL into the Azure Media Player at 'http://aka.ms/azuremediaplayer'."); Console.WriteLine("When finished, press ENTER to continue."); Console.Out.Flush(); Console.ReadLine(); } else if (job.State == JobState.Error) { Console.WriteLine($"ERROR: Job finished with error message: {job.Outputs[0].Error.Message}"); Console.WriteLine($"ERROR: error details: {job.Outputs[0].Error.Details[0].Message}"); } } catch (ApiErrorException e) { Console.WriteLine("Hit ApiErrorException"); Console.WriteLine($"\tCode: {e.Body.Error.Code}"); Console.WriteLine($"\tMessage: {e.Body.Error.Message}"); Console.WriteLine(); Console.WriteLine("Exiting, cleanup may be necessary..."); Console.ReadLine(); } finally { Console.WriteLine("Cleaning up..."); await CleanUpAsync(client, config.ResourceGroup, config.AccountName, adaptiveTransformName, jobName, inputAssetName, outputAssetName, accountFilterName, locatorName, stopEndpoint, DefaultStreamingEndpointName); Console.WriteLine("Done."); } }
/// <summary> /// Creates the AzureMediaServicesClient object based on the credentials /// supplied in local configuration file. /// </summary> /// <param name="config">The param is of type ConfigWrapper, which reads values from local configuration file.</param> /// <returns>A task.</returns> private static async Task <IAzureMediaServicesClient> CreateMediaServicesClientAsync(ConfigWrapper config) { var credentials = await GetCredentialsAsync(config); return(new AzureMediaServicesClient(config.ArmEndpoint, credentials) { SubscriptionId = config.SubscriptionId, }); }