public void InvalidOrderJsonExceptionTest() { var req = new AudioJobRequestModel(); var jobTask = _audioClient.CreateNewAsync(req); var innerException = Assert.Throws <AggregateException>(() => jobTask.Wait()).InnerException as JsonSerializationException; Console.WriteLine(innerException.ToString()); }
public Guid CreateNew(AudioJobRequestModel input) { if (!ModelState.IsValid) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)); } var res = HandleNewAudioJob(input); _logging.Info($"Created new audio job : {res}"); return(res); }
public async Task AudioJobTest() { File.Copy(AudioTestFile, _sourceAudioTestFile); Directory.CreateDirectory(_targetTestPath); AudioJobRequestModel request = new AudioJobRequestModel() { DestinationFilenamePrefix = _targetFileAudioPrefix, Inpoint = "0", Needed = DateTime.UtcNow, OutputFolder = _targetTestPath, SourceFilenames = new ObservableCollection <string>(new[] { _sourceAudioTestFile }), Targets = AudioTargets }; var jobGuid = await _audioJobClient.CreateNewAsync(request); bool done; int maxCount = 240; Stopwatch sw = new Stopwatch(); Console.WriteLine("Starting job {0}", jobGuid); sw.Start(); FfmpegJobModel job; do { job = await _statusClient.GetAsync(jobGuid); var runningTask = job.Tasks.FirstOrDefault(t => t.State == FfmpegTaskModelState.InProgress); Console.WriteLine($"Jobstatus : {job.State}, time: {sw.ElapsedMilliseconds} ms, filename: {runningTask?.DestinationFilename}, {runningTask?.Progress:0.##} %"); if (job.State == FfmpegJobModelState.Failed || job.State == FfmpegJobModelState.Canceled || job.State == FfmpegJobModelState.Unknown) { throw new Exception($"Error running job. job state: {job.State}"); } done = job.State == FfmpegJobModelState.Done; if (!done) { Thread.Sleep(1000); } } while (!done && maxCount-- > 0); Assert.That(done, Is.True); Console.WriteLine($"Job done, time : {sw.ElapsedMilliseconds} ms ({maxCount})"); sw.Stop(); Assert.That(job.Tasks.Count, Is.EqualTo(request.Targets.Count)); foreach (var target in job.Tasks) { string fileFullPath = Path.Combine(_targetTestPath, target.DestinationFilename); Console.WriteLine($"Checking file: {fileFullPath}"); Assert.That(File.Exists(fileFullPath), Is.True, $"Expected to find transcoded file @ {fileFullPath}"); } }
public void InvalidOrderNoTargetsExceptionTest() { var req = new AudioJobRequestModel { //Targets = null, Inpoint = TestRoot, SourceFilenames = new ObservableCollection <string> { "cliptest1.mov" }, OutputFolder = TestRoot + @"\FFMpg", DestinationFilenamePrefix = "", Needed = DateTime.UtcNow }; var jobTask = _audioClient.CreateNewAsync(req); var agg = Assert.Throws <AggregateException>(() => jobTask.Wait()); var innerException = agg.InnerException; Console.WriteLine(innerException?.Message); }
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)); }
public async Task AudioIntroOutroJobTest() { File.Copy(AudioTestFile, _sourceAudioTestFile); File.Copy(AudioIntroTestFile, _sourceAudioIntroFile); File.Copy(AudioOutroTestFile, _sourceAudioOutroFile); Directory.CreateDirectory(_targetTestPath); var introDuration = new MediaFile(_sourceAudioIntroFile).Audio[0].Duration; var mainDuration = new MediaFile(_sourceAudioTestFile).Audio[0].Duration; var outroDuration = new MediaFile(_sourceAudioOutroFile).Audio[0].Duration; Assert.That(introDuration, Is.GreaterThan(0)); Assert.That(mainDuration, Is.GreaterThan(0)); Assert.That(outroDuration, Is.GreaterThan(0)); AudioJobRequestModel request = new AudioJobRequestModel() { DestinationFilenamePrefix = _targetFileAudioIntroOutroPrefix, Inpoint = "0", Needed = DateTime.UtcNow, OutputFolder = _targetTestPath, SourceFilenames = new ObservableCollection <string>(new[] { _sourceAudioIntroFile, _sourceAudioTestFile, _sourceAudioOutroFile }), Targets = AudioTargets }; var jobGuid = await _audioJobClient.CreateNewAsync(request); bool done; int maxCount = 240; Stopwatch sw = new Stopwatch(); Console.WriteLine($"Starting job {jobGuid}"); sw.Start(); FfmpegJobModel job; do { job = await _statusClient.GetAsync(jobGuid); var runningTask = job.Tasks.FirstOrDefault(t => t.State == FfmpegTaskModelState.InProgress); Console.WriteLine($"Jobstatus : {job.State}, time: {sw.ElapsedMilliseconds} ms, filename: {runningTask?.DestinationFilename}, {runningTask?.Progress:0.##} %"); if (job.State == FfmpegJobModelState.Failed || job.State == FfmpegJobModelState.Canceled || job.State == FfmpegJobModelState.Unknown) { throw new Exception($"Error running job. job state: {job.State}"); } done = job.State == FfmpegJobModelState.Done; if (!done) { Thread.Sleep(1000); } } while (!done && maxCount-- > 0); Assert.That(done, Is.True); Console.WriteLine($"Job done, time : {sw.ElapsedMilliseconds} ms ({maxCount})"); sw.Stop(); Assert.That(job.Tasks.Count, Is.EqualTo(request.Targets.Count)); foreach (var target in job.Tasks) { var fileFullPath = Path.Combine(_targetTestPath, target.DestinationFilename); Console.WriteLine("Checking file: " + fileFullPath); Assert.That(File.Exists(fileFullPath), Is.True, $"Expected to find transcoded file @ {fileFullPath}"); var mi = new MediaFile(fileFullPath); if (mi.Audio[0].Duration == 0) { Console.WriteLine($"Skips duration test for {fileFullPath} since media info thinks it has zero duration."); continue; } var destDuration = mi.Audio[0].Duration; Assert.That(Math.Abs(destDuration - (introDuration + mainDuration + outroDuration)), Is.LessThan(100), "Stiching should not differ more than 100 ms"); } }