From 87072f6fd39fb5ec784fa0f39050090b992812ac Mon Sep 17 00:00:00 2001 From: Yubo Xie Date: Wed, 29 Nov 2023 03:02:18 -0800 Subject: [PATCH] [EncodingAndPackagingExample] Add HLS output format support --- .../EncodingAndPackagingTool.cs | 11 ++++++++++- .../EncodingAndPackagingTool.Cli.Test.cs | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/EncodingAndPackagingExample/EncodingAndPackagingTool.Core/EncodingAndPackagingTool.cs b/EncodingAndPackagingExample/EncodingAndPackagingTool.Core/EncodingAndPackagingTool.cs index bf092bc..688eee9 100644 --- a/EncodingAndPackagingExample/EncodingAndPackagingTool.Core/EncodingAndPackagingTool.cs +++ b/EncodingAndPackagingExample/EncodingAndPackagingTool.Core/EncodingAndPackagingTool.cs @@ -90,6 +90,7 @@ public async Task EncodeAndPackageAsync(Uri mp4BlobUri, Uri outputStorageUri, Ca // Prepare ffmpeg command lines. var mpdFile = $"{Path.GetFileNameWithoutExtension(inputFile)}.mpd"; + var hlsFile = $"{Path.GetFileNameWithoutExtension(inputFile)}.m3u8"; FFMpegArgumentProcessor ffmpegCommand; if (ffprobeAnalyse.VideoStreams != null) @@ -105,9 +106,13 @@ public async Task EncodeAndPackageAsync(Uri mp4BlobUri, Uri outputStorageUri, Ca .WithCustomArgument("-s:v:1 1280x720") .WithCustomArgument("-s:v:2 1920x1080") .WithCustomArgument("-adaptation_sets \"id=0,streams=v id=1,streams=a\"") + /* HLS related settings, comments out if you don't need generate hls playlist */ + .WithCustomArgument("-hls_playlist 1") + .WithCustomArgument($"-hls_master_name {hlsFile}") + /* HLS settings done */ .ForceFormat("dash")); } - else + else { // For audio only stream. ffmpegCommand = FFMpegArguments @@ -115,6 +120,10 @@ public async Task EncodeAndPackageAsync(Uri mp4BlobUri, Uri outputStorageUri, Ca .OutputToFile(mpdFile, overwrite: true, args => args .WithAudioCodec(AudioCodec.Aac) .WithCustomArgument("-adaptation_sets \"id=0,streams=a\"") + /* HLS related settings, comments out if you don't need generate hls playlist */ + .WithCustomArgument("-hls_playlist 1") + .WithCustomArgument($"-hls_master_name {hlsFile}") + /* HLS settings done */ .ForceFormat("dash")); } diff --git a/EncodingAndPackagingExample/EncodingAndPackagingTool.Test/EncodingAndPackagingTool.Cli.Test.cs b/EncodingAndPackagingExample/EncodingAndPackagingTool.Test/EncodingAndPackagingTool.Cli.Test.cs index c2d7e0b..58d224c 100644 --- a/EncodingAndPackagingExample/EncodingAndPackagingTool.Test/EncodingAndPackagingTool.Cli.Test.cs +++ b/EncodingAndPackagingExample/EncodingAndPackagingTool.Test/EncodingAndPackagingTool.Cli.Test.cs @@ -52,6 +52,7 @@ public async Task EncodingAndPackagingToolTest() await process.WaitForExitAsync(); Assert.Equal(0, process.ExitCode); + // Verify dash related files. // We should have the output mpd file. var blob = new BlobClient(new Uri($"{outputContainerUri}/bunny.640x480.15fps.mpd"), _azureCrendentail); using (var stream = await blob.OpenReadAsync()) @@ -109,6 +110,24 @@ public async Task EncodingAndPackagingToolTest() } } + // Verify hls related files. + // We should have the output master hls file. + blob = new BlobClient(new Uri($"{outputContainerUri}/bunny.640x480.15fps.m3u8"), _azureCrendentail); + using (var stream = await blob.OpenReadAsync()) + { + Assert.True(stream.Length > 400); + } + + // We should have 4 hls playlist file. + for (var i = 0; i < 4; ++i) + { + blob = new BlobClient(new Uri($"{outputContainerUri}/media_{i}.m3u8"), _azureCrendentail); + using (var stream = await blob.OpenReadAsync()) + { + Assert.True(stream.Length > 1000); + } + } + // Delete the container if success. var container = new BlobContainerClient(new Uri(outputContainerUri), _azureCrendentail); await container.DeleteAsync();