C#使用ffmpeg分割视频文件

时间:2024-03-19 22:16:29

使用ffmpeg分割视频文件

环境:ffmpeg&.NET4.0
效果如下:

C#使用ffmpeg分割视频文件
C#使用ffmpeg分割视频文件
代码如下:

**

    **using System;
    using System.Diagnostics;
    using System.IO;
    using static System.Console;
    namespace VideoSpilt
    {
        class DivideVideoIntoPart
        {
            private static int Threads; //线程数
            private static string InputFile;//要切割的视频文件
            private static string OutputRuler;//输出文件名
            private static int TotalTime;//文件总时长(单位s)
            private static int SpiltTime;//?时间切割一次(单位s)
            private static bool IsFailed = false; //失败标识
            private static object obj = new object();//线程锁
            private static int SpiltedTime = 0;//已切割时间
            private static int SpiltedFileCount = 0;//已切割文件数量
            public DivideVideoIntoPart()
            {
            }
            static void Main(string[] Args)
            {
                Title = "分割媒体文件";
                while (true)
                {
                    while (true)
                    {
                        try
                        {
                            while (true) {
                                try
                                {
                                    ExWrite("调用线程数(默认填1):");
                                    Threads = int.Parse(ReadLine());
                                    break;
                                }
                                catch { ExWriteLine("线程数值解析失败,请重新输入", ConsoleColor.Red); }
                            }
                            while (true)
                            {
                                try
                                {
                                    ExWrite("要分割的视频文件(全名,带路径):");
                                    InputFile = ReadLine();
                                    if (!File.Exists(InputFile)) { ExWriteLine("文件不存在,请重新输入", ConsoleColor.Red);}
                                    else { break; }
                                }
                                catch { ExWriteLine("文件位置解析失败,请重新输入",ConsoleColor.Red); }
                            }
                            ExWrite("输出文件的文件名(全名,带路径):");
                            OutputRuler = ReadLine();
                            while (true)
                            {
                                try
                                {
                                    ExWrite("视频总时长(单位:s):");
                                    TotalTime = Convert.ToInt32(ReadLine());
                                    break;
                                }
                                catch
                                {
                                    ExWriteLine("线程数值解析失败,请重新输入", ConsoleColor.Red);
                                }  
                            }
                            while(true)
                            {
                                try
                                {
                                    ExWrite("每次截取时长:");
                                    SpiltTime = Convert.ToInt32(ReadLine());
                                    if (SpiltTime > TotalTime) { ExWriteLine("每次切割的时长不能大于总时长",ConsoleColor.Red); continue; }
                                    else { break; }
                                }
                                catch
                                {
                                    ExWriteLine("时长解析失败,请重新输入",ConsoleColor.Red);
                                }
                            }
                            ExWriteLine("waitForProcess...",ConsoleColor.Yellow);
                            while (SpiltedTime < TotalTime)//开始切割
                            {
                                BeginSpilt();
                                SpiltedTime += SpiltTime;
                                SpiltedFileCount += 1;
                            }
                            if (SpiltedTime != TotalTime)
                            { //最后,当总时间÷已切割时间结果有余数时 则最后一段切割的时间是余数
                                SpiltTime = TotalTime - SpiltedTime;
                                BeginSpilt();
                            }
                            for (int i = 0; i < SpiltedFileCount; i++) //判断文件是否全部切割成功 若未成功则删除已分割的部分
                            {
                                if (File.Exists(OutputRuler.Substring(0, OutputRuler.LastIndexOf(".")) + $"-part{i}" + OutputRuler.Substring(OutputRuler.LastIndexOf(".")))&&new FileInfo(OutputRuler.Substring(0, OutputRuler.LastIndexOf(".")) + $"-part{i}" + OutputRuler.Substring(OutputRuler.LastIndexOf("."))).Length > 0) {
                                    ExWriteLine($"Task {i} 从{InputFile}中截取成功", ConsoleColor.Blue);
                                }
                                else { ExWriteLine($"Task {i} 从{InputFile}中截取失败", ConsoleColor.Red); ExWriteLine("尽量保证文件路径不含中文,成功率会提高", ConsoleColor.Red); DelFile(); break; }
                            }
                            if(!IsFailed)
                            {
                                ExWriteLine($"已将 {InputFile} 分割为{SpiltedFileCount}份",ConsoleColor.Green);
                            }
                            break;
                        }
                        catch(Exception ex) { ExWriteLine(ex.Message,ConsoleColor.Red); break; }
                    }
                    IsFailed = false;
                    SpiltedFileCount = 0;
                    SpiltedTime = 0;
                }
            }
            private static void DelFile()//删除已分割的视频文件
            {
                IsFailed = true;
                for (int i = 0; i < SpiltedFileCount; i++)
                {
                    try { File.Delete($"{OutputRuler.Substring(0, OutputRuler.LastIndexOf("."))}-part{i}{OutputRuler.Substring(OutputRuler.LastIndexOf("."))}"); } catch { continue; }
                }
            }
            static Process p; //Process组件
            private static void BeginSpilt()//开始切割
            {
                p = new Process();
                p.StartInfo.FileName = "ffmpeg.exe";
                p.StartInfo.Arguments = $"-threads {Threads} -ss {SpiltedTime.ToString()} -i \"{InputFile}\" -c copy -t {SpiltTime} \"{OutputRuler.Substring(0, OutputRuler.LastIndexOf("."))}-part{SpiltedFileCount}{OutputRuler.Substring(OutputRuler.LastIndexOf("."))}\" ".Trim();
                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.OutputDataReceived += Output;
                p.ErrorDataReceived += Output;
                p.Start();
                p.Exited += P_Exited;
                p.StandardInput.AutoFlush = true;
                p.BeginOutputReadLine();
                p.BeginErrorReadLine();
                p.WaitForExit();
            }
            private static void P_Exited(object sender, EventArgs e)
            {
                ExWriteLine($"Task {SpiltedFileCount} is Completed",ConsoleColor.Yellow);
            }
            protected static void Output(object sender, DataReceivedEventArgs e)
            {
                if (!string.IsNullOrEmpty(e.Data))
                {
                    ExWriteLine(e.Data);
                }
            }
            private static void ExWriteLine(string str,ConsoleColor cs = ConsoleColor.White)
            {
                lock(obj)
                {
                    ForegroundColor = cs;
                    Console.WriteLine(str);
                    ResetColor();
                }
            }
            private static void ExWrite(string str, ConsoleColor cs = ConsoleColor.White)
            {
                lock (obj)
                {
                    ForegroundColor = cs;
                    Console.Write(str);
                    ResetColor();
                }
            }
        }
    }**

**