在运行代码之前需要添加相应的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();
}
}