iT邦幫忙

DAY 7
0

c#應用系列 第 7

C#應用(7)使用DirectShow.NET做轉檔工具

  • 分享至 

  • xImage
  •  

相關技術:
*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, 就這樣了


上一篇
C#應用(6)加密與解密,以及雜湊值
下一篇
C#應用(8)語音應用
系列文
c#應用13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言