public virtual IProcessManagerAvs CreateAvs(ProcessOptions options = null, ProcessStartedEventHandler callback = null)
        {
            var Result = Create <IProcessManagerAvs>(options, callback);

            Result.Setup(x => x.RunAvisynth(It.IsAny <string>())).Callback((string s) => Result.Object.Run("avs2yuv.exe", s)).Returns(RunResult);
            return(Result.Object);
        }
        public virtual Mock <T> Create <T>(ProcessOptions options = null, ProcessStartedEventHandler callback = null) where T : class, IProcessManager
        {
            var Result = new Mock <T>();

            // process.SetupAllProperties();
            Result.Setup(x => x.Options).Returns(options);
            Result.Setup(x => x.Run(It.IsAny <string>(), It.IsAny <string>())).Callback((string s, string a) => {
                Result.Setup(x => x.CommandWithArgs).Returns(string.Format(@"""{0}"" {1}", s, a).TrimEnd());
                Result.Setup(x => x.Run(It.IsAny <string>(), It.IsAny <string>())).Returns(RunResult);
                Result.Raise(x => x.ProcessStarted += null, Result, new ProcessStartedEventArgs());
                callback?.Invoke(Result, new ProcessStartedEventArgs());
                var Ffmpeg = Result as Mock <IProcessManagerFFmpeg>;
                if (Ffmpeg != null)
                {
                    Ffmpeg.Setup(x => x.FileStreams).Returns(new List <FFmpegStreamInfo>()
                    {
                        new FFmpegVideoStreamInfo(), new FFmpegAudioStreamInfo()
                    });
                    Ffmpeg.Raise(x => x.StatusUpdated += null, Result, new StatusUpdatedEventArgs(new FFmpegStatus()
                    {
                        Frame = FrameCount
                    }));
                }
                Result.Raise(x => x.ProcessCompleted += null, Result, new ProcessCompletedEventArgs());
            });
            Instances.Add(Result.Object);
            return(Result);
        }
        public override IProcessWorker Create(ProcessOptions options = null, ProcessStartedEventHandler callback = null)
        {
            var Result = base.Create(options, callback);

            Instances.Add(Result);
            return(Result);
        }
Example #4
0
        /// <summary>
        /// Returns the version information from FFmpeg.
        /// </summary>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>A IFFmpegProcess object containing the version information.</returns>
        public string GetVersion(ProcessOptionsEncoder options = null, ProcessStartedEventHandler callback = null)
        {
            IProcessWorkerEncoder Worker = factory.CreateEncoder(options, callback);

            Worker.OutputType = ProcessOutput.Output;
            Worker.RunEncoder("-version", EncoderApp.FFmpeg);
            return(Worker.Output);
        }
Example #5
0
        /// <summary>
        /// Returns the version information from FFmpeg.
        /// </summary>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>A IFFmpegProcess object containing the version information.</returns>
        public IProcessManagerFFmpeg GetVersion(ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            IProcessManagerFFmpeg Worker = factory.CreateFFmpeg(options, callback);

            Worker.OutputType = ProcessOutput.Output;
            Worker.RunFFmpeg("-version");
            return(Worker);
        }
        public void GetFrameCount_Valid_ReturnsFrameCount(string output, int expected)
        {
            var Info = SetupInfo();
            ProcessStartedEventHandler Callback = (s, e) => FakeProcessWorkerFactory.FeedOutputToProcess(e.ProcessWorker, output);

            var Result = Info.GetFrameCount(TestFile, null, Callback);

            Assert.Equal(expected, Result);
        }
Example #7
0
        /// <summary>
        /// Creates a new process manager with specified options.
        /// </summary>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The newly created process manager.</returns>
        public IProcessManager Create(ProcessOptions options = null, ProcessStartedEventHandler callback = null)
        {
            var Result = new ProcessManager(Config, Parser, ProcessFactory, FileSystemService, options);

            if (callback != null)
            {
                Result.ProcessStarted += callback;
            }
            return(Result);
        }
Example #8
0
        public void Truncate_Valid_Success(string source, string destExt, TimeSpan?startPos, TimeSpan?duration)
        {
            string                     Src     = AppPaths.GetInputFile(source);
            string                     Dest    = AppPaths.PrepareDestPath("Truncate", source, destExt);
            var                        Muxer   = SetupMuxer();
            IProcessManager            Manager = null;
            ProcessStartedEventHandler Started = (s, e) => Manager = e.ProcessManager;

            var Result = Muxer.Truncate(Src, Dest, startPos, duration, null, Started);

            output.WriteLine(Manager.CommandWithArgs);
            output.WriteLine(Manager.Output);
            Assert.Equal(CompletionStatus.Success, Result);
            Assert.True(File.Exists(Dest));
            var FileInfo = GetFileInfo(Dest);

            if (duration.HasValue)
            {
                Assert.True(Math.Abs((duration.Value - FileInfo.FileDuration).TotalSeconds) < .1, "Truncate did not produce expected file duration.");
            }
        }
Example #9
0
        private CompletionStatus EncodeX264Internal(SourceType sourceType, EncoderApp encoderApp, string source, string destination, string encodeArgs, ProcessOptionsEncoder options, ProcessStartedEventHandler callback)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("Source cannot be null or empty.", nameof(source));
            }
            if (string.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("Destination cannot be null or empty.", nameof(destination));
            }
            File.Delete(destination);

            StringBuilder Query = new StringBuilder();

            if (sourceType != SourceType.Direct)
            {
                Query.AppendFormat("--{0}y4m ", encoderApp == EncoderApp.x264 ? "demuxer " : "");
            }
            if (!string.IsNullOrEmpty(encodeArgs))
            {
                Query.Append($"{encodeArgs} ");
            }
            Query.Append($@"-o ""{destination}"" ");
            if (sourceType == SourceType.Direct)
            {
                Query.Append($@"""{source}""");
            }
            else
            {
                Query.Append("-");
            }

            // Run X264 or X265 with query.
            IProcessWorkerEncoder Worker = factory.CreateEncoder(options, callback);
            CompletionStatus      Result = RunEncoderInternal(source, Query.ToString(), Worker, sourceType, encoderApp);

            return(Result);
        }
        public virtual IProcessManagerFFmpeg CreateFFmpeg(ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            var Result = Create <IProcessManagerFFmpeg>(options, callback);

            Result.Setup(x => x.RunFFmpeg(It.IsAny <string>())).Callback((string s) => Result.Object.Run("ffmpeg.exe", s)).Returns(RunResult);
            return(Result.Object);
        }
 public virtual IProcessManager Create(ProcessOptions options = null, ProcessStartedEventHandler callback = null)
 {
     return(Create <IProcessManager>(options, callback).Object);
 }
Example #12
0
        /// <summary>
        /// Gets file streams information of specified file via FFmpeg.
        /// </summary>
        /// <param name="source">The file to get information about.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>A IFFmpegProcess object containing the file information.</returns>
        public IProcessManagerFFmpeg GetFileInfo(string source, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("Source cannot be null or empty.", nameof(source));
            }
            IProcessManagerFFmpeg Worker = factory.CreateFFmpeg(options, callback);

            Worker.RunFFmpeg(string.Format(@"-i ""{0}""", source));
            return(Worker);
        }
Example #13
0
        /// <summary>
        /// Merges the specified list of file streams.
        /// </summary>
        /// <param name="fileStreams">The list of file streams to include in the output.</param>
        /// <param name="destination">The destination file.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The process completion status.</returns>
        public CompletionStatus Muxe(IEnumerable <FFmpegStream> fileStreams, string destination, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            if (fileStreams == null || !fileStreams.Any())
            {
                throw new ArgumentException("FileStreams cannot be null or empty.", nameof(fileStreams));
            }
            if (string.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("Destination cannot be null or empty.", nameof(destination));
            }

            CompletionStatus Result    = CompletionStatus.Success;
            List <string>    TempFiles = new List <string>();

            fileSystem.Delete(destination);

            // FFMPEG fails to muxe H264 into MKV container. Converting to MP4 and then muxing with the audio, however, works.
            foreach (FFmpegStream item in fileStreams)
            {
                if (string.IsNullOrEmpty(item.Path) && item.Type != FFmpegStreamType.None)
                {
                    throw new ArgumentException("FFmpegStream.Path cannot be null or empty.", nameof(item.Path));
                }
                if (item.Type == FFmpegStreamType.Video && (item.Format == "h264" || item.Format == "h265") && destination.EndsWith(".mkv"))
                {
                    string NewFile = item.Path.Substring(0, item.Path.LastIndexOf('.')) + ".mp4";
                    Result = Muxe(new List <FFmpegStream>()
                    {
                        item
                    }, NewFile, options);
                    TempFiles.Add(NewFile);
                    if (Result != CompletionStatus.Success)
                    {
                        break;
                    }
                }
            }

            if (Result == CompletionStatus.Success)
            {
                // Join audio and video files.
                StringBuilder Query = new StringBuilder();
                StringBuilder Map   = new StringBuilder();
                Query.Append("-y ");
                int           StreamIndex = 0;
                bool          HasVideo = false, HasAudio = false, HasPcmDvdAudio = false;
                StringBuilder AacFix             = new StringBuilder();
                var           FileStreamsOrdered = fileStreams.OrderBy(f => f.Type);
                foreach (FFmpegStream item in FileStreamsOrdered)
                {
                    if (item.Type == FFmpegStreamType.Video)
                    {
                        HasVideo = true;
                    }
                    if (item.Type == FFmpegStreamType.Audio)
                    {
                        HasAudio = true;
                        if (item.Format == "aac")
                        {
                            AacFix.AppendFormat("-bsf:{0} aac_adtstoasc ", StreamIndex);
                        }
                        if (item.Format == "pcm_dvd")
                        {
                            HasPcmDvdAudio = true;
                        }
                    }
                    Query.Append("-i \"");
                    Query.Append(item.Path);
                    Query.Append("\" ");
                    Map.Append("-map ");
                    Map.Append(StreamIndex++);
                    Map.Append(":");
                    Map.Append(item.Index);
                    Map.Append(" ");
                }
                if (!HasVideo && !HasAudio)
                {
                    throw new ArgumentException("FileStreams cannot be empty.", nameof(fileStreams));
                }
                if (HasVideo)
                {
                    Query.Append("-vcodec copy ");
                }
                if (HasAudio)
                {
                    Query.Append(HasPcmDvdAudio ? "-acodec pcm_s16le " : "-acodec copy ");
                }
                Query.Append(Map);
                // FFMPEG-encoded AAC streams are invalid and require an extra flag to join.
                if (AacFix.Length > 0 && HasVideo)
                {
                    Query.Append(AacFix);
                }
                Query.Append("\"");
                Query.Append(destination);
                Query.Append("\"");
                IProcessManagerFFmpeg Worker = factory.CreateFFmpeg(options, callback);
                Result = Worker.RunFFmpeg(Query.ToString());
            }

            // Delete temp file.
            foreach (string item in TempFiles)
            {
                fileSystem.Delete(item);
            }
            return(Result);
        }
Example #14
0
        public FileInfoFFmpeg GetFileInfo(string source, ProcessOptionsEncoder options = null, ProcessStartedEventHandler callback = null)
        {
            var result = new FileInfoFFmpeg();

            result.ParseFileInfo(OutputText, null);
            return(result);
        }
Example #15
0
        /// <summary>
        /// Concatenates (merges) all specified files.
        /// </summary>
        /// <param name="files">The files to merge.</param>
        /// <param name="destination">The destination file.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The process completion status.</returns>
        public CompletionStatus Concatenate(IEnumerable <string> files, string destination, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            if (files == null || !files.Any())
            {
                throw new ArgumentException("Files cannot be null or empty.", nameof(files));
            }
            if (string.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("Destination cannot be null or empty.", nameof(destination));
            }
            CompletionStatus Result = CompletionStatus.None;

            // Write temp file.
            string        TempFile    = fileSystem.GetTempFile();
            StringBuilder TempContent = new StringBuilder();

            foreach (string item in files)
            {
                TempContent.AppendFormat("file '{0}'", item).AppendLine();
            }
            fileSystem.WriteAllText(TempFile, TempContent.ToString());

            string Query = string.Format(@"-y -f concat -fflags +genpts -async 1 -safe 0 -i ""{0}"" -c copy ""{1}""", TempFile, destination);

            IProcessManagerFFmpeg Worker = factory.CreateFFmpeg(options, callback);

            Result = Worker.RunFFmpeg(Query.ToString());

            fileSystem.Delete(TempFile);
            return(Result);
        }
Example #16
0
 /// <summary>
 /// Encodes a media file with specified arguments.
 /// </summary>
 /// <param name="source">The file to convert.</param>
 /// <param name="videoCodec">The codec to use to encode the video stream.</param>
 /// <param name="audioCodec">The codec to use to encode the audio stream.</param>
 /// <param name="encodeArgs">Additional arguments to pass to FFmpeg.</param>
 /// <param name="destination">The destination file.</param>
 /// <param name="options">The options for starting the process.</param>
 /// <param name="callback">A method that will be called after the process has been started.</param>
 /// <returns>The process completion status.</returns>
 public CompletionStatus Encode(string source, string videoCodec, string audioCodec, string encodeArgs, string destination, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
 {
     string[] VideoCodecList = string.IsNullOrEmpty(videoCodec) ? null : new string[] { videoCodec };
     string[] AudioCodecList = string.IsNullOrEmpty(audioCodec) ? null : new string[] { audioCodec };
     return(Encode(source, VideoCodecList, AudioCodecList, encodeArgs, destination, options, callback));
 }
Example #17
0
 /// <summary>
 /// Extracts the audio stream from specified file.
 /// </summary>
 /// <param name="source">The media file to extract from.</param>
 /// <param name="destination">The destination file.</param>
 /// <param name="options">The options for starting the process.</param>
 /// <param name="callback">A method that will be called after the process has been started.</param>
 /// <returns>The process completion status.</returns>
 public CompletionStatus ExtractAudio(string source, string destination, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
 {
     return(ExtractStream(@"-y -i ""{0}"" -vn -acodec copy ""{1}""", source, destination, options, callback));
 }
Example #18
0
 /// <summary>
 /// Converts specified file into AVI UT Video format.
 /// </summary>
 /// <param name="source">The file to convert.</param>
 /// <param name="destination">The destination file, ending with .AVI</param>
 /// <param name="audio">Whether to encode audio.</param>
 /// <param name="options">The options for starting the process.</param>
 /// <param name="callback">A method that will be called after the process has been started.</param>
 /// <returns>The process completion status.</returns>
 public CompletionStatus ConvertToAvi(string source, string destination, bool audio, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
 {
     // -vcodec huffyuv or utvideo, -acodec pcm_s16le
     return(Encode(source, "utvideo", audio ? "pcm_s16le" : null, null, destination, options, callback));
 }
Example #19
0
        /// <summary>
        /// Encodes a media file with specified arguments.
        /// </summary>
        /// <param name="source">The file to convert.</param>
        /// <param name="videoCodec">The codec(s) to use to encode the video stream(s).</param>
        /// <param name="audioCodec">The codec(s) to use to encode the audio stream(s).</param>
        /// <param name="encodeArgs">Additional arguments to pass to FFmpeg.</param>
        /// <param name="destination">The destination file.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The process completion status.</returns>
        public CompletionStatus Encode(string source, string[] videoCodec, string[] audioCodec, string encodeArgs, string destination, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            File.Delete(destination);
            StringBuilder Query = new StringBuilder();

            Query.Append("-y -i ");
            // AviSynth source will pipe through Avs2Yuv into FFmpeg.
            bool SourceAvisynth = source.ToLower().EndsWith(".avs");

            if (SourceAvisynth)
            {
                Query.Append("-"); // Pipe source
            }
            else
            {
                Query.Append("\"");
                Query.Append(source);
                Query.Append("\"");
            }

            // Add video codec.
            if (videoCodec == null || videoCodec.Length == 0)
            {
                Query.Append(" -vn");
            }
            else if (videoCodec.Length == 1)
            {
                Query.Append(" -vcodec ");
                Query.Append(videoCodec[0]);
            }
            else
            {
                for (int i = 0; i < videoCodec.Length; i++)
                {
                    Query.Append(" -vcodec:");
                    Query.Append(i);
                    Query.Append(" ");
                    Query.Append(videoCodec[i]);
                }
            }

            // Add audio codec.
            if (audioCodec == null || audioCodec.Length == 0)
            {
                Query.Append(" -an");
            }
            else if (audioCodec.Length == 1)
            {
                Query.Append(" -acodec ");
                Query.Append(audioCodec[0]);
            }
            else
            {
                for (int i = 0; i < audioCodec.Length; i++)
                {
                    Query.Append(" -acodec:");
                    Query.Append(i);
                    Query.Append(" ");
                    Query.Append(audioCodec[i]);
                }
            }

            if (!string.IsNullOrEmpty(encodeArgs))
            {
                Query.Append(" ");
                Query.Append(encodeArgs);
            }

            Query.Append(" \"");
            Query.Append(destination);
            Query.Append("\"");

            // Run FFmpeg with query.
            IProcessManagerFFmpeg Worker = factory.CreateFFmpeg(options, callback);
            CompletionStatus      Result = SourceAvisynth ?
                                           Worker.RunAvisynthToEncoder(source, Query.ToString()) :
                                           Worker.RunFFmpeg(Query.ToString());

            return(Result);
        }
Example #20
0
        /// <summary>
        /// Truncates a media file from specified start position with specified duration.
        /// </summary>
        /// <param name="source">The source file to truncate.</param>
        /// <param name="destination">The output file to write.</param>
        /// <param name="startPos">The position where to start copying. Anything before this position will be ignored. TimeSpan.Zero or null to start from beginning.</param>
        /// <param name="duration">The duration after which to stop copying. Anything after this duration will be ignored. TimeSpan.Zero or null to copy until the end.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The process completion status.</returns>
        public CompletionStatus Truncate(string source, string destination, TimeSpan?startPos, TimeSpan?duration = null, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("Source cannot be empty.", nameof(source));
            }
            if (string.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("Destination cannot be empty.", nameof(destination));
            }
            fileSystem.Delete(destination);
            IProcessManagerFFmpeg Worker = factory.CreateFFmpeg(options, callback);
            string Args = string.Format(@"-i ""{0}"" -vcodec copy -acodec copy {1}{2}""{3}""", source,
                                        startPos.HasValue && startPos > TimeSpan.Zero ? string.Format("-ss {0:c} ", startPos) : "",
                                        duration.HasValue && duration > TimeSpan.Zero ? string.Format("-t {0:c} ", duration) : "",
                                        destination);

            return(Worker.RunFFmpeg(Args));
        }
        /// <summary>
        /// Creates a new process worker to run an encoder with specified options.
        /// </summary>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The newly created encoder process manager.</returns>
        public virtual IProcessWorkerEncoder CreateEncoder(ProcessOptionsEncoder options = null, ProcessStartedEventHandler callback = null)
        {
            var Result = new ProcessWorkerEncoder(Config, ProcessFactory, FileSystemService, ParserFactory, options);

            if (callback != null)
            {
                Result.ProcessStarted += callback;
            }
            return(Result);
        }
Example #22
0
 public string GetVersion(ProcessOptionsEncoder options = null, ProcessStartedEventHandler callback = null) => "Version number";
Example #23
0
        /// <summary>
        /// Returns the exact frame count of specified video file.
        /// </summary>
        /// <param name="source">The file to get information about.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The number of frames in the video.</returns>
        public long GetFrameCount(string source, ProcessOptionsEncoder options = null, ProcessStartedEventHandler callback = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("Source cannot be null or empty.", nameof(source));
            }
            long Result = 0;
            IProcessWorkerEncoder Worker = factory.CreateEncoder(options, callback);

            Worker.ProgressReceived += (sender, e) => {
                // Read all status lines and keep the last one.
                Result = (e.Progress as ProgressStatusFFmpeg).Frame;
            };
            Worker.RunEncoder($@"-i ""{source}"" -f null /dev/null", EncoderApp.FFmpeg);
            return(Result);
        }
Example #24
0
        /// <summary>
        /// Extracts an audio or video stream from specified file.
        /// </summary>
        /// <param name="args">The arguments string that will be passed to FFmpeg.</param>
        /// <param name="source">The media file to extract from.</param>
        /// <param name="destination">The destination file.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The process completion status.</returns>
        private CompletionStatus ExtractStream(string args, string source, string destination, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("Source cannot be empty.", nameof(source));
            }
            if (string.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("Destination cannot be empty.", nameof(destination));
            }
            fileSystem.Delete(destination);
            IProcessManagerFFmpeg Worker = factory.CreateFFmpeg(options, callback);

            return(Worker.RunFFmpeg(string.Format(args, source, destination)));
        }
Example #25
0
 public long GetFrameCount(string source, ProcessOptionsEncoder options = null, ProcessStartedEventHandler callback = null) => 1;
Example #26
0
        private CompletionStatus EncodeFFmpegInternal(SourceType sourceType, string source, string destination, string videoCodec, string audioCodec, string encodeArgs, ProcessOptionsEncoder options, ProcessStartedEventHandler callback)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("Source cannot be null or empty.", nameof(source));
            }
            if (string.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("Destination cannot be null or empty.", nameof(destination));
            }
            if (string.IsNullOrEmpty(videoCodec) && string.IsNullOrEmpty(audioCodec))
            {
                throw new ArgumentException("You must specify at least one video or audio codec.");
            }

            File.Delete(destination);
            StringBuilder Query = new StringBuilder();

            Query.Append("-y -i ");
            if (sourceType == SourceType.Direct)
            {
                Query.Append("\"");
                Query.Append(source);
                Query.Append("\"");
            }
            else
            {
                Query.Append("-"); // Pipe source
            }
            // Add video codec.
            if (string.IsNullOrEmpty(videoCodec))
            {
                Query.Append(" -vn");
            }
            else
            {
                Query.Append($" -vcodec {videoCodec}");
            }
            // Add audio codec.
            if (string.IsNullOrEmpty(audioCodec))
            {
                Query.Append(" -an");
            }
            else
            {
                Query.Append($" -acodec {audioCodec}");
            }

            if (!string.IsNullOrEmpty(encodeArgs))
            {
                Query.Append(" ");
                Query.Append(encodeArgs);
            }

            Query.Append(" \"");
            Query.Append(destination);
            Query.Append("\"");

            // Run FFmpeg with query.
            IProcessWorkerEncoder Worker = factory.CreateEncoder(options, callback);
            CompletionStatus      Result = RunEncoderInternal(source, Query.ToString(), Worker, sourceType, EncoderApp.FFmpeg);

            return(Result);
        }
Example #27
0
        /// <summary>
        /// Gets file streams information of specified file via FFmpeg.
        /// </summary>
        /// <param name="source">The file to get information about.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>A IFFmpegProcess object containing the file information.</returns>
        public IFileInfoFFmpeg GetFileInfo(string source, ProcessOptionsEncoder options = null, ProcessStartedEventHandler callback = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("Source cannot be null or empty.", nameof(source));
            }
            IProcessWorkerEncoder Worker = factory.CreateEncoder(options, callback);

            Worker.ProcessCompleted += (s, e) => {
                if (e.Status == CompletionStatus.Failed && (Worker.FileInfo as IFileInfoFFmpeg)?.FileStreams != null)
                {
                    e.Status = CompletionStatus.Success;
                }
            };
            Worker.RunEncoder($@"-i ""{source}""", EncoderApp.FFmpeg);
            return(Worker.FileInfo as IFileInfoFFmpeg);
        }
        public override IProcessWorkerEncoder CreateEncoder(object owner, ProcessOptionsEncoder options = null, ProcessStartedEventHandler callback = null)
        {
            var result = base.CreateEncoder(owner, options, callback);

            result.ProcessCompleted += (s, e) =>
            {
                if (result.FileInfo is FileInfoFFmpeg info && info.FileStreams == null)
                {
                    // If no data was fed into the process, this will initialize FileStreams.
                    var mockP = Mock.Get <IProcess>(result.WorkProcess);
                    mockP.Raise(x => x.ErrorDataReceived  += null, CreateMockDataReceivedEventArgs(null));
                    mockP.Raise(x => x.OutputDataReceived += null, CreateMockDataReceivedEventArgs(null));
                    if (info.FileStreams != null)
                    {
                        info.FileStreams.Add(new MediaVideoStreamInfo());
                        info.FileStreams.Add(new MediaAudioStreamInfo());
                    }
                }
            };
            Instances.Add(result);
            return(result);
        }
Example #29
0
        /// <summary>
        /// Returns the exact frame count of specified video file.
        /// </summary>
        /// <param name="source">The file to get information about.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The number of frames in the video.</returns>
        public long GetFrameCount(string source, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("Source cannot be null or empty.", nameof(source));
            }
            long Result = 0;
            IProcessManagerFFmpeg Worker = factory.CreateFFmpeg(options, callback);

            Worker.StatusUpdated += (sender, e) => {
                Result = e.Status.Frame;
            };
            Worker.RunFFmpeg(string.Format(@"-i ""{0}"" -f null /dev/null", source));
            return(Result);
        }
Example #30
0
        /// <summary>
        /// Merges specified audio and video files.
        /// </summary>
        /// <param name="videoFile">The file containing the video.</param>
        /// <param name="audioFile">The file containing the audio.</param>
        /// <param name="destination">The destination file.</param>
        /// <param name="options">The options for starting the process.</param>
        /// <param name="callback">A method that will be called after the process has been started.</param>
        /// <returns>The process completion status.</returns>
        public CompletionStatus Muxe(string videoFile, string audioFile, string destination, ProcessOptionsFFmpeg options = null, ProcessStartedEventHandler callback = null)
        {
            if (string.IsNullOrEmpty(videoFile) && string.IsNullOrEmpty(audioFile))
            {
                throw new ArgumentException("You must specifiy either videoFile or audioFile.", nameof(videoFile));
            }
            if (string.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("Destination cannot be null or empty.", nameof(destination));
            }

            List <FFmpegStream> InputStreamList = new List <FFmpegStream>();
            FFmpegStream        InputStream;

            if (!string.IsNullOrEmpty(videoFile))
            {
                InputStream = GetStreamInfo(videoFile, FFmpegStreamType.Video, options);
                if (InputStream != null)
                {
                    InputStreamList.Add(InputStream);
                }
            }
            if (!string.IsNullOrEmpty(audioFile))
            {
                InputStream = GetStreamInfo(audioFile, FFmpegStreamType.Audio, options);
                if (InputStream != null)
                {
                    InputStreamList.Add(InputStream);
                }
            }

            if (InputStreamList.Any())
            {
                return(Muxe(InputStreamList, destination, options, callback));
            }
            else
            {
                return(CompletionStatus.Failed);
            }
        }