在运行代码之前需要添加相应的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) { //find video renderer input pin connected pin 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(); } }