Freigeben über


Aufzeichnen von Videos in einer AVI-Datei

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]

Die folgende Abbildung zeigt das einfachste mögliche Diagramm zum Aufzeichnen von Videos in einer AVI-Datei.

avi video capture graph

Der AVI Mux-Filter übernimmt den Videostream vom Aufnahmepin und packt ihn in einen AVI-Stream. Ein Audiostream könnte auch mit dem AVI Mux-Filter verbunden werden, in diesem Fall würde der Mux die beiden Streams überschneiden. Der Filter File Writer schreibt den AVI-Stream auf den Datenträger.

Um das Diagramm zu erstellen, rufen Sie zunächst die ICaptureGraphBuilder2::SetOutputFileName-Methode wie folgt auf:

IBaseFilter *pMux;
hr = pBuild->SetOutputFileName(
    &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
    L"C:\\Example.avi", // File name.
    &pMux,              // Receives a pointer to the mux.
    NULL);              // (Optional) Receives a pointer to the file sink.

Der erste Parameter gibt den Dateityp an, in diesem Fall AVI. Der zweite Parameter gibt den Dateinamen an. Für AVI erstellt die SetOutputFileName-Methode den AVI-Mux-Filter und den File Writer-Filter und fügt sie dem Diagramm hinzu. Außerdem wird der Dateiname für den File Writer-Filter festgelegt, indem die IFileSinkFilter::SetFileName-Methode aufgerufen wird, und die beiden Filter werden miteinander verbunden. Die -Methode gibt einen Zeiger auf den AVI-Mux im dritten Parameter zurück. Optional wird ein Zeiger auf die IFileSinkFilter-Schnittstelle im vierten Parameter zurückgegeben. Wenn Sie diese Schnittstelle nicht benötigen, können Sie diesen Parameter auf NULL festlegen, wie im vorherigen Beispiel gezeigt.

Rufen Sie als Nächstes die ICaptureGraphBuilder2::RenderStream-Methode auf, um den Erfassungsfilter wie folgt mit avi Mux zu verbinden:

hr = pBuild->RenderStream(
    &PIN_CATEGORY_CAPTURE, // Pin category.
    &MEDIATYPE_Video,      // Media type.
    pCap,                  // Capture filter.
    NULL,                  // Intermediate filter (optional).
    pMux);                 // Mux or file sink filter.

// Release the mux filter.
pMux->Release();

Der erste Parameter gibt die Pinkategorie an, die für die Erfassung PIN_CATEGORY_CAPTURE ist. Der zweite Parameter gibt den Medientyp an. Der dritte Parameter ist ein Zeiger auf die IBaseFilter-Schnittstelle des Erfassungsfilters. Der vierte Parameter ist optional. Damit können Sie den Videostream über einen Zwischenfilter, z. B. einen Encoder, weiterleiten, bevor Sie ihn an den Muxfilter übergeben. Legen Sie andernfalls diesen Parameter auf NULL fest, wie im vorherigen Beispiel gezeigt. Der fünfte Parameter ist der Zeiger auf den Muxfilter. Dieser Zeiger wird durch Aufrufen der SetOutputFileName-Methode abgerufen.

Um Audio zu erfassen, rufen Sie RenderStream mit dem Medientyp MEDIATYPE_Audio auf. Wenn Sie Audio und Video von zwei separaten Geräten erfassen, empfiehlt es sich, den Audiostream zum master Stream zu machen. Dies trägt dazu bei, Abweichungen zwischen den beiden Streams zu verhindern, da der AVI-Mux-Filter die Wiedergaberate im Videostream an den Audiodatenstrom anpasst. Um den master-Datenstrom festzulegen, rufen Sie die IConfigAviMux::SetMasterStream-Methode für den AVI Mux-Filter auf:

IConfigAviMux *pConfigMux = NULL;
hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux);
if (SUCCEEDED(hr))
{
    pConfigMux->SetMasterStream(1);
    pConfigMux->Release();
}

Der Parameter für SetMasterStream ist die Streamnummer, die durch die Reihenfolge bestimmt wird, in der RenderStream aufgerufen wird. Wenn Sie beispielsweise RenderStream zuerst für Video und dann für Audio aufrufen, ist das Video Stream 0 und das Audio ist Stream 1.

Sie können auch festlegen, wie der AVI Mux-Filter die Audio- und Videodatenströme interleasiert, indem Sie die IConfigInterleaving::p ut_Mode-Methode aufrufen.

IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
if (SUCCEEDED(hr))
{
    pInterleave->put_Mode(INTERLEAVE_CAPTURE);
    pInterleave->Release();
}

Mit dem flag INTERLEAVE_CAPTURE führt der AVI Mux überlappend eine Rate aus, die für die Videoaufnahme geeignet ist. Sie können auch INTERLEAVE_NONE verwenden, d. h. keine Verschachtelung – der AVI-Mux schreibt die Daten einfach in der Reihenfolge, in der sie eingehen. Die INTERLEAVE_FULL-Kennzeichnung bedeutet, dass der AVI-Mux eine vollständige Ineinanderflechtung durchführt; Dieser Modus eignet sich jedoch weniger für die Videoaufnahme, da er die meisten Überhörten erfordert.

Codieren des Videostreams

Sie können den Videostream codieren, indem Sie einen Encoderfilter zwischen dem Aufnahmefilter und dem AVI-Mux-Filter einfügen. Verwenden Sie den Systemgeräteenumerator oder die Filterzuordnung , um einen Encoderfilter auszuwählen. (Weitere Informationen finden Sie unter Auflisten von Geräten und Filtern.)

Geben Sie den Encoderfilter als vierten Parameter für RenderStream an, der im folgenden Beispiel fett dargestellt wird:

IBaseFilter *pEncoder;
/* Create the encoder filter (not shown). */
// Add it to the filter graph.
pGraph->AddFilter(pEncoder, L"Encoder");

/* Call SetOutputFileName as shown previously. */

// Render the stream.
hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, 
    pCap, 
pEncoder, pMux);
pEncoder->Release();

Der Encoderfilter unterstützt möglicherweise IAMVideoCompression oder andere Schnittstellen zum Festlegen der Codierungsparameter. Eine Liste der möglichen Schnittstellen finden Sie unter Dateicodierungs- und Decodierungsschnittstellen.

Aufzeichnen von Videos in einer Datei