Ich versuche, C# net zu lernen. Denn ich kenne bereits OO PHP, Java und C++ (das ich wegen der manuellen Speicherverwaltung nie wirklich benutzt habe). Ich dachte, ich fange mit etwas Nützlichem an und nicht mit einem weiteren Buch voller künstlicher Probleme. Ich dachte an eine einfache Hausüberwachung.
Ich habe ein wenig gegoogelt und bin auf DirectShowNET . Kompiliert es natürlich ich bin auf win7 64b. Kompiliert CaptureWMV Beispiel, schauen Sie sich den Code und für 12 Stunde versucht, Audio-Capture hinzufügen, aber es immer zerquetschen, wenn ich versuche, nicht nur Video-Codec verwenden. Ich habe nach einem funktionierenden Beispiel gegoogelt, konnte aber keins finden (nur Audio - ja, nur Video - ja, aber beides - nirgends). Hier ist mein leicht veränderter Code. Ich bin sicher, etwas dumm zu tun, aber wird sehr froh sein, wenn jemand mich in die richtige Richtung zeigen.
Schauen Sie sich den kommentierten Code neben
(...)AddSourceFilterForMoniker(devAudio.Mon(...)
Ich weiß, das ist falsch, aber wie macht man es richtig?
using System;
using System.Runtime.InteropServices;
using DirectShowLib;
namespace AsfFilter
{
internal class Capture: IDisposable
{
#region Member variables
/// <summary> graph builder interface. </summary>
private IFilterGraph2 m_FilterGraph = null;
IMediaControl m_mediaCtrl = null;
/// <summary> Set by async routine when it captures an image </summary>
private bool m_bRunning = false;
#if DEBUG
DsROTEntry m_rot = null;
#endif
#endregion
/// <summary> release everything. </summary>
public void Dispose()
{
GC.SuppressFinalize(this);
CloseInterfaces();
}
~Capture()
{
Dispose();
}
/// <summary>
/// Create capture object
/// </summary>
/// <param name="iDeviceNum">Zero based index of capture device</param>
/// <param name="szFileName">Output ASF file name</param>
public Capture(int iDeviceNum, int iAudioNum,string szOutputFileName)
{
DsDevice [] capDevices;
DsDevice [] audioCapDevices;
// Get the collection of video devices
capDevices = DsDevice.GetDevicesOfCat( FilterCategory.VideoInputDevice );
audioCapDevices = DsDevice.GetDevicesOfCat(FilterCategory.AudioInputDevice);
if (iDeviceNum + 1 > capDevices.Length)
{
throw new Exception("No video capture devices found at that index!");
}
if (iAudioNum + 1 > audioCapDevices.Length)
{
throw new Exception("No audio capture devices found at that index!");
}
try
{
// Set up the capture graph
SetupGraph( capDevices[iDeviceNum], audioCapDevices[iDeviceNum], szOutputFileName);
m_bRunning = false;
}
catch
{
Dispose();
throw;
}
}
// Start the capture graph
public void Start()
{
if (!m_bRunning)
{
int hr = m_mediaCtrl.Run();
Marshal.ThrowExceptionForHR( hr );
m_bRunning = true;
}
}
// Pause the capture graph.
// Running the graph takes up a lot of resources. Pause it when it
// isn't needed.
public void Pause()
{
if (m_bRunning)
{
IMediaControl mediaCtrl = m_FilterGraph as IMediaControl;
int hr = mediaCtrl.Pause();
Marshal.ThrowExceptionForHR( hr );
m_bRunning = false;
}
}
/// <summary> build the capture graph. </summary>
private void SetupGraph(DsDevice dev, DsDevice devAudio, string szOutputFileName)
{
int hr;
IBaseFilter capFilter = null;
IBaseFilter asfWriter = null;
IBaseFilter audFilter = null;
ICaptureGraphBuilder2 capGraph = null;
// Get the graphbuilder object
m_FilterGraph = (IFilterGraph2)new FilterGraph();
#if DEBUG
m_rot = new DsROTEntry( m_FilterGraph );
#endif
try
{
// Get the ICaptureGraphBuilder2
capGraph = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();
// Start building the graph
hr = capGraph.SetFiltergraph( m_FilterGraph );
Marshal.ThrowExceptionForHR( hr );
// Add the capture device to the graph
//hr = m_FilterGraph.AddSourceFilterForMoniker(devAudio.Mon, null, devAudio.Name, out capFilter);
//Marshal.ThrowExceptionForHR(hr);
hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter);
Marshal.ThrowExceptionForHR( hr );
asfWriter = ConfigAsf(capGraph, szOutputFileName);
hr = capGraph.RenderStream(null, null, capFilter, null, asfWriter);
Marshal.ThrowExceptionForHR( hr );
m_mediaCtrl = m_FilterGraph as IMediaControl;
}
finally
{
if (capFilter != null)
{
Marshal.ReleaseComObject(capFilter);
capFilter = null;
}
if (asfWriter != null)
{
Marshal.ReleaseComObject(asfWriter);
asfWriter = null;
}
if (capGraph != null)
{
Marshal.ReleaseComObject(capGraph);
capGraph = null;
}
}
}
private IBaseFilter ConfigAsf(ICaptureGraphBuilder2 capGraph, string szOutputFileName)
{
IFileSinkFilter pTmpSink = null;
IBaseFilter asfWriter = null;
int hr = capGraph.SetOutputFileName( MediaSubType.Asf, szOutputFileName, out asfWriter, out pTmpSink);
Marshal.ThrowExceptionForHR( hr );
try
{
IConfigAsfWriter lConfig = asfWriter as IConfigAsfWriter;
// Windows Media Video 8 for Dial-up Modem (No audio, 56 Kbps)
// READ THE README for info about using guids
//WMProfile_V80_56VideoOnly
Guid cat = new Guid(0x6e2a6955, 0x81df, 0x4943, 0xba, 0x50, 0x68, 0xa9, 0x86, 0xa7, 0x8, 0xf6);
//WMProfile_V80_BESTVBRVideo
Guid bat = new Guid(0x48439ba, 0x309c, 0x440e, 0x9c, 0xb4, 0x3d, 0xcc, 0xa3, 0x75, 0x64, 0x23);
//WMProfile_V80_288VideoOnly
Guid vot = new Guid(0x8c45b4c7, 0x4aeb, 0x4f78, 0xa5, 0xec, 0x88, 0x42, 0xb, 0x9d, 0xad, 0xef);
//WMProfile_V80_56Video
Guid vau = new Guid(0x254E8A96, 0x2612, 0x405C, 0x80, 0x39, 0xf0, 0xBF, 0x72, 0x5C, 0xED, 0x7D);
//WMProfile_V80_288MonoAudio
Guid aon = new Guid(0x7ea3126d, 0xe1ba, 0x4716, 0x89, 0xaf, 0xf6, 0x5c, 0xee, 0xc, 0xc, 0x67);
hr = lConfig.ConfigureFilterUsingProfileGuid(cat);
//hr = lConfig.ConfigureFilterUsingProfileGuid(W288Video);
Marshal.ThrowExceptionForHR( hr );
}
finally
{
Marshal.ReleaseComObject(pTmpSink);
}
return asfWriter;
}
/// <summary> Shut down capture </summary>
private void CloseInterfaces()
{
int hr;
try
{
if( m_mediaCtrl != null )
{
// Stop the graph
hr = m_mediaCtrl.Stop();
m_bRunning = false;
}
}
catch {}
#if DEBUG
// Remove graph from the ROT
if ( m_rot != null )
{
m_rot.Dispose();
m_rot = null;
}
#endif
if (m_FilterGraph != null)
{
Marshal.ReleaseComObject(m_FilterGraph);
m_FilterGraph = null;
}
}
}
}
Ich möchte nicht C++-Code für diese wegen der Speicherverwaltung verwenden und DirectShowNet docs sind sehr... minimalistisch. Und ich kann die Idee hinter "pin's" nicht wirklich verstehen. Vielleicht muss ich ganz auf ICaptureGraphBuilder2 verzichten und versuchen, es auf die harte Tour zu machen.
DIES IST MEINE ERSTE BEGEGNUNG MIT C# - BITTE MERKEN SIE SICH DAS!