Ejemplo n.º 1
0
        public Guid Add(AudioJobRequest request, ICollection <AudioTranscodingJob> jobs)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (jobs == null)
            {
                throw new ArgumentNullException(nameof(jobs));
            }
            if (jobs.Count == 0)
            {
                throw new ArgumentException("Jobs parameter must contain at least 1 job", nameof(jobs));
            }

            Guid jobCorrelationId = Guid.NewGuid();

            using (var scope = TransactionUtils.CreateTransactionScope())
            {
                using (var connection = _helper.GetConnection())
                {
                    connection.Execute(
                        "INSERT INTO FfmpegAudioRequest (JobCorrelationId, SourceFilename, DestinationFilename, OutputFolder, Needed, Created) VALUES(@JobCorrelationId, @SourceFilename, @DestinationFilename, @OutputFolder, @Needed, @Created);",
                        new
                    {
                        JobCorrelationId = jobCorrelationId,
                        SourceFilename   = string.Join(" ", request.SourceFilenames),
                        request.DestinationFilename,
                        request.Needed,
                        request.OutputFolder,
                        Created = DateTime.UtcNow
                    });

                    foreach (AudioDestinationFormat target in request.Targets)
                    {
                        connection.Execute(
                            "INSERT INTO FfmpegAudioRequestTargets (JobCorrelationId, Codec, Format, Bitrate) VALUES(@JobCorrelationId, @Codec, @Format, @Bitrate);",
                            new
                        {
                            jobCorrelationId,
                            Codec  = target.AudioCodec.ToString(),
                            Format = target.Format.ToString(),
                            target.Bitrate
                        });
                    }

                    var jobId = connection.ExecuteScalar <int>(
                        "INSERT INTO FfmpegJobs (JobCorrelationId, Created, Needed, JobState, JobType) VALUES(@JobCorrelationId, @Created, @Needed, @JobState, @JobType);SELECT @@IDENTITY;",
                        new
                    {
                        JobCorrelationId = jobCorrelationId,
                        Created          = DateTimeOffset.UtcNow,
                        request.Needed,
                        JobState = TranscodingJobState.Queued,
                        JobType  = JobType.Audio
                    });

                    foreach (AudioTranscodingJob transcodingJob in jobs)
                    {
                        connection.Execute(
                            "INSERT INTO FfmpegTasks (FfmpegJobs_id, Arguments, TaskState, DestinationFilename, DestinationDurationSeconds, VerifyOutput) VALUES(@FfmpegJobsId, @Arguments, @TaskState, @DestinationFilename, @DestinationDurationSeconds, @VerifyOutput);",
                            new
                        {
                            FfmpegJobsId = jobId,
                            transcodingJob.Arguments,
                            TaskState = TranscodingJobState.Queued,
                            transcodingJob.DestinationFilename,
                            transcodingJob.DestinationDurationSeconds,
                            VerifyOutput = true
                        });
                    }
                }

                scope.Complete();

                return(jobCorrelationId);
            }
        }
Ejemplo n.º 2
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));
        }