コード例 #1
0
        public FfmpegCommandLine ToCommandXfade()
        {
            if (_fileInput == null || _fileInput.Count == 0)
            {
                throw new Exception("No input file. please call function AddFileInput");
            }
            if (_videoDuration < 1)
            {
                throw new Exception("Video duration do not valid. please call function WithVideoDurationInSeconds");
            }
            if (_fadeDuration < 0)
            {
                throw new Exception("Video duration do not valid. please call function WithFadeDurationInSeconds");
            }
            if (string.IsNullOrEmpty(_fileOutput))
            {
                throw new Exception("File video outputdo not valid. please call function WithFileOutput");
            }

            _fileInput = _fileInput.Where(i => i.FullPathFile
                                          .EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) == false).ToList();

            var timeForEachImage = (_videoDuration / _fileInput.Count);

            timeForEachImage = Math.Round(timeForEachImage, 2);

            var fadeDuration = _fadeDuration;

            if (fadeDuration > timeForEachImage)
            {
                fadeDuration = timeForEachImage;
            }
            timeForEachImage = timeForEachImage + fadeDuration;

            List <FfmpegCommandLine> cmdsPrepare = new List <FfmpegCommandLine>();

            #region convert images to videos 1-1
            var fileGifts = _fileInput.Where(i => i.FullPathFile
                                             .EndsWith(".gif", StringComparison.OrdinalIgnoreCase) == true &&
                                             i.FullPathFile
                                             .EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) == false
                                             ).ToList();

            foreach (var gf in fileGifts)
            {
                var fileIn  = gf.FullPathFile.Trim();
                var fileOut = fileIn + ".mp4";

                cmdsPrepare.Add(new FfmpegCommandLine
                {
                    GroupOrder    = gf.Order,
                    FfmpegCommand = BuildCmdForGiftToVideo(fileIn, fileOut, timeForEachImage),
                    FileOutput    = fileOut
                });
            }

            List <FileInput> fileImgs = _fileInput.Where(i => i.FullPathFile
                                                         .EndsWith(".gif", StringComparison.OrdinalIgnoreCase) == false &&
                                                         i.FullPathFile
                                                         .EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) == false
                                                         ).ToList();

            foreach (var imgf in fileImgs)
            {
                var fileIn  = imgf.FullPathFile.Trim();
                var fileOut = fileIn + ".mp4";

                cmdsPrepare.Add(new FfmpegCommandLine
                {
                    GroupOrder    = imgf.Order,
                    FfmpegCommand = BuildCmdForImgToVideo(fileIn, fileOut, timeForEachImage),
                    FileOutput    = fileOut
                });
            }
            #endregion ;

            var groupOrder = 0;

            List <FfmpegCommandLine> listAllSubOrderedCmd = new List <FfmpegCommandLine>();

            #region combine video one by one
            //line by line merger video into one
            groupOrder = groupOrder + 1;

            string latestFileOutputCombined = Path.Combine(_dirOutput, groupOrder + "v" + +0 + "_" + _fileOutputName);
            var    latestTimeVideoDuration  = timeForEachImage;

            var subCmd = BuildFfmpegCommandTransitionXFade(new FileInput
            {
                FullPathFile = cmdsPrepare[0].FileOutput,
                IsVideoOrGif = true
            }, new FileInput
            {
                FullPathFile = cmdsPrepare[1].FileOutput,
                IsVideoOrGif = true
            }
                                                           , latestFileOutputCombined, latestTimeVideoDuration, timeForEachImage, fadeDuration
                                                           , _xfadeImageConst[_rnd.Next(0, _xfadeImageConst.Count - 1)]);

            listAllSubOrderedCmd.Add(new FfmpegCommandLine
            {
                FfmpegCommand = subCmd,
                FileOutput    = latestFileOutputCombined,
                GroupOrder    = groupOrder
            });

            latestTimeVideoDuration = latestTimeVideoDuration + timeForEachImage - fadeDuration;

            for (var i = 2; i < cmdsPrepare.Count; i++)
            {
                var idx = i - 1;
                groupOrder = groupOrder + 1;

                var fileOutput = Path.Combine(_dirOutput, groupOrder + "v" + idx + "_" + _fileOutputName);

                subCmd = BuildFfmpegCommandTransitionXFade(new FileInput
                {
                    FullPathFile = latestFileOutputCombined,
                    IsVideoOrGif = true
                }, new FileInput
                {
                    FullPathFile = cmdsPrepare[i].FileOutput,
                    IsVideoOrGif = true
                }
                                                           , fileOutput, latestTimeVideoDuration, timeForEachImage, fadeDuration
                                                           , _xfadeImageConst[_rnd.Next(0, _xfadeImageConst.Count - 1)]);

                listAllSubOrderedCmd.Add(new FfmpegCommandLine
                {
                    FfmpegCommand = subCmd,
                    FileOutput    = fileOutput,
                    GroupOrder    = groupOrder
                });

                latestFileOutputCombined = fileOutput;
                latestTimeVideoDuration  = latestTimeVideoDuration + timeForEachImage - fadeDuration;
            }

            #endregion

            #region build gif overlay

            if (_fileGifOverlay != null && _fileGifOverlay.Count > 0)
            {
                for (int i = 0; i < _fileGifOverlay.Count; i++)
                {
                    var f = ImageOverlayConfigCal(_fileGifOverlay[i]);

                    groupOrder = groupOrder + 1;

                    var outputFileWithGif = Path.Combine(_dirOutput, groupOrder + "g" + +i + "_" + _fileOutputName);

                    var gifCmd = BuildGiftOverlayCommand(latestFileOutputCombined, outputFileWithGif, f.FullPathFile, f.FromSeconds, f.Duration, f.Scale, f.X, f.Y);

                    listAllSubOrderedCmd.Add(new FfmpegCommandLine
                    {
                        GroupOrder    = groupOrder,
                        FileOutput    = outputFileWithGif,
                        FfmpegCommand = gifCmd,
                    });

                    latestFileOutputCombined = outputFileWithGif;
                }
            }

            #endregion

            #region build image overlay

            if (_fileImageOverlay != null && _fileImageOverlay.Count > 0)
            {
                for (int i = 0; i < _fileImageOverlay.Count; i++)
                {
                    var f = ImageOverlayConfigCal(_fileImageOverlay[i]);

                    groupOrder = groupOrder + 1;

                    var outputFileWithOverlay = Path.Combine(_dirOutput, groupOrder + "oi" + +i + "_" + _fileOutputName);

                    var overlayCmd = BuildImageOverlayCommand(latestFileOutputCombined, outputFileWithOverlay, f.FullPathFile, _videoDuration, f.FromSeconds, f.Duration, f.Scale, f.X, f.Y);

                    listAllSubOrderedCmd.Add(new FfmpegCommandLine
                    {
                        GroupOrder    = groupOrder,
                        FileOutput    = outputFileWithOverlay,
                        FfmpegCommand = overlayCmd,
                    });

                    latestFileOutputCombined = outputFileWithOverlay;
                }
            }

            #endregion

            #region build main command

            string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "window/ffmpeg/bin");

            string ffmpegCmd = Path.Combine(dir, "ffmpeg.exe");

            var fileAudioSilence = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "window/ffmpeg/bin/silence.mp3");
            var fileAudio        = fileAudioSilence;

            if (!string.IsNullOrEmpty(_fileAudio))
            {
                fileAudio = _fileAudio;
            }

            string cmd = $"\"{ffmpegCmd}\" -y -i {latestFileOutputCombined} -t {_videoDuration} -i {fileAudio} -c copy -shortest {_fileOutput}";

            #endregion

            var cmdMain = new FfmpegCommandLine
            {
                CommandsToBeforeConvert = cmdsPrepare,
                GroupOrder        = groupOrder + 1,
                FfmpegCommand     = cmd,
                FileOutput        = _fileOutput,
                CommandsToConvert = listAllSubOrderedCmd
            };

            return(cmdMain);
        }
コード例 #2
0
        public FfmpegConvertedResult Run(FfmpegCommandLine cmd)
        {
            if (cmd.IsValid() == false)
            {
                throw new Exception("Not valid ffmpeg command, because the commandline over 8000 character");
            }

            List <FfmpegConvertedResult> subResult = new List <FfmpegConvertedResult>();

            List <string> tempCmd = new List <string>();

            if (cmd.CommandsToBeforeConvert != null && cmd.CommandsToBeforeConvert.Count > 0)
            {
                cmd.CommandsToBeforeConvert.SplitToRun(3, (itms, idx) =>
                {
                    List <Task <FfmpegConvertedResult> > cmdTask = new List <Task <FfmpegConvertedResult> >();
                    foreach (var itm in itms)
                    {
                        tempCmd.Add(itm.FfmpegCommand);
                        cmdTask.Add(Task <FfmpegCommandLine> .Run(() =>
                        {
                            return(InternalRun(itm.FfmpegCommand, itm.FileOutput));
                        }));
                    }

                    subResult.AddRange(Task.WhenAll(cmdTask).GetAwaiter().GetResult());
                });
            }

            if (cmd.CommandsToConvert != null && cmd.CommandsToConvert.Count > 0)
            {
                //var group = cmd.CommandsToConvert.GroupBy(i => i.GroupOrder).Select(m => new { GroupOrder = m.Key, Cmds = m.DefaultIfEmpty() });
                //foreach (var g in group)
                //{
                //    g.Cmds.ToList().SplitToRun(3, (itms, idx) =>
                //    {
                //        List<Task<FfmpegConvertedResult>> cmdTask = new List<Task<FfmpegConvertedResult>>();
                //        foreach (var itm in itms)
                //        {
                //            tempCmd.Add(itm.FfmpegCommand);
                //            cmdTask.Add(Task<FfmpegCommandLine>.Run(() =>
                //            {
                //                return InternalRun(itm.FfmpegCommand, itm.FileOutput);
                //            }));
                //        }

                //        subResult.AddRange(Task.WhenAll(cmdTask).GetAwaiter().GetResult());
                //    });
                //}
                foreach (var subCmd in cmd.CommandsToConvert)
                {
                    FfmpegConvertedResult cmdSubRes = InternalRun(subCmd.FfmpegCommand, subCmd.FileOutput);
                    cmdSubRes.CommadExecuted = subCmd;
                    subResult.Add(cmdSubRes);
                    tempCmd.Add(subCmd.FfmpegCommand);
                }
            }
            tempCmd.Add(cmd.FfmpegCommand);

            var allcmd = string.Join("\r\n\r\n", tempCmd);

            var mainCmdResult = InternalRun(cmd.FfmpegCommand, cmd.FileOutput);

            mainCmdResult.SubResult = subResult;

            mainCmdResult.CommadExecuted = cmd;

            Task.Run(() =>
            {
                foreach (var subCmd in cmd.CommandsToBeforeConvert)
                {
                    try
                    {
                        File.Delete(subCmd.FileOutput);
                    }
                    catch { }
                }
                foreach (var subCmd in cmd.CommandsToConvert)
                {
                    try
                    {
                        File.Delete(subCmd.FileOutput);
                    }
                    catch { }
                }
            });

            return(mainCmdResult);
        }