相關技術:
*DirectShow SDK原本放在DirectX SDK裡,但自DirectX 9.0c SDK以後,被移到Windows SDK。
*DirectShow.NET
*GraphEdit(原本放在DirectShow SDK裡的圖形化工具, 可查到DirectShow相關過濾器)
回目錄
原始版本出處:Media files conversion using C#
1.先新增一個C#的Windows Form應用程式的專案, 名稱為 ConvertFile
2.下載DirectShow.NET的檔案解壓後, 將DirectShowLib-2005.dll 複製到專案中, 並加入參考
3.在Form1上用"工具箱"分別拉進
1個OpenFileDialog
1個SaveFileDialog
3個Button
3個Label
*檔案 Form1.Designer.cs
namespace ConvertFile
{
partial class Form1
{
/// <summary>
/// 設計工具所需的變數。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清除任何使用中的資源。
/// </summary>
/// <param name="disposing">如果應該處置 Managed 資源則為 true,否則為 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form 設計工具產生的程式碼
/// <summary>
/// 此為設計工具支援所需的方法 - 請勿使用程式碼編輯器
/// 修改這個方法的內容。
/// </summary>
private void InitializeComponent()
{
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.button3 = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
this.SuspendLayout();
//
// openFileDialog1
//
this.openFileDialog1.FileName = "openFileDialog1";
//
// button1
//
this.button1.Location = new System.Drawing.Point(13, 13);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "來源";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(13, 86);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 1;
this.button2.Text = "目的";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// label1
//
this.label1.Location = new System.Drawing.Point(38, 52);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(790, 12);
this.label1.TabIndex = 2;
this.label1.Text = "label1";
//
// label2
//
this.label2.Location = new System.Drawing.Point(40, 131);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(788, 23);
this.label2.TabIndex = 3;
this.label2.Text = "label2";
//
// button3
//
this.button3.Location = new System.Drawing.Point(13, 195);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(75, 23);
this.button3.TabIndex = 4;
this.button3.Text = "轉檔";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// label3
//
this.label3.Location = new System.Drawing.Point(119, 195);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(709, 23);
this.label3.TabIndex = 5;
this.label3.Text = "label3";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(840, 261);
this.Controls.Add(this.label3);
this.Controls.Add(this.button3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
}
}
*檔案 Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using DirectShowLib;
using System.Runtime.InteropServices.ComTypes;
using System.IO;
namespace ConvertFile
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.label1.Text = "";
this.label2.Text = "";
this.label3.Text = "";
}
const int WM_GRAPHNOTIFY = 0x00008001;
// The main com object
FilterGraph fg = null;
// The graphbuilder interface ref
IGraphBuilder gb = null;
// The mediacontrol interface ref
IMediaControl mc = null;
// The mediaevent interface ref
IMediaEventEx me = null;
private void button1_Click(object sender, EventArgs e)
{
string file = this.label1.Text;
if (File.Exists(file))
{
this.openFileDialog1.FileName = file;
this.openFileDialog1.InitialDirectory = Path.GetFullPath(file);
}
else
{
this.openFileDialog1.InitialDirectory = "c:\\";
}
openFileDialog1.Filter = "All files (*.*)|*.*|Matroska Multimedia files (*.mkv)|*.mkv|Windows Media Vidio files (*.wmv)";
openFileDialog1.FilterIndex = 1;
DialogResult result = this.openFileDialog1.ShowDialog();
if (result == DialogResult.OK) // Test result.
{
this.label1.Text = this.openFileDialog1.FileName;
}
}
private void button2_Click(object sender, EventArgs e)
{
string file = this.label2.Text;
if (File.Exists(file))
{
this.saveFileDialog1.FileName = file;
this.saveFileDialog1.InitialDirectory = Path.GetFullPath(file);
}
else
{
this.saveFileDialog1.InitialDirectory = "c:\\";
}
saveFileDialog1.Filter = "All files (*.*)|*.*|Matroska Multimedia files (*.mkv)|*.mkv|Windows Media Vidio files (*.wmv)";
saveFileDialog1.FilterIndex = 1;
DialogResult result = this.saveFileDialog1.ShowDialog();
if (result == DialogResult.OK) // Test result.
{
this.label2.Text = this.saveFileDialog1.FileName;
}
}
private void button3_Click(object sender, EventArgs e)
{
string src = this.label1.Text;
string dest = this.label2.Text;
if (File.Exists(src) == false)
{
MessageBox.Show("來源的檔案不存在, 無須轉換");
return;
}
if (Path.GetExtension(src).ToLower() == Path.GetExtension(dest).ToLower())
{
MessageBox.Show("來源與目的的副檔名一樣, 無須轉換");
return;
}
if (src.ToLower() == dest.ToLower())
{
MessageBox.Show("來源與目的的檔名一樣, 無須轉換");
return;
}
try
{
button3.Enabled = false;
// The main com object
fg = new FilterGraph();
// The graphbuilder interface ref
gb = (IGraphBuilder)fg;
// The mediacontrol interface ref
mc = (IMediaControl)fg;
// The mediaevent interface ref
me = (IMediaEventEx)fg;
int hr = 0;
hr = me.SetNotifyWindow(this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
switch (Path.GetExtension(dest).ToLower())
{
case ".mkv":
{
// we want to add a filewriter filter to the filter graph
FileWriter file_writer = new FileWriter();
// make sure we access the IFileSinkFilter interface to
// set the file name
IFileSinkFilter fs = (IFileSinkFilter)file_writer;
fs.SetFileName(dest, null);
DsError.ThrowExceptionForHR(hr);
// add the filter to the graph
hr = gb.AddFilter((IBaseFilter)file_writer, "File Writer");
DsError.ThrowExceptionForHR(hr);
// create an instance of the matroska multiplex filter and add it
// Matroska Mux Clsid = {1E1299A2-9D42-4F12-8791-D79E376F4143}
Guid guid = new Guid("1E1299A2-9D42-4F12-8791-D79E376F4143");
Type comtype = Type.GetTypeFromCLSID(guid);
IBaseFilter matroska_mux = (IBaseFilter)Activator.CreateInstance(comtype);
hr = gb.AddFilter((IBaseFilter)matroska_mux, "Matroska Muxer");
DsError.ThrowExceptionForHR(hr);
// use Intelligent connect to build the rest of the graph
hr = gb.RenderFile(src, null);
DsError.ThrowExceptionForHR(hr);
// we are ready to convert
hr = mc.Run();
DsError.ThrowExceptionForHR(hr);
}
break;
case ".wmv":
{
// here we use the asf writer to create wmv files
WMAsfWriter asf_filter = new WMAsfWriter();
IFileSinkFilter fs = (IFileSinkFilter)asf_filter;
hr = fs.SetFileName(dest, null);
DsError.ThrowExceptionForHR(hr);
hr = gb.AddFilter((IBaseFilter)asf_filter, "WM Asf Writer");
DsError.ThrowExceptionForHR(hr);
hr = gb.RenderFile(src, null);
DsError.ThrowExceptionForHR(hr);
hr = mc.Run();
DsError.ThrowExceptionForHR(hr);
}
break;
default:
MessageBox.Show("未能處理的檔案格式, 轉換工具待修正");
break;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_GRAPHNOTIFY)
{
IntPtr p1, p2;
EventCode code;
if (me == null)
return;
while (me.GetEvent(out code, out p1, out p2, 0) == 0)
{
if (code == EventCode.Complete)
{
//label1.Text = "done";
button3.Enabled = true;
mc.Stop();
}
me.FreeEventParams(code, p1, p2);
}
return;
}
base.WndProc(ref m);
}
}
}
4.最後, 建置 ConvertFile, 就這樣了