代码拉取完成,页面将自动刷新
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FFmpegCutVideo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//剪切视频
private async void BtnCutVideo_Click(object sender, EventArgs e)
{
if (this.txtMin.Text == "" && this.txtSec.Text == ""&&this.txtHour.Text=="")
{
MessageBox.Show("起始时间的小时、分钟和秒不能同时为空。");
return;
}
if (this.txtNewFileName.Text == "") return;
if (!File.Exists(textBoxFileName.Text))
{
MessageBox.Show("文件不存在。请检查一下。");
return;
}
if (File.Exists(txtNewFileName.Text))
{
MessageBox.Show("存在同名文件");
return;
}
//参数
string _ss = " -ss "+ (txtHour.Text == "" ? "00" : txtHour.Text)+":" + (txtMin.Text == "" ? "00" : txtMin.Text) + ":" + (txtSec.Text == "" ? "00" : txtSec.Text);
string _t;
if (string.IsNullOrEmpty(txtHourEnd.Text)&& string.IsNullOrEmpty(txtMinEnd.Text)&& string.IsNullOrEmpty(txtSecEnd.Text))
{
_t = " -t 09:59:59";
}
else
{
_t=" -t "+ (txtHourEnd.Text == "" ? "00" : txtHourEnd.Text)+":" + (txtMinEnd.Text == "" ? "00" : txtMinEnd.Text) + ":" + (txtSecEnd.Text == "" ? "00" : txtSecEnd.Text);
}
string _i = " -accurate_seek -i " + "\"" + this.textBoxFileName.Text + "\""; //在i参数之前加-accurate_seek,据说是能更精准的剪切,试过后,发现并不能.加与不加效果一样。
string _copy = " -vcodec copy -acodec copy "; //-avoid_negative_ts 1。加上后,会影响精准性。它的意义应该是 转变时间戳shift timestamps。
string _destName = txtNewFileName.Text;
string strArguments = _ss + _t + _i + _copy + "\"" + _destName + "\"";
Debug.Print(strArguments);
this.BtnCutVideo.Enabled = false;
await Task.Run(()=>FuncFFmpeg(strArguments));//调用方法
this.BtnCutVideo.Enabled = true;
}
//加载
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;//不必检查跨线程
}
//将文件拖动到窗口,获得文件的全路径。
private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.All;
else
e.Effect = DragDropEffects.None;
}
//获得路径
private void Form1_DragDrop(object sender, DragEventArgs e)
{
string path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
textBoxFileName.Text = path;
txtNewFileName.Text = SetNewFileName(path);
this.txtHour.Text = this.txtMin.Text = this.txtSec.Text = this.txtHourEnd.Text = this.txtMinEnd.Text = this.txtSecEnd.Text = "";
}
//选择另外的路径,避免在原文件夹内导致重名问题。
private void BtnSelectOtherPath_Click(object sender, EventArgs e)
{
if (File.Exists(textBoxFileName.Text))
{
string fileRootPath = Path.GetPathRoot(textBoxFileName.Text);//获取文件的根路径。
string fileName= Path.GetFileName(textBoxFileName.Text);
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog
{
Description = "请选择要保存的文件路径:",
SelectedPath = fileRootPath //设置初始定位
};
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
txtNewFileName.Text = folderBrowserDialog.SelectedPath+"\\"+fileName;
}
}
}
//调整视频比例
private void BtnChangeRate_Click(object sender, EventArgs e)
{
if (this.comboBoxRatio.Text == "") return;
if (this.txtNewFileName.Text == "") return;
if (!File.Exists(textBoxFileName.Text))
{
MessageBox.Show("文件不存在。请检查一下。");
return;
}
if (File.Exists(txtNewFileName.Text))
{
MessageBox.Show("存在同名文件");
return;
}
//参数:.\ffmpeg -i 松松.mp4 -vcodec copy -acodec copy -aspect 16:9 松松-out.mp4
//-aspect 调整视频播放的纵横比:屏幕比例
//用-s参数设置视频分辨率,参数值wxh,w宽度单位是像素,h高度单位是像素
string _i = " -i " + "\"" + this.textBoxFileName.Text + "\"";
string _aspect = " -vcodec copy -acodec copy -aspect ";
string _s = " -vf scale=";
string _ratio = this.comboBoxRatio.Text;
string _destName = " \"" + txtNewFileName.Text + "\"";
//根据是否有X来判断,操作是调整播放纵横比还是视频的分辨率。
string strArguments;
if (this.comboBoxRatio.Text.ToLower().Contains("x"))
{
strArguments = _i + _s + _ratio + _destName;
}
else
{
strArguments = _i + _aspect + _ratio + _destName;
}
Debug.Print(strArguments);
this.BtnChangeRate.Enabled = false;
FuncFFmpeg(strArguments);//调用方法
this.BtnChangeRate.Enabled = true;
}
//选择文件
private void BtnSelectFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog
{
Title = "请选择要处理的视频文件",
Filter = "视频文件|*.avi;*.mp4;*.mkv;*.mpg;*.mov;*.rmvb;*.ts"
};
ofd.ShowDialog();
if (ofd.FileName == "") return;
this.textBoxFileName.Text = ofd.FileName;
txtNewFileName.Text = SetNewFileName(this.textBoxFileName.Text);
this.txtHour.Text = this.txtMin.Text = this.txtSec.Text = this.txtHourEnd.Text = this.txtMinEnd.Text = this.txtSecEnd.Text = "";
}
private string[] videoNames = null;//准备存多个文件路径的数组
//多选文件
private void BtnSelectFiles_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog
{
Title = "请选择要处理的视频文件",
Multiselect = true,
Filter = "视频文件|*.avi;*.mp4;*.mkv;*.mpg;*.mov;*.rmvb;*.ts;*.wmv"
};
ofd.ShowDialog();
if (ofd.FileName == "") return;
videoNames = ofd.FileNames;//将文件全路径存到数组中。
List<string> videoNamesNullDir=new List<string>();
foreach (string item in videoNames)
{
videoNamesNullDir.Add(Path.GetFileNameWithoutExtension(item));
}
this.textBoxFileMulti.Text = string.Join("|", videoNamesNullDir.ToArray());
txtNewFileName.Text = SetNewFileName(videoNames[0]);
}
//合并多个同类视频
private void BtnConcat_Click(object sender, EventArgs e)
{
if (this.textBoxFileMulti.Text == "") return;
if (this.txtNewFileName.Text == "") return;
if (File.Exists(txtNewFileName.Text))
{
MessageBox.Show("存在同名文件");
return;
}
//先向路径中的file_List.txt文件中,写入要合并视频的路径文件名,然后再调用这个文本文件。
//判断txt文件是否存在。
if (!File.Exists("file_List.txt"))
{
MessageBox.Show("缺少file_List.txt文件。可以新建一个空文件。");
return;
}
//向文本文件中写入数据(覆盖)
using (StreamWriter writer = new StreamWriter("file_List.txt"))
{
foreach (string item in videoNames)
{
writer.WriteLine("file '" + item + "'");
}
}
//参数:.\ffmpeg -f concat -i list.txt -c copy concat.mp4
string _f = " -f concat -safe 0";
string _i = " -i file_List.txt";
string _c = " -c copy";
string _destName = " \"" + txtNewFileName.Text + "\"";
string strArguments = _f + _i + _c + _destName;
Debug.Print(strArguments);
this.BtnConcat.Enabled = false;
FuncFFmpeg(strArguments);//调用方法
this.BtnConcat.Enabled = true;
}
#region 方法组
/// <summary>
/// 方法:调用FFmpeg进行操作视频
/// </summary>
/// <param name="strArguments">传递的参数</param>
private void FuncFFmpeg(string strArguments)
{
Stopwatch watch = new Stopwatch();
watch.Start();
Process p = new Process();
p.StartInfo.FileName = @".\ffmpeg.exe";//FFmpeg的路径
p.StartInfo.Arguments = strArguments;//参数
p.StartInfo.UseShellExecute = false;//是否使用操作系统shell启动,一定要为false
//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的
//这是作者耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;//不显示程序窗口
p.ErrorDataReceived += new DataReceivedEventHandler(Output);
p.Start();//启动线程
p.BeginErrorReadLine();//开始异步读取
p.WaitForExit();//阻塞等待进程结束
p.Close();//关闭进程
p.Dispose();//释放资源
watch.Stop();
TimeSpan time = watch.Elapsed;
MessageBox.Show("完成。共计用时:" + time.TotalSeconds + "秒");
}
/// <summary>
/// 方法:根据原文件名生成新的文件名
/// </summary>
/// <param name="text">原文件名与路径</param>
/// <returns></returns>
private string SetNewFileName(string text)
{
string path = Path.GetDirectoryName(text);
string fileName = Path.GetFileNameWithoutExtension(text);
string extension = Path.GetExtension(text);
if (fileName.ToLower().EndsWith("c"))
{
fileName = fileName.Substring(0, fileName.Length - 1) + "-C-out";
}
else if (fileName.ToLower().EndsWith("ch"))
{
fileName = fileName.Substring(0, fileName.Length - 2) + "-C-out";
}
else
{
fileName += "-out";
}
return path + "\\" + fileName + extension;
}
/// <summary>
/// 方法:FFmpeg输出
/// </summary>
/// <param name="sendProcess"></param>
/// <param name="output"></param>
private void Output(object sendProcess, DataReceivedEventArgs output)
{
if (!String.IsNullOrEmpty(output.Data))
{
this.textBoxResult.Text = output.Data.ToString();
}
}
#endregion
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。