类似这样的客户端,
第一个框是输入压缩视频的路径的,可以多选,
第二个框是输出压缩视频路径的,只可以选一个
第三个框是进度条
最后一个框是点击立即压缩
首先 限制文件格式 ,只允许是视频格式的可以被选择
private void create_video_list()
{
video_list.Add(".MP4");
video_list.Add(".mp4");
video_list.Add(".MOV");
video_list.Add(".mov");
video_list.Add(".AVI");
video_list.Add(".avi");
video_list.Add(".MPEG");
video_list.Add(".mpeg");
video_list.Add(".WMV");
video_list.Add(".wmv");
video_list.Add(".3GP");
video_list.Add(".3gp");
}
通过video_list.Contains(Path.GetExtension(path)) 判断是否是视频的格式
另外 由于太小的文件没有压缩的必要,所以直接忽略掉,设置20M以下的文件不允许被选中
通过函数
public static long FileSize(string filePath)//判断文件大小
{
//定义一个FileInfo对象,是指与filePath所指向的文件相关联,以获取其大小
FileInfo fileInfo = new FileInfo(filePath);
return fileInfo.Length;
}
来判断文件大小
然后可以通过拖动文件来加入文件路径
private void Form1_DragEnter(object sender, DragEventArgs e)//拖拽加入文件
{
string allIntputPath = "";
//获取拖放数据
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] content = (string[])e.Data.GetData(DataFormats.FileDrop);
for (int i = 0; i < content.Length; i++)
{
//这是全路径
if (is_videos(content[i].ToString())) {
allIntputPath = content[i].ToString() + "\r\n";
inputList.Add(content[i].ToString() + "\r\n");
}
}
changeText(allIntputPath);
}
}
通过点击按钮来选择压迫压缩的文件路径
private void SelectFolder_Click(object sender, EventArgs e)//点击选择视频获取路径
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Multiselect = true;//该值确定是否可以选择多个文件
dialog.Title = "请选择文件夹";
dialog.Filter = "所有文件(*.*)|*.*";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string allIntputPath = "";
string[] strNames = dialog.FileNames;
for (int i = 0; i < strNames.Length; i++)
{
if (is_videos(strNames[i].ToString()))
{
allIntputPath = strNames[i].ToString() + "\r\n";
inputList.Add(strNames[i].ToString() + "\r\n");
}
}
changeText(allIntputPath);
}
}
然后使用线程来进行执行压缩动作
Thread t = new Thread(ZipVideos);
t.IsBackground = true;//把前台线程,设置为后台线程,随着应用程序,不必等线程结束即会被终止。
t.Start();
public void ZipVideos()
{
successCount = 0;
if (isVideoIsEmpty)
{
string[] striparr = this.skinTextBox1.Text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
foreach (String ph in striparr)
{
if (ph.Length > 1)
{
zippath = System.IO.Path.GetFileName(ph);
try
{
this.SelectFolder.Enabled = false;
this.SaveFolderPath.Enabled = false;
this.MakeVideo.Enabled = false;
ConvertVideo(ph);
}
catch (System.Exception ex)
{
LogHelper.WriteLog(ex.ToString());
}
}
Thread.Sleep(1000);
}
}
}
然后通过
public void ConvertVideo(String inputpath)//压缩视频
{
now_path = inputpath;
isVideoIsEmpty = false;
string filename = System.IO.Path.GetFileName(inputpath);
string outputpath = VideoOutPath + "\\zip" + filename;
string sPath = Environment.GetEnvironmentVariable("ffmpeg");
string new_fps = "25";
string ffmpegpath = @"ffmpeg.exe";
LogHelper.WriteLog(ffmpegpath);
altime=GetVideoDuration(ffmpegpath, inputpath);
int intbitr = 0;
int.TryParse(allbitrate, out intbitr);
string bitcount = (intbitr / 3).ToString() + "k";
LogHelper.WriteLog(altime+"@"+bitcount + "@" + allbitrate);
string cmd1 = "";
if (new_resolution.Length < 1)
{
cmd1 = "-i " + inputpath + " -r " + new_fps + " -threads 2" + " -y " + outputpath + "";
}
if (allbitrate.Length < 1)
{
cmd1 = "-i " + inputpath + " -r " + new_fps + " -threads 2" + " -y " + outputpath + "";
}
if (allbitrate.Length > 2 && new_resolution.Length > 2)
{
cmd1 = "-i " + inputpath + " -b " + bitcount + " -s " + new_resolution + " -r " + new_fps + " -threads 2" + " -y " + outputpath + "";
}
LogHelper.WriteLog("@---------------");
LogHelper.WriteLog(cmd1);
LogHelper.WriteLog("@---------------");
Process p = new Process();//建立外部调用线程
p.StartInfo.FileName = ffmpegpath;//要调用外部程序的绝对路径
p.StartInfo.Arguments = cmd1;//参数(这里就是FFMPEG的参数了)
p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)
p.StartInfo.CreateNoWindow = true;//不创建进程窗口
p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
p.Start();//启动线程
p.BeginErrorReadLine();//开始异步读取
p.WaitForExit();//阻塞等待进程结束
p.Close();//关闭进程
p.Dispose();//释放资源
}
来进行压缩视频
全部代码如下
using CCWin;
using log4net;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CompaessVideo
{
public partial class ZipVideo : CCSkinMain
{
public ZipVideo()
{
InitializeComponent();
}
readonly static object _locker = new object();
string VideoInutPath = "";
string VideoOutPath = "";
string new_resolution = "";
string allbitrate = "";
Boolean isVideoIsEmpty = true;
Queue<string> videoQueue = new Queue<string>();
string zippath = "";
int successCount = 0;
ArrayList inputList = new ArrayList();
ArrayList video_list = new ArrayList();
int altime = 0;
string now_path = "";
private void ZipVideo_Load(object sender, EventArgs e)//进来项目的初始化函数
{
LogHelper.WriteLog("记录日志");
this.AllowDrop = true;
this.skinTextBox1.SkinTxt.Leave += skinLabel1Change;
create_video_list();
}
private void skinLabel1Change(object sender, EventArgs e) {//再输入框输入路径的时候
inputList.Clear();
string[] striparr = this.skinTextBox1.Text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
System.Text.RegularExpressions.Regex regex =new System.Text.RegularExpressions.Regex(@"^[a-zA-Z]:((\\+[^\/:*?""<>|]+)+)\s*$");
foreach (String ph in striparr)
{
if (System.IO.File.Exists(ph)) {
if (is_videos(ph))
{
inputList.Add(ph + "\r\n");
}
}
}
}
private void create_video_list()
{
video_list.Add(".MP4");
video_list.Add(".mp4");
video_list.Add(".MOV");
video_list.Add(".mov");
video_list.Add(".AVI");
video_list.Add(".avi");
video_list.Add(".MPEG");
video_list.Add(".mpeg");
video_list.Add(".WMV");
video_list.Add(".wmv");
video_list.Add(".3GP");
video_list.Add(".3gp");
}
private Boolean is_videos(string filePath) { //判断是否是视频文件 以及判断是否大于20m
string path = filePath.Replace("\r\n", "");
long filesize = FileSize(filePath);
long sizem=filesize / 1048576;
if (path.Length > 1)
{
//Path.GetExtension(filePath).ToString()
if (video_list.Contains(Path.GetExtension(path)))
{
if (sizem > 20)
{
return true;
}
else {
MessageBox.Show("请勿添加小于20M视频");
return false;
}
}
else
{
MessageBox.Show("请勿添加非视频文件");
return false;
}
}
else
{
return false;
}
}
public static long FileSize(string filePath)//判断文件大小
{
//定义一个FileInfo对象,是指与filePath所指向的文件相关联,以获取其大小
FileInfo fileInfo = new FileInfo(filePath);
return fileInfo.Length;
}
private void Form1_DragEnter(object sender, DragEventArgs e)//拖拽加入文件
{
string allIntputPath = "";
//获取拖放数据
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] content = (string[])e.Data.GetData(DataFormats.FileDrop);
for (int i = 0; i < content.Length; i++)
{
//这是全路径
if (is_videos(content[i].ToString())) {
allIntputPath = content[i].ToString() + "\r\n";
inputList.Add(content[i].ToString() + "\r\n");
}
}
changeText(allIntputPath);
}
}
private void changeText(String inputDictory)//把文件名称放到框里
{
if (inputDictory.Length > 1) {
this.skinTextBox1.Text = "";
if (!this.skinTextBox2.Text.Contains("\\"))
{
string folder = System.IO.Path.GetDirectoryName(inputDictory.Replace("\r\n", ""));
VideoOutPath = @folder;
this.skinTextBox2.Text = VideoOutPath;
}
if (inputList.Count > 0)
{
foreach (String pt in inputList)
{
this.skinTextBox1.Text += pt;
}
}
}
}
private void SelectFolder_Click(object sender, EventArgs e)//点击选择视频获取路径
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Multiselect = true;//该值确定是否可以选择多个文件
dialog.Title = "请选择文件夹";
dialog.Filter = "所有文件(*.*)|*.*";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string allIntputPath = "";
string[] strNames = dialog.FileNames;
for (int i = 0; i < strNames.Length; i++)
{
if (is_videos(strNames[i].ToString()))
{
allIntputPath = strNames[i].ToString() + "\r\n";
inputList.Add(strNames[i].ToString() + "\r\n");
}
}
changeText(allIntputPath);
}
}
private void SaveFolderPath_Click(object sender, EventArgs e)//点击选择存储视频路径
{
this.skinTextBox2.Text = "";
string[] paths = new string[0];
if (String.IsNullOrEmpty(this.skinTextBox1.Text))
{
MessageBox.Show("请选择获取视频路径");
return;
}
paths = VideoInutPath.Split('\\');
string temp = paths[paths.Length - 1];
System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
dialog.Description = "请选择Txt所在文件夹";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
if (string.IsNullOrEmpty(dialog.SelectedPath))
{
MessageBox.Show(this, "文件夹路径不能为空", "提示");
return;
}
else
{
string filename = dialog.SelectedPath;
string folder = System.IO.Path.GetFullPath(dialog.SelectedPath);
VideoOutPath = @folder;
this.skinTextBox2.Text = VideoOutPath;
}
}
}
private void MakeVideo_Click(object sender, EventArgs e)//点击压缩视频
{
CheckForIllegalCrossThreadCalls = false;
string[] striparr = this.skinTextBox1.Text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
foreach (String ph in striparr)
{
if (ph.Length > 1) {
if (!System.IO.File.Exists(ph))
{
MessageBox.Show("文件格式不正确");
return;
}
}
}
if (String.IsNullOrEmpty(this.skinTextBox1.Text))
{
MessageBox.Show("请选择获取视频路径");
return;
}
if (String.IsNullOrEmpty(this.skinTextBox2.Text))
{
MessageBox.Show("请选择保存视频路径");
return;
}
try
{
Thread t = new Thread(ZipVideos);
t.IsBackground = true;//把前台线程,设置为后台线程,随着应用程序,不必等线程结束即会被终止。
t.Start();
this.SelectFolder.Enabled = false;
this.skinTextBox1.Enabled = false;
this.skinTextBox2.Enabled = false;
this.SaveFolderPath.Enabled = false;
this.MakeVideo.Enabled = false;
}
catch (System.Exception ex)
{
LogHelper.WriteLog(ex.ToString());
}
}
public void ZipVideos()
{
successCount = 0;
if (isVideoIsEmpty)
{
string[] striparr = this.skinTextBox1.Text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
foreach (String ph in striparr)
{
if (ph.Length > 1)
{
zippath = System.IO.Path.GetFileName(ph);
try
{
this.SelectFolder.Enabled = false;
this.SaveFolderPath.Enabled = false;
this.MakeVideo.Enabled = false;
ConvertVideo(ph);
}
catch (System.Exception ex)
{
LogHelper.WriteLog(ex.ToString());
}
}
Thread.Sleep(1000);
}
}
}
public void ZipVideos1()
{
successCount = 0;
string[] striparr = this.skinTextBox1.Text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
foreach (String ph in striparr)
{
if (ph.Length > 1)
{
videoQueue.Enqueue(ph);
}
}
while (true)
{
if (videoQueue.Count != 0)
{
if (isVideoIsEmpty)
{
lock (_locker)
{
String path1 = "";
String path2 = "";
try
{
path1 = videoQueue.Dequeue();
}
catch
{
path1 = "";
}
try
{
path2 = videoQueue.Dequeue();
}
catch
{
path2 = "";
}
String zippath1 = System.IO.Path.GetFileName(path1);
String zippath2 = System.IO.Path.GetFileName(path2);
zippath = zippath1 + "/" + zippath2;
try
{
this.SelectFolder.Enabled = false;
this.SaveFolderPath.Enabled = false;
this.MakeVideo.Enabled = false;
if (path1.Length > 1)
{
Task task1 = new Task(() =>
{
ConvertVideo(path1);
});
task1.Start();
}
if (path2.Length > 1)
{
Task task2 = new Task(() =>
{
ConvertVideo(path2);
});
task2.Start();
}
}
catch (System.Exception ex)
{
LogHelper.WriteLog(ex.ToString());
}
}
}
}
else
{
break;
}
Thread.Sleep(1000);
}
}
public void ConvertVideo(String inputpath)//压缩视频
{
now_path = inputpath;
isVideoIsEmpty = false;
string filename = System.IO.Path.GetFileName(inputpath);
string outputpath = VideoOutPath + "\\zip" + filename;
string sPath = Environment.GetEnvironmentVariable("ffmpeg");
string new_fps = "25";
string ffmpegpath = @"ffmpeg.exe";
LogHelper.WriteLog(ffmpegpath);
altime=GetVideoDuration(ffmpegpath, inputpath);
int intbitr = 0;
int.TryParse(allbitrate, out intbitr);
string bitcount = (intbitr / 3).ToString() + "k";
LogHelper.WriteLog(altime+"@"+bitcount + "@" + allbitrate);
string cmd1 = "";
if (new_resolution.Length < 1)
{
cmd1 = "-i " + inputpath + " -r " + new_fps + " -threads 2" + " -y " + outputpath + "";
}
if (allbitrate.Length < 1)
{
cmd1 = "-i " + inputpath + " -r " + new_fps + " -threads 2" + " -y " + outputpath + "";
}
if (allbitrate.Length > 2 && new_resolution.Length > 2)
{
cmd1 = "-i " + inputpath + " -b " + bitcount + " -s " + new_resolution + " -r " + new_fps + " -threads 2" + " -y " + outputpath + "";
}
LogHelper.WriteLog("@---------------");
LogHelper.WriteLog(cmd1);
LogHelper.WriteLog("@---------------");
Process p = new Process();//建立外部调用线程
p.StartInfo.FileName = ffmpegpath;//要调用外部程序的绝对路径
p.StartInfo.Arguments = cmd1;//参数(这里就是FFMPEG的参数了)
p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)
p.StartInfo.CreateNoWindow = true;//不创建进程窗口
p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
p.Start();//启动线程
p.BeginErrorReadLine();//开始异步读取
p.WaitForExit();//阻塞等待进程结束
p.Close();//关闭进程
p.Dispose();//释放资源
}
private int GetVideoDuration(string ffmpegfile, string sourceFile)//获取视频详细信息
{
try
{
using (System.Diagnostics.Process ffmpeg = new System.Diagnostics.Process())
{
String duration; // soon will hold our video's duration in the form "HH:MM:SS.UU"
String result; // temp variable holding a string representation of our video's duration
StreamReader errorreader; // StringWriter to hold output from ffmpeg
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.StartInfo.FileName = ffmpegfile;
ffmpeg.StartInfo.Arguments = "-i " + sourceFile;
ffmpeg.Start();
errorreader = ffmpeg.StandardError;
ffmpeg.WaitForExit();
result = errorreader.ReadToEnd();
LogHelper.WriteLog("---------------");
LogHelper.WriteLog(result);
LogHelper.WriteLog("---------------");
duration = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length);
string allsizes = result.Substring(result.IndexOf("Video: ") + ("Video: ").Length);
LogHelper.WriteLog(allsizes);
LogHelper.WriteLog(allsizes.Split(',')[0]);
string new_fps = allsizes.Split(',')[4].Split(new string[] { "fps" }, StringSplitOptions.None)[0];
string sizes = allsizes.Split(',')[2].Split('[')[0];
new_resolution = sizes;
string[] birts = result.Substring(result.IndexOf("bitrate: ") + ("bitrate: ").Length).Split(new string[] { "Stream" }, StringSplitOptions.None);
allbitrate = birts[0].ToString().Split(new string[] { "kb" }, StringSplitOptions.None)[0];
string[] ss = duration.Split(':');
int h = int.Parse(ss[0]);
int m = int.Parse(ss[1]);
int s = int.Parse(ss[2]);
return h * 3600 + m * 60 + s;
}
}
catch (System.Exception ex)
{
LogHelper.WriteLog(ex.ToString());
return 60;
}
}
private void Output(object sendProcess, DataReceivedEventArgs output)//打印视频生成过程中详细信息
{
if (!String.IsNullOrEmpty(output.Data))
{
createFileTime(output);
if (output.Data.Contains("headers"))
{
successCount += 1;
isVideoIsEmpty = true;
}
if (output.Data.Contains("No such file"))
{
this.SelectFolder.Enabled = true;
this.SaveFolderPath.Enabled = true;
this.MakeVideo.Enabled = true;
this.skinTextBox1.Text = "";
this.skinTextBox2.Text = "";
MessageBox.Show("找不到此文件,请修改路径");
}
if (inputList.Count == successCount)
{
this.skinTextBox1.Enabled = true;
this.skinTextBox2.Enabled = true;
this.skinTextBox1.Text = "";
this.skinTextBox2.Text = "";
this.SelectFolder.Enabled = true;
this.SaveFolderPath.Enabled = true;
this.MakeVideo.Enabled = true;
now_path = "全部文件";
inputList.Clear();
MessageBox.Show("全部压缩完毕");
}
}
}
private void createFileTime(DataReceivedEventArgs output) {
LogHelper.WriteLog("日志内容" + output.Data);
string outputData = output.Data;
string[] filetimes = outputData.Split(' ');
foreach (string filetime in filetimes) {
if (filetime.Contains("time=")) {
string[] fl_time = filetime.Split('=');
try
{
float tm = 0;
float.TryParse(fl_time[1], out tm);
int program =Convert.ToInt32(((tm/altime)*100));
this.skinLabel1.Text = now_path+"压缩进度:";
skinProgressBar1.Value = program;
}
catch(Exception e){
LogHelper.WriteLog(e.ToString());
}
}
}
}
}
}