예제 #1
0
        public void ReverseVideo(string outputPath, string videoPath)
        {
            if (string.IsNullOrEmpty(outputPath))
            {
                throw new ArgumentNullException(nameof(outputPath));
            }
            if (string.IsNullOrEmpty(videoPath))
            {
                throw new ArgumentNullException(nameof(videoPath));
            }

            if (System.IO.File.Exists(outputPath))
            {
                System.IO.File.Delete(outputPath);
            }

            string audioArg = string.Empty;

            if (MediaFileInfo.FileHasAudio(videoPath))
            {
                audioArg = "-af areverse ";
            }

            FFmpegProcessRunner fpr = new FFmpegProcessRunner();

            fpr.OnDurationMessage += DurationMessageReceived;
            fpr.OnTimeMessage     += TimeMessageReceived;
            totalSteps             = 1;

            currentStep = 1;
            fpr.Run($"-i \"{videoPath}\" -vf reverse {audioArg}\"{outputPath}\"");

            fpr.OnDurationMessage -= DurationMessageReceived;
            fpr.OnTimeMessage     -= TimeMessageReceived;
        }
예제 #2
0
        public void CombineVideos(string outputPath, string videoPath1, string videoPath2, bool combineHorizontally)
        {
            if (string.IsNullOrEmpty(outputPath))
            {
                throw new ArgumentNullException(nameof(outputPath));
            }
            if (string.IsNullOrEmpty(videoPath1))
            {
                throw new ArgumentNullException(nameof(videoPath1));
            }
            if (string.IsNullOrEmpty(videoPath2))
            {
                throw new ArgumentNullException(nameof(videoPath2));
            }

            if (System.IO.File.Exists(outputPath))
            {
                System.IO.File.Delete(outputPath);
            }

            string stackArg = null;

            if (combineHorizontally)
            {
                stackArg = "hstack";
            }
            else
            {
                stackArg = "vstack";
            }

            bool   video1HasAudio = MediaFileInfo.FileHasAudio(videoPath1);
            bool   video2HasAudio = MediaFileInfo.FileHasAudio(videoPath2);
            string args           = null;

            if (video1HasAudio && video2HasAudio)
            {
                args = $"-i \"{videoPath1}\" -i \"{videoPath2}\" -filter_complex \"[0:v][1:v]{stackArg}=inputs=2[v];[0:a][1:a]amerge[a]\" -map \"[v]\" -map \"[a]\" -ac 2 \"{outputPath}\"";
            }
            else if (!video1HasAudio && !video2HasAudio)
            {
                args = $"-i \"{videoPath1}\" -i \"{videoPath2}\" -filter_complex \"[0:v][1:v]{stackArg}=inputs=2[v]\" -map \"[v]\" \"{outputPath}\"";
            }
            else
            {
                throw new NotImplementedException();
            }

            FFmpegProcessRunner fpr = new FFmpegProcessRunner();

            fpr.OnDurationMessage += DurationMessageReceived;
            fpr.OnTimeMessage     += TimeMessageReceived;
            totalSteps             = 1;

            currentStep = 1;
            fpr.Run(args);

            fpr.OnDurationMessage -= DurationMessageReceived;
            fpr.OnTimeMessage     -= TimeMessageReceived;
        }
예제 #3
0
        public void GetScreenshotAtEnd(string outputPath, string videoPath)
        {
            if (string.IsNullOrEmpty(outputPath))
            {
                throw new ArgumentNullException(nameof(outputPath));
            }
            if (string.IsNullOrEmpty(videoPath))
            {
                throw new ArgumentNullException(nameof(videoPath));
            }

            if (System.IO.File.Exists(outputPath))
            {
                System.IO.File.Delete(outputPath);
            }

            MediaFileInfo mediaFileInfo = new MediaFileInfo(videoPath);

            FFmpegProcessRunner fpr = new FFmpegProcessRunner();

            fpr.Run($"-i \"{videoPath}\" -vf \"select='eq(n,{mediaFileInfo.FrameCount - 1})'\" -vframes 1 -q:v 2 \"{outputPath}\"");
        }
예제 #4
0
        public void AdjustVideoSpeed(string outputPath, string videoFilepath, float newPlaybackRate, float newFramerate = 0, bool alsoChangeAudio = false)
        {
            if (string.IsNullOrEmpty(outputPath))
            {
                throw new ArgumentNullException(nameof(outputPath));
            }
            if (string.IsNullOrEmpty(videoFilepath))
            {
                throw new ArgumentNullException(nameof(videoFilepath));
            }

            if (alsoChangeAudio && !MediaFileInfo.FileHasAudio(videoFilepath))
            {
                alsoChangeAudio = false;
            }

            if (alsoChangeAudio)
            {
                if (newPlaybackRate <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(newPlaybackRate));
                }
                if (newPlaybackRate < 0.5f && !(new List <float> {
                    0.25f, 0.125f, 0.0625f, 0.03125f, 0.015625f, 0.0078125f, 0.00390625f
                }).Contains(newPlaybackRate))
                {
                    throw new ArgumentException("Playback rates lower than 0.5 must be: 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, or 0.00390625.");
                }
                if (newPlaybackRate > 2 && !(new List <float> {
                    4, 8, 16, 32, 64, 128, 256
                }).Contains(newPlaybackRate))
                {
                    throw new ArgumentException("Playback rates higher than 2 must be: 4, 8, 16, 32, 64, 128, or 256.");
                }
            }

            if (System.IO.File.Exists(outputPath))
            {
                System.IO.File.Delete(outputPath);
            }

            float setptsVal = 1 / newPlaybackRate;

            string frameRateArg = string.Empty;

            if (newFramerate > 0)
            {
                frameRateArg = $"-r {newFramerate} ";
            }

            string args;

            if (alsoChangeAudio)
            {
                string audioArg;
                if (newPlaybackRate < 0.5f)
                {
                    audioArg = "atempo=0.5";
                    float temp = newPlaybackRate;
                    while (temp < 0.5f)
                    {
                        temp     /= 0.5f;
                        audioArg += ",atempo=0.5";
                    }
                }
                else if (newPlaybackRate > 2)
                {
                    audioArg = "atempo=2.0";
                    float temp = newPlaybackRate;
                    while (temp > 2)
                    {
                        temp     /= 2;
                        audioArg += ",atempo=2.0";
                    }
                }
                else
                {
                    audioArg = $"atempo={newPlaybackRate}";
                }

                args = $"-i \"{videoFilepath}\" {frameRateArg}-filter_complex \"[0:v]setpts={setptsVal}*PTS[v];[0:a]{audioArg}[a]\" -map \"[v]\" -map \"[a]\" \"{outputPath}\"";
            }
            else
            {
                args = $"-i \"{videoFilepath}\" {frameRateArg}-filter:v \"setpts={setptsVal}*PTS\" -an \"{outputPath}\"";
            }

            FFmpegProcessRunner fpr = new FFmpegProcessRunner();

            fpr.OnDurationMessage += DurationMessageReceived;
            fpr.OnTimeMessage     += TimeMessageReceived;
            totalSteps             = 1;

            currentStep = 1;
            fpr.Run(args);

            fpr.OnDurationMessage -= DurationMessageReceived;
            fpr.OnTimeMessage     -= TimeMessageReceived;
        }
예제 #5
0
        public static bool FileHasVideo(MediaFileInfo mfi)
        {
            IReadOnlyList <VideoStreamInfo> videoStreams = mfi.VideoStreams;

            return(videoStreams != null && videoStreams.Count > 0);
        }
예제 #6
0
        public static bool FileHasAudio(MediaFileInfo mfi)
        {
            IReadOnlyList <AudioStreamInfo> audioStreams = mfi.AudioStreams;

            return(audioStreams != null && audioStreams.Count > 0);
        }