C#语言编写的基于directshow的音视频格式转换

在运行代码之前需要添加相应的filter,我再次做的是音频转换的格式是MP3,视频转换的格式是flv格式。

需要的filter:dump.ax(音频转换写入流)、lame_dshow.ax(MP3格式编码器encoder)、mmflvmux.ax(flv合成器)、mmx264.ax(h.264视频编码,可以换成其他的编码器,只要改下代码中的编码器名称: string Videoencoder = "MONOGRAM x264 Encoder"; 为你所用名称即可)、mc_enc_aac_ds.ax(aac音频编码,也可以换成其他编码器,也是改下代码中编码器名称:string Audioencoder = "MainConcept AAC Encoder"; )。这些filter网上都可以找到。

欢迎加入C#基于directshow音视频处理技术探讨群:272840645 共同学习进步

public partial class Form1 : Form

     {

    /// <summary>

         /// 必需的设计器变量。

         /// </summary>

         private System.ComponentModel.IContainer components = null;

        /// <summary>

         /// 清理所有正在使用的资源。

         /// </summary>

         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>

         protected override void Dispose(bool disposing)

         {

             if (disposing && (components != null))

             {

                 components.Dispose();

             }

             base.Dispose(disposing);

         }

        #region Windows 窗体设计器生成的代码

        /// <summary>

         /// 设计器支持所需的方法 - 不要

         /// 使用代码编辑器修改此方法的内容。

         /// </summary>

         private void InitializeComponent()

         {

             this.textBox1 = new System.Windows.Forms.TextBox();

             this.textBox2 = new System.Windows.Forms.TextBox();

             this.button1 = new System.Windows.Forms.Button();

             this.SuspendLayout();

             //

             // textBox1

             //

             this.textBox1.Location = new System.Drawing.Point(50, 26);

             this.textBox1.Name = "textBox1";

             this.textBox1.Size = new System.Drawing.Size(237, 21);

             this.textBox1.TabIndex = 0;

             this.textBox1.Click += new System.EventHandler(this.textBox1_Click);

             //

             // textBox2

             //

             this.textBox2.Location = new System.Drawing.Point(50, 70);

             this.textBox2.Name = "textBox2";

             this.textBox2.Size = new System.Drawing.Size(237, 21);

             this.textBox2.TabIndex = 1;

             this.textBox2.Click += new System.EventHandler(this.textBox2_Click);

             //

             // button1

             //

             this.button1.Location = new System.Drawing.Point(212, 124);

             this.button1.Name = "button1";

             this.button1.Size = new System.Drawing.Size(75, 23);

             this.button1.TabIndex = 2;

             this.button1.Text = "button1";

             this.button1.UseVisualStyleBackColor = true;

             this.button1.Click += new System.EventHandler(this.button1_Click);

             //

             // Form1

             //

             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);

             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

             this.ClientSize = new System.Drawing.Size(346, 182);

             this.Controls.Add(this.button1);

             this.Controls.Add(this.textBox2);

             this.Controls.Add(this.textBox1);

             this.Name = "Form1";

             this.Text = "Form1";

             this.ResumeLayout(false);

             this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox textBox1;

         private System.Windows.Forms.TextBox textBox2;

         private System.Windows.Forms.Button button1;

        /// <summary>

         /// 源文件路径

         /// </summary>

         public string FFileName;

         /// <summary>

         /// 截取时间点

         /// </summary>

         public double Ftime;

         /// <summary>

         /// 目标文件路径

         /// </summary>

         public string FdesFileName;

         IFilterGraph2 iFilterGraph2;

         /// <summary>

         /// IFilterGraph2----增强的IFilterGraph(过滤通道接口) 

        /// </summary>

        // private IFilterGraph2 graphBuilder;////

         private IGraphBuilder graphBuilder; 

        /// <summary>

         /// 用来控制流媒体,例如流的启动和停止暂停等,播放控制接口

         /// </summary>

         public IMediaControl mediaControl;////

         /// <summary>

         /// 判断抽帧

         /// </summary>

         public bool bHasVideo;

         /// <summary>

         /// 定义一个FilterGraph

         /// </summary>

         private FilterGraph zFilterGraph;

        /// <summary>

         /// 视频编码处理

         /// </summary>

         IBaseFilter ibfVideoCompressor = null;

         /// <summary>

         /// 音频编码处理

         /// </summary>

         IBaseFilter ibfAudioCompressor = null;

        /// <summary>

         /// 视频编码

         /// </summary>

         //string Videoencoder = "ffdshow video encoder";

         string Videoencoder = "MONOGRAM x264 Encoder";

         /// <summary>

         /// 音频编码

         /// </summary>

         string Audioencoder = "MainConcept AAC Encoder";

         IMediaSeeking iMediaSeek;

        IBaseFilter sampleFilter;

         ISampleGrabber sampleGrabber;

        public Form1()

         {

             InitializeComponent();

         }

         public void run()

         {

             zFilterGraph = new FilterGraph();

             iFilterGraph2 = zFilterGraph as IFilterGraph2;

             graphBuilder = iFilterGraph2 as IGraphBuilder;

             if (graphBuilder == null)

                 return;

             int hr = graphBuilder.RenderFile(FFileName, null);

             iMediaSeek = zFilterGraph as IMediaSeeking;

             mediaControl = iFilterGraph2 as IMediaControl;

             //hr = mediaControl.RenderFile(FFileName);

             DsError.ThrowExceptionForHR(hr);

             IBaseFilter videoRenderer = null;

             IBaseFilter dSoundFilter = null;

             IPin pinVRIn = null, pinVideoOut = null;

             IPin pinDDDIn = null, pinAudioOut = null;

             try

             {

                 string str = FdesFileName.Substring(FdesFileName.Length - 3, 3).ToLower();

                 hr=iFilterGraph2.FindFilterByName("Video Renderer", out videoRenderer);

                 //DsError.ThrowExceptionForHR(hr);

                 bHasVideo = videoRenderer != null;

                 if (bHasVideo)

                 {

                     pinVRIn = DsFindPin.ByDirection(videoRenderer, PinDirection.Input,0);

                     if (pinVRIn == null)

                     {

                         MessageBox.Show("no pinVRIn");

                     }

                     if (pinVideoOut == null)

                     {

                         pinVRIn.ConnectedTo(out pinVideoOut);

                     }

                     if (pinVideoOut == null)

                     {

                         MessageBox.Show("no pinVideoOut");

                     }

                     hr = iFilterGraph2.Disconnect(pinVRIn);

                     DsError.ThrowExceptionForHR(hr);

                     hr = iFilterGraph2.Disconnect(pinVideoOut);

                     DsError.ThrowExceptionForHR(hr);

                     hr = iFilterGraph2.RemoveFilter(videoRenderer);

                     DsError.ThrowExceptionForHR(hr);

                 }

                 iFilterGraph2.FindFilterByName("Default DirectSound Device", out dSoundFilter);

                 bHasVideo = dSoundFilter != null;

                 if (bHasVideo)

                 {

                     pinDDDIn = DsFindPin.ByDirection(dSoundFilter, PinDirection.Input, 0);

                     if (pinDDDIn == null)

                     {

                         MessageBox.Show("no find Default DirectSound Device pin");

                     }

                     if (pinAudioOut == null)

                     {

                         pinDDDIn.ConnectedTo(out pinAudioOut);

                     }

                     if (pinAudioOut == null)

                     {

                         MessageBox.Show("no Audio out pin");

                     }

                     hr = iFilterGraph2.Disconnect(pinDDDIn);

                     DsError.ThrowExceptionForHR(hr);

                     hr = iFilterGraph2.Disconnect(pinAudioOut);

                     DsError.ThrowExceptionForHR(hr);

                     hr = iFilterGraph2.RemoveFilter(dSoundFilter);

                     DsError.ThrowExceptionForHR(hr);

                 }

                 ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();//捕获图表生成器

                                 IBaseFilter filter;

                 IFileSinkFilter filter2;

                 DsError.ThrowExceptionForHR(icgb.SetFiltergraph(graphBuilder));

                 if (str == "flv")

                 {

                     hr = icgb.SetOutputFileName(new Guid("{C1FB436D-3A1A-4F7B-8D69-B8B8BC652718}"), FdesFileName, out filter, out filter2);//flv

                     //hr = icgb.SetOutputFileName(new Guid("{A28F324B-DDC5-4999-AA25-D3A7E25EF7A8}"), FdesFileName, out filter, out filter2);

                 }

                 else if (str == "mp3")

                 {

                     hr = icgb.SetOutputFileName(new Guid("{36A5F770-FE4C-11CE-A8ED-00AA002FEAB5}"), FdesFileName, out filter, out filter2);

                 }

                 else if (str == "mp4")

                 {

                     hr = icgb.SetOutputFileName(new Guid("{A28F324B-DDC5-4999-AA25-D3A7E25EF7A8}"), FdesFileName, out filter, out filter2);

                 } 

                else 

                {

                     hr = icgb.SetOutputFileName(MediaSubType.Avi, FdesFileName, out filter, out filter2);

                 }

                 DsError.ThrowExceptionForHR(hr);

                 Marshal.ReleaseComObject(filter2);

                 if (str == "mp3")

                     ibfAudioCompressor = GetAudioCompressor("LAME MPEG Layer III Audio Encoder");

                 else 

                    GetTransFilter();

                AMMediaType mt = new AMMediaType();

                 iFilterGraph2.AddFilter(filter, "flvMuxer");

                 if (str == "mp3")

                 {

                     hr = iFilterGraph2.AddFilter(ibfAudioCompressor, "LAME MPEG Layer III Audio Encoder");

                 }

                 else

                 {

                     hr = iFilterGraph2.AddFilter(ibfVideoCompressor, "MONOGRAM x264 Encoder");

                     DsError.ThrowExceptionForHR(hr);

                     hr = iFilterGraph2.AddFilter(ibfAudioCompressor, "MainConcept AAC Encoder");

                     DsError.ThrowExceptionForHR(hr);

                 }

                 if (str == "mp3")

                 {

                     hr = icgb.RenderStream(null, null, pinAudioOut, ibfAudioCompressor, filter);

                     DsError.ThrowExceptionForHR(hr);

                 }

                 else

                 {

                     IPin pinSGIn = null, pinSGOut = null;

                    sampleFilter = (new SampleGrabber()) as IBaseFilter;

                     sampleGrabber = sampleFilter as ISampleGrabber;

                     pinSGIn = DsFindPin.ByDirection(sampleFilter, PinDirection.Input, 0);

                     pinSGOut = DsFindPin.ByDirection(sampleFilter, PinDirection.Output, 0);

                     hr = iFilterGraph2.AddFilter(sampleFilter, "SampleGrabber");

                     DsError.ThrowExceptionForHR(hr);

                    hr = icgb.RenderStream(null, null, pinVideoOut, ibfVideoCompressor, filter);

                     DsError.ThrowExceptionForHR(hr);

                     hr = icgb.RenderStream(null, null, pinAudioOut, ibfAudioCompressor, filter);

                     DsError.ThrowExceptionForHR(hr);

                 }

                 DsUtils.FreeAMMediaType(mt);

                 mediaControl.Run();

                             }

             finally

             {

                 if (videoRenderer != null)

                 {

                     Marshal.ReleaseComObject(videoRenderer);

                     videoRenderer = null;

                 }

                 if (pinVRIn != null)

                 {

                     Marshal.ReleaseComObject(pinVRIn);

                     pinVRIn = null;

                 }

                 if (pinVideoOut != null)

                 {

                     Marshal.ReleaseComObject(pinVideoOut);

                     pinVideoOut = null;

                 }

                 if (dSoundFilter != null)

                 {

                     Marshal.ReleaseComObject(dSoundFilter);

                     dSoundFilter = null;

                 }

                 if (pinDDDIn != null)

                 {

                     Marshal.ReleaseComObject(pinDDDIn);

                     pinDDDIn = null;

                 }

                 if (pinAudioOut != null)

                 {

                     Marshal.ReleaseComObject(pinAudioOut);

                     pinAudioOut = null;

                 }

                 if (pinAudioOut != null)

                 {

                     Marshal.ReleaseComObject(pinAudioOut);

                     pinAudioOut = null;

                 }

             }

         }

         private void GetTransFilter()

         {

             if (Videoencoder != null)

             {

                 //视屏编码选择处理

                 ibfVideoCompressor = GetVideoCompressor(Videoencoder);

                 // MessageBox.Show("未找到ibfVideoCompressor==null");

                 if (ibfVideoCompressor == null)

                 {

                     //MessageBox.Show("视频编码选择处理出现错误");

                 }

             }

             else

             {

                 //MessageBox.Show("未找到合适的视频编码器");

            }

             if (Audioencoder != null)

             {

                 //音频编码选择处理

                 ibfAudioCompressor = GetAudioCompressor(Audioencoder);

                if (ibfAudioCompressor == null)

                 {

                     //MessageBox.Show("音频编码选择处理出现错误");

                 }

             }             else             {

                 //MessageBox.Show("未找到合适的音频编码器");

            }

         }

         #region 音视频编码器初始化

         /// <summary>

         /// 视频编码初始化

         /// </summary>

         /// <param name="videocodec"></param>

         /// <returns></returns>

         private IBaseFilter GetVideoCompressor(string videocodec)

         {

             IBaseFilter ibf = null;

            DsDevice[] ds = DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory);

             for (int i = 0; i < ds.Length; i++)

             {

                 if (ds[i].Name == videocodec)

                 {

                     Guid id = typeof(IBaseFilter).GUID;

                     object o;

                     ds[i].Mon.BindToObject(null, null, ref id, out o);

                     ibf = o as IBaseFilter;

                     break;

                 }

             }

             if (ibf == null)

             {

                 ibf = Legacy(videocodec);

             }

             return ibf;

        }

         /// <summary>

         /// 音频编码初始化

         /// </summary>

         /// <param name="audioCompressor"></param>

         /// <returns></returns>

         private IBaseFilter GetAudioCompressor(string audioCompressor)

         {

             IBaseFilter ibf = null;

             DsDevice[] ds = DsDevice.GetDevicesOfCat(FilterCategory.AudioCompressorCategory);

             for (int i = 0; i < ds.Length; i++)

             {

                 if (ds[i].Name == audioCompressor)

                 {

                     Guid id = typeof(IBaseFilter).GUID;

                     object o;

                     ds[i].Mon.BindToObject(null, null, ref id, out o);

                     ibf = o as IBaseFilter;

                     break;

                 }

             }

             if (ibf == null)

             {

                 ibf = Legacy(audioCompressor);

             }

             return ibf;

         }

        private static IBaseFilter Legacy(string Compressor)

         {

             IBaseFilter ibf = null;

             DsDevice[] dsc = DsDevice.GetDevicesOfCat(FilterCategory.LegacyAmFilterCategory);

             for (int i = 0; i < dsc.Length; i++)

             {

                 if (dsc[i].Name == Compressor)

                 {

                     Guid id = typeof(IBaseFilter).GUID;

                     object o;

                     dsc[i].Mon.BindToObject(null, null, ref id, out o);

                     ibf = o as IBaseFilter;

                     break;

                 }

             }

             return ibf;

         }

         #endregion

         private void textBox1_Click(object sender, EventArgs e) 

        {

             OpenFileDialog ofd = new OpenFileDialog();

             if (ofd.ShowDialog() == DialogResult.OK)

             {

                 textBox1.Text = ofd.FileName;

                 FFileName = ofd.FileName;

             }

        }

        private void textBox2_Click(object sender, EventArgs e)

         {

             SaveFileDialog sfd = new SaveFileDialog();

             if (sfd.ShowDialog() == DialogResult.OK)

             {

                 textBox2.Text = sfd.FileName;

                 FdesFileName = sfd.FileName;

             }

         }

        private void button1_Click(object sender, EventArgs e)

         {

             run();

         }

     }

原文地址:https://www.cnblogs.com/cnzryblog/p/directsho.html