private Guid HandleNewAudioJob(AudioJobRequestModel request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } AudioJobRequest jobRequest = new AudioJobRequest { Needed = request.Needed.LocalDateTime, Inpoint = request.Inpoint, Targets = request.Targets, SourceFilenames = request.SourceFilenames, OutputFolder = request.OutputFolder, DestinationFilename = request.DestinationFilenamePrefix }; Guid jobCorrelationId = Guid.NewGuid(); string sourceFilename = request.SourceFilenames.First(); string uniqueNamePart = Guid.NewGuid().ToString();//Used to avoid file collisions when transcoding the same file multiple times to the same location var frameCount = _helper.GetDuration(sourceFilename); var jobs = new List <AudioTranscodingJob>(); foreach (var target in request.Targets) { string extension = ContainerHelper.GetExtension(target.Format); string destinationFilename = $@"{request.DestinationFilenamePrefix}_{uniqueNamePart}_{target.Bitrate}.{extension}"; string destinationFullPath = $@"{request.OutputFolder}{Path.DirectorySeparatorChar}{destinationFilename}"; string arguments = string.Empty; string outputFullPath = Convert.ToBoolean(ConfigurationManager.AppSettings["TranscodeToLocalDisk"]) ? @"|TEMP|" : destinationFullPath; if (jobRequest.SourceFilenames.Count == 1) { if (target.Format == ContainerFormat.MP4) { arguments = $@"-y -xerror -i ""{sourceFilename}"" -c:a {target.AudioCodec.ToString().ToLowerInvariant()} -b:a {target .Bitrate}k -vn -movflags +faststart -map_metadata -1 -f {target.Format} ""{outputFullPath}"""; } else { arguments = $@"-y -xerror -i ""{sourceFilename}"" -c:a {target.AudioCodec.ToString().ToLowerInvariant()} -b:a {target .Bitrate}k -vn -map_metadata -1 -f {target.Format} ""{outputFullPath}"""; } } else { /*RESULT: * -y -xerror * -i "\\ondnas01\MediaCache\Test\test.mp3" -i "\\ondnas01\MediaCache\Test\radioavis.mp3" -i "\\ondnas01\MediaCache\Test\temp.mp3" * -filter_complex * [0:0][1:0][2:0]concat=n=3:a=1:v=0 * -c:a mp3 -b:a 64k -vn -map_metadata -1 -f MP3 \\ondnas01\MediaCache\Test\marvin\ffmpeg\test2.mp3 */ string filenameArguments = String.Empty, streams = String.Empty; int streamCount = 0; foreach (var filename in jobRequest.SourceFilenames) { filenameArguments += $@" -i ""{filename}"" "; streams = $"{streams}[{streamCount++}:0]"; } streams = $"{streams}concat=n={streamCount}:a=1:v=0"; if (target.Format == ContainerFormat.MP4) { arguments = $@"-y -xerror{filenameArguments}-filter_complex {streams} -c:a {target.AudioCodec.ToString().ToLowerInvariant()} -b:a {target .Bitrate}k -vn -movflags +faststart -map_metadata -1 -f {target.Format} ""{outputFullPath}"""; } else { arguments = $@"-y -xerror{filenameArguments}-filter_complex {streams} -c:a {target.AudioCodec.ToString().ToLowerInvariant()} -b:a {target .Bitrate}k -vn -map_metadata -1 -f {target.Format} ""{outputFullPath}"""; } } var transcodingJob = new AudioTranscodingJob { JobCorrelationId = jobCorrelationId, SourceFilename = sourceFilename, Needed = request.Needed.DateTime, State = TranscodingJobState.Queued, DestinationFilename = destinationFullPath, Bitrate = target.Bitrate, Arguments = arguments, DestinationDurationSeconds = frameCount }; jobs.Add(transcodingJob); } Directory.CreateDirectory(request.OutputFolder); if (!Directory.Exists(request.OutputFolder)) { throw new ArgumentException($@"Destination folder {request.OutputFolder} does not exist."); } return(_repository.Add(jobRequest, jobs)); }