Beispiel #1
0
        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());
        }
Beispiel #2
0
        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}");
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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");
            }
        }