使用ffmpeg分割视频文件
环境:ffmpeg&.NET4.0
效果如下:
代码如下:
**
**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();
}
}
}
}**
**