I'm conditionally constructing the command object with settings and filters indirectly defined by the user. Filters are optionally applied, but when they are the audio is stripped from the video because -filter_complex
requires that audio be explicitly included in a separate -map
command if it's not included in the filters. I can't find a way to add the -map
command for audio. I've only got one input and one output, and the filters are relatively simple, so how can I get audio into the output from the input file?
Here's a slightly simplified version of what I'm doing at the moment. settingsList is a List<ISetting>
which may contain codecs, frame rate, output duration, format, quality etc.
var outputSettings = SettingsCollection.ForOutput(settingsList.ToArray());
var videoFilterList = new List<IFilter>();
if (resizeSettings.ContentScale != 1f)
{
videoFilterList.Add(new Scale(resizeSettings.ContentRect.Width, resizeSettings.ContentRect.Height));
if (resizeSettings.Crop)
videoFilterList.Add(new Crop(resizeSettings.CropRect.Size.Width, resizeSettings.CropRect.Size.Height, resizeSettings.CropRect.Location.X, resizeSettings.CropRect.Location.Y));
if (resizeSettings.Pad)
{
int expectedOutputHeight = sourceHeight * (resizeSettings.OutputSize.Width / sourceWidth);
var padFilter = new Pad(new System.Drawing.Size(resizeSettings.OutputSize.Width, resizeSettings.OutputSize.Height), new System.Drawing.Point(Math.Max(0, (int)(resizeSettings.OutputSize.Width - (sourceWidth * resizeSettings.ContentScale)) / 2), Math.Max(0, (int)(resizeSettings.OutputSize.Height - (sourceHeight * resizeSettings.ContentScale)) / 2)));
if (backgroundColor != null)
padFilter.Color = ToHexString(backgroundColor.Value);
videoFilterList.Add(padFilter);
}
}
var commandFactory = CommandFactory.Create();
CommandStage command = null;
if (inputSettingsList.Count > 0)
command = commandFactory.CreateOutputCommand().WithInput<VideoStream>(tempFile.FullName, SettingsCollection.ForInput(inputSettingsList.ToArray()));
else
command = commandFactory.CreateOutputCommand().WithInput<VideoStream>(tempFile.FullName);
if (videoFilterList.Count > 0)
{
command = command.Filter(Filterchain.FilterTo<VideoStream>(videoFilterList.ToArray()));
}
Guid outputFileID = Guid.NewGuid();
string outputTempFilePath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), String.Format("{0}.mp4", outputFileID));
List<CommandOutput> output = command.MapTo<Mp4>(outputTempFilePath, outputSettings);
var result = commandFactory.Render();