环境准备:.net core 2.1+.net standard 2.0
一、实现效果
二、步骤
1、下载ffmpeg.exe并放入项目中(具体下载方法可百度,本文重点讲解如何使用)
2、将需要的信息写入配置文件中(源文件路径、转换规则)
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"ConvertParam": {
"MaxWidth": 1280,
"MaxHeight": 720,
"OutputWidth": 1280,
"OutputHeight": 720,
"SourceFPS": 50,
"OutputFPS": 50,
"NeedConvertType": "MOV,AVI",
"ConvertType": "MP4",
"CornString": "*/5 * * * * ?", //"0 0 1 * * ?", //excute 1:00 AM everyday
"SourcePath": "C:\\Users\\fishliu\\Videos",
"OutputPath": "C:\\Users\\fishliu\\Desktop\\New_folder\\video"
},
"AllowedHosts": "*"
}
3、新增媒体模型
namespace ConvertVideoJob.Model
{
public class VideoModel
{
public int FrameWidth { get; set; }
public int FrameHeight { get; set; }
public string Size { get; set; }
public double FrameRate { get; set; }
public VideoType MediaType { get; set; }
public string Path { get; set; }
/// <summary>
/// second
/// </summary>
public double Duration { get; set; }
}
public enum VideoType
{
MP4=1,
MOV=2,
AVI=3,
FLV=4,
WMV=5
}
}
4、核心转换方法
/// <summary>
/// Copy source file, call ffmpeg to convert, copy converted file back, delete temp files.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
string stratConvert(VideoModel model, string sourceDirectory)
{
string fullAppPath = Path.GetFullPath(APP_PATH);
lock (objlock)
{
if (File.Exists(model.Path.Trim()))
{
// Copy file to temp directory
string sourceFileName = Path.GetFileName(model.Path);
string tempIn = string.Format(@"{0}\{1}", _tempPath, sourceFileName);
File.Copy(model.Path, tempIn, true);
string destinationFileName = Path.GetFileNameWithoutExtension(tempIn);
string tempOut = string.Format(@"{0}\{1}.mp4", _tempPath, destinationFileName);
// Build the command parameters
string[] args = new string[8];
args[0] = string.Format("-i \"{0}\"", tempIn);
//args[1] = string.Format("-ss {0}", startTime); // starting at hh:mm:ss[.xxx]
//args[2] = string.Format("-t {0}", duration); // limit duration to hh:mm:ss[.xxx]
args[1] = "-r " + model.FrameRate;
args[2] = "-s " + model.FrameWidth + "*" + model.FrameHeight;
args[3] = "-ac 1";
args[4] = "-ar 11025";
args[5] = "-y"; // Force override
args[6] = "-hide_banner"; // Hide unrequired output
args[7] = string.Format("\"{0}\"", tempOut);
// Call ffmpeg to convert file
CallConsoleAppAsync(fullAppPath, args);
// Copy converted file back to origin (append "(x)" if already existing)
string destinationPath = string.Format(@"{0}\{1}.mp4", sourceDirectory, destinationFileName);
int suffix = 1;
while (File.Exists(destinationPath))
{
destinationPath = string.Format(@"{0}\{1}({2}).mp4", sourceDirectory, destinationFileName, suffix);
suffix++;
}
try
{
if (!File.Exists(destinationPath))
File.Copy(tempOut, destinationPath);
}
catch (Exception ex)
{
WriteLog(string.Format("Could not copy temporary file '{0}' to {1}: {2}", tempOut, destinationPath, ex.Message), true, true);
}
finally
{
WriteLog(string.Format("Saved converted file to '{0}'.", destinationPath), true);
}
// Delete temp files if enabled and copying was successful
if (_isCleanUpEnabled)
{
// TempIn
if (_isVerboseLoggingEnabled)
WriteLog(string.Format("Deleting temporary input file '{0}'...", tempIn), true);
try
{
if (File.Exists(tempIn))
File.Delete(tempIn);
}
catch (Exception ex)
{
WriteLog(string.Format("Could not delete temporary input file '{0}': {1}", tempIn, ex.Message), true, true);
}
// TempOut
if (_isVerboseLoggingEnabled)
WriteLog(string.Format("Deleting temporary output file '{0}'...", tempOut), true);
try
{
if (File.Exists(tempOut))
File.Delete(tempOut);
}
catch (Exception ex)
{
WriteLog(string.Format("Could not delete temporary output file '{0}': {1}", tempOut, ex.Message), true);
}
}
return destinationPath;
}
else
{
WriteLog(string.Format("Could not find '{0}'", model.Path), true);
return "sourcePath cant not be null";
}
}
}
//异步转换
void CallConsoleAppAsync(string appPath, string[] args = null)
{
string command = " " + string.Join(" ", args);
if (_isVerboseLoggingEnabled)
WriteLog(string.Format("Parameters: {0}", command),true);
// Create process
Process process = new Process();
process.StartInfo.FileName = appPath;
process.StartInfo.Arguments = command;
// Set UseShellExecute to false to allow redirection
process.StartInfo.UseShellExecute = false;
// Redirect the standard output and error
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
try
{
// Start the process
process.Start();
process.BeginErrorReadLine();
//CallWithTimeout(process.BeginErrorReadLine);//开始异步读取,并设置超时时间
process.WaitForExit();//阻塞等待进程结束
}
catch (Exception ex)
{
WriteLog(ex.Message, true, true);
throw ex;
}
finally
{
process.Close();//关闭进程
process.Dispose();//释放资源
}
}
完整代码可移步:
https://download.csdn.net/download/qq_39628933/11058109