最近在開發mpeg視頻編輯工具,深感老外的mpeg做的好強大,跨平臺都支持,而且目前多個大型視頻軟件都在用人家的東西,老外這方面超前太多了,他們做基礎,我們做應用,雖然是開源的dll庫,哪天說沒就沒了,不囉嗦了,上代碼。主要還是視頻截取,截圖,轉碼等初級的應用,磚家別見笑,你還捨不得開源你的代碼咧。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
namespace WinMediaPlayer
{
class FfmpegHelp
{
public static string FFmpegPath = @".\ffmpeg.exe";
//public static int currentSecond { get; set; }
// public static string videoLengh { get; set; }
public static string videoUrl { get; internal set; }
//public static object newVideo { get; internal set; }
public static double totalSeconds { get; internal set; }
/// <summary>
/// 運行mpeg批處理
/// </summary>
/// <param name="Parameters"></param>
internal static void RunMyProcess(string Parameters)
{
//p.StartInfo.RedirectStandardInput = true; //接受來自調用程序的輸入信息
//p.StartInfo.RedirectStandardOutput = true; //由調用程序獲取輸出信息
//p.StartInfo.RedirectStandardError = true; //重定向標準錯誤輸出
//向cmd窗口寫入命令
//p.StandardInput.WriteLine(cmd);
//p.StandardInput.AutoFlush = true;
var p = new Process();
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = FFmpegPath;
p.StartInfo.Arguments = Parameters;
p.StartInfo.UseShellExecute = false; //是否使用操作系統shell啓動
p.StartInfo.CreateNoWindow = false; //不顯示程序窗口
p.Start();
p.WaitForExit();//等待程序執行完退出進程
p.Close();
}
/// <summary>
/// 截屏
/// </summary>
/// <param name="videoUrlPath"></param>
/// <param name="targetUrl"></param>
/// <param name="currentTime"></param>
internal static void screenShot(string videoUrlPath, string targetUrl, string currentTime)
{
string processPara = string.Format("-ss {2} -i {0} -t 0.01 -f image2 -y {1}", videoUrlPath, targetUrl, currentTime);
RunMyProcess(processPara);
// ffmpeg - i[視頻路徑] - r 1 - q:v 2 - f image2 image-% d.jpeg
//-r:每秒提取的幀數,如上面爲每秒1幀,即一張圖像
//- q:v :圖片質量
//- f:圖片格式,上述爲image2
//image -% d.jpeg:生成圖像的文件名,可以加上完整路徑,% d會使文件名按整數編號,如上述生成圖像爲image - 1.jpeg, image - 2.jpeg, ...
//還有其他參數:
//-t:持續時間,如 - t 4表示持續4s
//- ss:起始時間,如 - ss 01:30:14,從01: 30:14開始
//- vframes:指定抽取的幀數,如 - vframes 120,指定抽取120張
//- s:格式大小,如 - s 640x360
//- y:覆蓋,直接使用
}
/// <summary>
/// 手動截取視頻
/// </summary>
/// <param name="startTime"></param>
/// <param name="videoLen"></param>
/// <param name="targetVodeo"></param>
/// <param name="videoUrl"></param>
internal static void cutVideo(string startTime, int videoLen, string targetVodeo,string videoUrl)
{
string processPara = string.Format("-i {0} -ss " + startTime + " -t " + videoLen + " -codec copy {1} ", videoUrl, targetVodeo); //視頻切割
RunMyProcess(processPara);
}
/// <summary>
/// 創建文件夾
/// </summary>
/// <param name="targetPath"></param>
/// <returns></returns>
internal static string createPath(string targetPath)
{
string targetUrl = System.Environment.CurrentDirectory + @"\";
string targetFolder = targetUrl + DateTime.Now.ToString(targetPath);
if (!File.Exists(targetFolder))
{
Directory.CreateDirectory(targetFolder);
}
return targetFolder;
}
/// <summary>
/// 自動切割視頻
/// </summary>
/// <param name="videoLengh"></param>
/// <param name="videoCount"></param>
/// <param name="targetFolder"></param>
internal static void autoCutVideo(int videoLengh, int videoCount, string targetFolder)
{
string processPara = "";
int currentSecond = 0;
for (int i = 0; i < videoCount; i++)
{
string newVideo = targetFolder + @"\newFile" + i + @".mp4";
processPara += string.Format("-i {0} -ss " + currentSecond + " -t " + videoLengh + " -codec copy {1} ", videoUrl, newVideo); //視頻切割
currentSecond += videoLengh;
// RunMyProcess(processPara);
}
RunMyProcess(processPara);
}
/// <summary>
/// 視頻轉碼
/// </summary>
private void convertCode( string path)
{
Process p = new Process();
p.StartInfo.FileName = path + "ffmpeg.exe";
p.StartInfo.UseShellExecute = false;
string srcFileName = "";
string destFileName = "";
srcFileName = path + "InitVideo1.mp4";
destFileName = path + "InitVideo.mp4";
p.StartInfo.Arguments = "-i " + srcFileName + " -y -vcodec h264 -b 500000 " + destFileName; //執行參數
p.StartInfo.UseShellExecute = false; ////不使用系統外殼程序啓動進程
p.StartInfo.CreateNoWindow = true; //不顯示dos程序窗口
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;//把外部程序錯誤輸出寫到StandardError流中
//p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
//p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
p.StartInfo.UseShellExecute = false;
p.Start();
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.BeginErrorReadLine();//開始異步讀取
p.WaitForExit();//阻塞等待進程結束
p.Close();//關閉進程
p.Dispose();//釋放資源
}
//// 去掉視頻中的音頻
//ffmpeg -i input.mp4 -vcodec copy -an output.mp4
//// -an: 去掉音頻;-vcodec:視頻選項,一般後面加copy表示拷貝
//// 提取視頻中的音頻
//ffmpeg -i input.mp4 -acodec copy -vn output.mp3
//// -vn: 去掉視頻;-acodec: 音頻選項, 一般後面加copy表示拷貝
//// 音視頻合成
//ffmpeg -y –i input.mp4 –i input.mp3 –vcodec copy –acodec copy output.mp4
//// -y 覆蓋輸出文件
////剪切視頻
//ffmpeg -ss 0:1:30 -t 0:0:20 -i input.mp4 -vcodec copy -acodec copy output.mp4
//// -ss 開始時間; -t 持續時間
//// 視頻截圖
//ffmpeg –i test.mp4 –f image2 -t 0.001 -s 320x240 image-%3d.jpg
// -s 設置分辨率; -f 強迫採用格式fmt;
//// 視頻分解爲圖片
//ffmpeg –i test.mp4 –r 1 –f image2 image-%3d.jpg
//// -r 指定截屏頻率
//// 將圖片合成視頻
//ffmpeg -f image2 -i image%d.jpg output.mp4
////視頻拼接
//ffmpeg -f concat -i filelist.txt -c copy output.mp4
//// 將視頻轉爲gif
//ffmpeg -i input.mp4 -ss 0:0:30 -t 10 -s 320x240 -pix_fmt rgb24 output.gif
//// -pix_fmt 指定編碼
//// 將視頻前30幀轉爲gif
//ffmpeg -i input.mp4 -vframes 30 -f gif output.gif
//// 旋轉視頻
//ffmpeg -i input.mp4 -vf rotate = PI / 2 output.mp4
// 縮放視頻
// ffmpeg -i input.mp4 -vf scale = iw / 2:-1 output.mp4
// iw 是輸入的寬度, iw/2就是一半;-1 爲保持寬高比
//視頻變速
// ffmpeg -i input.mp4 -filter:v setpts = 0.5 * PTS output.mp4
//音頻變速
//ffmpeg -i input.mp3 -filter:a atempo = 2.0 output.mp3
//音視頻同時變速,但是音視頻爲互倒關係
//ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4
// 視頻添加水印
// ffmpeg -i input.mp4 -i logo.jpg -filter_complex[0:v][1:v] overlay = main_w - overlay_w - 10:main_h-overlay_h-10[out] -map[out] -map 0:a -codec:a copy output.mp4
// main_w-overlay_w-10 視頻的寬度-水印的寬度-水印邊距;
}
}