文章2:
最近完成了這個小Demo,來分享一下!
上面給了我兩天時間,來完成這個小功能
于時我花了半天時間從網絡上到處鄱資料,又花了半天時間調試代碼,成功之后,終于有了以下一點的經驗之談:
這里講一下重要的:
1.用到兩個工具,一個是ffmpeg.exe,另一個是mencoder.exe
ffmpeg最新版本的下載地址:http://ffdshow.faireal.net/mirror/ffmpeg/
Mencoder新版本的下載地址:http://www5.mplayerhq.hu/MPlayer/releases/win32/
這里有一個重點,網上的文章都沒講到,所以造成有些人運行后沒反應,原因是上面路徑的下載,有很多版本,不同的版本可能個別參數不同,而網上的文章所用的參數都是用很早的版本寫的,所以會造成運行后因參數錯誤而沒有效果
簡單處理是:把網上參數在cmd命令行執行一下,這時命令行會報哪個參數錯誤,把它刪了即可!
2.判斷處理成功與失敗或是進度是否完成,從異步獲取的輸出信息判斷[包括獲取原視頻的寬與高]
這里重點在兩個委托事件中,詳情見以下幾行代碼
-
private void StartProcess(string tool)
-
{
-
StartProcess(tool, false);
-
}
-
private void StartProcess(string tool,bool onlyCheckInfo)
-
{
-
System.Diagnostics.Process p = new System.Diagnostics.Process();
-
p.StartInfo.FileName = tool;
-
p.StartInfo.Arguments = commandPara;
-
p.StartInfo.UseShellExecute = false;
-
p.StartInfo.RedirectStandardInput = true;
-
p.StartInfo.RedirectStandardOutput = true;
-
p.StartInfo.RedirectStandardError = true;
-
p.StartInfo.CreateNoWindow = false;
-
p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_OutputDataReceived);
-
if (onlyCheckInfo)
-
{
-
p.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_CheckInfoDataReceived);
-
}
-
else
-
{
-
p.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_ErrorDataReceived);
-
}
-
-
try
-
{
-
p.Start();
-
p.BeginOutputReadLine();
-
p.BeginErrorReadLine();
-
p.WaitForExit();
-
}
-
catch (Exception err)
-
{
-
Console.WriteLine(err.Message);
-
}
-
finally
-
{
-
p.Close();
-
}
-
}
-
void p_CheckInfoDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
-
{
-
if (!string.IsNullOrEmpty(e.Data))
-
{
-
if (e.Data.Contains("Stream") && e.Data.Contains("Video:"))
-
{
-
Match match = Regex.Match(e.Data, @", (\d+)x(\d+)");
-
if (match != null)
-
{
-
videoWidth = match.Groups[1].Value;
-
videoHeight = match.Groups[2].Value;
-
}
-
}
-
else if (e.Data.Contains("could not find codec parameters"))
-
{
-
isCanChangeToFlv = false;
-
Program.SetDataBase(id, 1, count + 1);
-
}
-
}
-
-
}
-
-
void p_ErrorDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
-
{
-
if (!string.IsNullOrEmpty(e.Data))
-
{
-
if (e.Data.Contains("video:") && e.Data.Contains("muxing overhead"))
-
{
-
Program.SetDataBase(id, 2, count + 1);
-
Console.WriteLine("轉換完成");
-
}
-
Console.WriteLine(e.Data);
-
}
-
-
}
-
-
void p_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
-
{
-
if (!string.IsNullOrEmpty(e.Data))
-
{
-
if (e.Data.Contains("Writing index"))
-
{
-
Program.SetDataBase(id, 2, count + 1);
-
Console.WriteLine("轉換完成");
-
}
-
-
-
-
-
Console.WriteLine(e.Data);
-
}
-
}
private void StartProcess(string tool)
{
StartProcess(tool, false);
}
private void StartProcess(string tool,bool onlyCheckInfo)
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = tool;
p.StartInfo.Arguments = commandPara;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = false;
p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_OutputDataReceived);
if (onlyCheckInfo)//只檢測文件是否可轉換與獲到內部寬與高
{
p.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_CheckInfoDataReceived);
}
else
{
p.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_ErrorDataReceived);
}
//開始執行
try
{
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
finally
{
p.Close();
}
}
void p_CheckInfoDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
if (e.Data.Contains("Stream") && e.Data.Contains("Video:"))//設置原視頻窗口大小作為flv視頻的寬與高
{
Match match = Regex.Match(e.Data, @", (\d+)x(\d+)");
if (match != null)
{
videoWidth = match.Groups[1].Value;
videoHeight = match.Groups[2].Value;
}
}
else if (e.Data.Contains("could not find codec parameters"))//ffmpeg轉換失敗
{
isCanChangeToFlv = false;
Program.SetDataBase(id, 1, count + 1);
}
}
}
void p_ErrorDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
if (e.Data.Contains("video:") && e.Data.Contains("muxing overhead"))//ffmpeg轉換完成
{
Program.SetDataBase(id, 2, count + 1);
Console.WriteLine("轉換完成");
}
Console.WriteLine(e.Data);
}
}
void p_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
if (e.Data.Contains("Writing index"))//mencoder轉換完成
{
Program.SetDataBase(id, 2, count + 1);
Console.WriteLine("轉換完成");
}
//else if (e.Data.Contains("Exiting"))//mencoder轉換失敗
//{
// Console.WriteLine("轉換失敗");
//}
Console.WriteLine(e.Data);
}
}
本文只講重點,請結合網絡其它文章與本文即可!
文章3:
Youtube的成功,使得國內的視頻網站如雨后春筍般的冒出來,前不久朋友叫我幫他寫一個將各種視頻格式轉換成flv的程序,這里就將編寫程序遇到困難和獲得的經驗拿出來和大家分享一下。 1、使用引擎:ffmpeg + Mencoder 2、ffmpeg最新版本的下載地址:http://ffdshow.faireal.net/mirror/ffmpeg/ Mencoder新版本的下載地址:http://www5.mplayerhq.hu/MPlayer/releases/win32/ 3、轉換速度比較:總體上ffmpeg轉換的速度快于Mencoder 4、轉換格式要求:rm、rmvb、r
Youtube的成功,使得國內的視頻網站如雨后春筍般的冒出來,前不久朋友叫我幫他寫一個將各種視頻格式轉換成flv的程序,這里就將編寫程序遇到困難和獲得的經驗拿出來和大家分享一下。
1、使用引擎:ffmpeg + Mencoder
2、ffmpeg最新版本的下載地址:http://ffdshow.faireal.net/mirror/ffmpeg/
Mencoder新版本的下載地址:http://www5.mplayerhq.hu/MPlayer/releases/win32/
3、轉換速度比較:總體上ffmpeg轉換的速度快于Mencoder
4、轉換格式要求:rm、rmvb、rt格式的文件只能用Mencoder轉換,出于速度考慮我基本上都用ffmpeg轉換,所以Mencoder能轉換的格式我沒有詳細測試(哪個朋友知道,麻煩你告訴我下,我補充上去)。
5、純音頻格式只能用Mencoder進行轉換。如何判斷是否是純音頻格式可以通過使用命令 FFmpeg -i "文件的完整路徑" 獲得輸出后就可以分析出來。
6、.mov格式的用ffmpeg轉換出來的效果比較差,建議用Mencoder進行轉換,wmv8用ffmpeg經常會有花屏產生建議用Mencoder。
7、視頻按比率輸出的問題:必須先獲取源視頻文件的寬度和高度(也是通過 FFmpeg -i "文件的完整路徑" 獲得輸出后就可以分析出來)根據這個高度和寬度的比率來設定輸出文件的尺寸。
8、可能的難點:因為這ffmpeg 和 Mencoder都是命令行工具(當然你也可以下載源代碼自己修改成com之類的),在C#只能用Process調用,前面我提過要獲得輸出信息(獲取視頻相關信息、獲取當前的轉換進度、獲取什么時候完成轉換),必須設置process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true;然后必須通過異步編程的方式獲取Process.StandardOutput和Process.StandardError的值,相關說明可以見(ms-help://MS.MSDNQTR.2003FEB.2052/cpref/html /frlrfSystemDiagnosticsProcessClassStandardOutputTopic.htm)(必須安裝了msdn的才能看)。
本文旨在幫助大家少走一些彎路,并不提供實際的解決方案及相關的源碼下載。