Reputation: 40663
I want to put an image overlay over video, but I'm not sure how I can do this. I'm trying to modify example from this repo Azure Media Services v3 .NET Core tutorials , bascially what I changed here is transform:
private static Transform EnsureTransformForOverlayExists(IAzureMediaServicesClient client, string resourceGroupName, string accountName, string transformNameNew)
{
Console.WriteLine(transformNameNew);
Transform transform = client.Transforms.Get(resourceGroupName, accountName, transformName);
if (transform == null)
{
TransformOutput[] outputs = new TransformOutput[]
{
new TransformOutput(
new StandardEncoderPreset(
codecs: new Codec[]
{
new AacAudio(
channels: 2,
samplingRate: 48000,
bitrate: 128000,
profile: AacAudioProfile.AacLc
),
new H264Video(stretchMode: "AutoFit",
keyFrameInterval: TimeSpan.FromSeconds(2),
layers: new[]
{
new H264Layer(
bitrate: 1500000,
maxBitrate: 1500000,
width: "640",
height: "360"
)
}
),
new PngImage(
start: "25%",
step: "25%",
range: "80%",
layers: new PngLayer[]{
new PngLayer(
width: "50%",
height: "50%"
)
}
),
},
filters: new Filters
{
Overlays = new List<Overlay>
{
new VideoOverlay("input1")
}
},
formats: new Format[]
{
new Mp4Format(
filenamePattern: "{Basename}_letterbox{Extension}"
),
new PngFormat(
filenamePattern: "{Basename}_{Index}_{Label}_{Extension}"
),
}
))
};
transform = client.Transforms.CreateOrUpdate(resourceGroupName, accountName, transformName, outputs);
}
return transform;
}
and RunAsync
method to provide multiple inputs where one of them should be an overlay:
private static async Task RunAsync(ConfigWrapper config)
{
IAzureMediaServicesClient client = await CreateMediaServicesClientAsync(config);
// 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;
try
{
// Ensure that you have customized encoding Transform. This is really a one time setup operation.
Transform overlayTransform = EnsureTransformForOverlayExists(client, config.ResourceGroup, config.AccountName, transformName);
// 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 inputAssetName = "input-" + uniqueness;
string outputAssetName = "output-" + uniqueness;
Asset asset = client.Assets.CreateOrUpdate(config.ResourceGroup, config.AccountName, inputAssetName, new Asset());
var inputs = new JobInputs(new List<JobInput>());
var input = new JobInputHttp(
baseUri: "https://nimbuscdn-nimbuspm.streaming.mediaservices.windows.net/2b533311-b215-4409-80af-529c3e853622/",
files: new List<String> {"Ignite-short.mp4"},
label:"input1"
);
inputs.Inputs.Add((input));
input = new JobInputHttp(
baseUri: "SomeBaseUriHere",
files: new List<string> {"AssetVideo_000001_None_.png"},
label: "overlay");
inputs.Inputs.Add((input));
Asset outputAsset = CreateOutputAsset(client, config.ResourceGroup, config.AccountName, outputAssetName);
Job job = SubmitJob(client, config.ResourceGroup, config.AccountName, transformName, jobName, inputs, outputAsset.Name);
DateTime startedTime = DateTime.Now;
job = WaitForJobToFinish(client, config.ResourceGroup, config.AccountName, transformName, jobName);
TimeSpan elapsed = DateTime.Now - startedTime;
if (job.State == JobState.Finished)
{
Console.WriteLine("Job finished.");
if (!Directory.Exists(outputFolder))
Directory.CreateDirectory(outputFolder);
await MakeContainerPublic(client, config.ResourceGroup, config.AccountName, outputAsset.Name, config.BlobConnectionString);
DownloadResults(client, config.ResourceGroup, config.AccountName, outputAsset.Name, outputFolder).Wait();
}
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 ex)
{
string code = ex.Body.Error.Code;
string message = ex.Body.Error.Message;
Console.WriteLine("ERROR:API call failed with error code: {0} and message: {1}", code, message);
}
}
But I have this error
Microsoft.Cloud.Media.Encoding.PresetException: Preset ERROR: There are 2 input assets. Preset has 2 Source but does NOT specify AssetID for each Source and I have no idea how to overcome this.
Upvotes: 0
Views: 206