Partager via


Capture de vidéo dans un fichier AVI

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation au lieu de DirectShow, si possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

L’illustration suivante montre le graphique le plus simple possible pour capturer des vidéos dans un fichier AVI.

avi video capture graph

Le filtre AVI Mux prend le flux vidéo de la broche de capture et l’empatte dans un flux AVI. Un flux audio peut également être connecté au filtre AVI Mux, auquel cas le mux entrelace les deux flux. Le filtre Enregistreur de fichiers écrit le flux AVI sur le disque.

Pour générer le graphe, commencez par appeler la méthode ICaptureGraphBuilder2::SetOutputFileName , comme suit :

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.

Le premier paramètre spécifie le type de fichier , dans ce cas, AVI. Le deuxième paramètre donne le nom de fichier. Pour AVI, la méthode SetOutputFileName cocrée le filtre AVI Mux et le filtre Enregistreur de fichiers et les ajoute au graphique. Il définit également le nom de fichier sur le filtre Enregistreur de fichiers, en appelant la méthode IFileSinkFilter::SetFileName , puis connecte les deux filtres. La méthode retourne un pointeur vers avi Mux dans le troisième paramètre. Si vous le souhaitez, elle retourne un pointeur vers l’interface IFileSinkFilter dans le quatrième paramètre. Si vous n’avez pas besoin de cette interface, vous pouvez définir ce paramètre sur NULL, comme indiqué dans l’exemple précédent.

Ensuite, appelez la méthode ICaptureGraphBuilder2::RenderStream pour connecter le filtre de capture à avi Mux, comme suit :

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();

Le premier paramètre donne la catégorie d’épingle, qui est PIN_CATEGORY_CAPTURE pour la capture. Le deuxième paramètre donne le type de média. Le troisième paramètre est un pointeur vers l’interface IBaseFilter du filtre de capture. Le quatrième paramètre est facultatif ; il vous permet d’acheminer le flux vidéo via un filtre intermédiaire, tel qu’un encodeur, avant de le transmettre au filtre mux. Sinon, définissez ce paramètre sur NULL, comme indiqué dans l’exemple précédent. Le cinquième paramètre est le pointeur vers le filtre mux. Ce pointeur est obtenu en appelant la méthode SetOutputFileName.

Pour capturer l’audio, appelez RenderStream avec le type de média MEDIATYPE_Audio. Si vous capturez de l’audio et de la vidéo à partir de deux appareils distincts, il est judicieux de faire en sorte que le flux audio soit le flux master. Cela permet d’éviter la dérive entre les deux flux, car le filtre AVI Mux ajuste la vitesse de lecture sur le flux vidéo pour qu’elle corresponde au flux audio. Pour définir le flux master, appelez la méthode IConfigAviMux::SetMasterStream sur le filtre AVI Mux :

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

Le paramètre de SetMasterStream est le numéro de flux, qui est déterminé par l’ordre dans lequel vous appelez RenderStream. Par exemple, si vous appelez RenderStream d’abord pour la vidéo, puis pour l’audio, la vidéo est stream 0 et l’audio est stream 1.

Vous pouvez également définir la façon dont le filtre AVI Mux entrelace les flux audio et vidéo, en appelant la méthode IConfigInterleaving::p ut_Mode .

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

Avec l’indicateur INTERLEAVE_CAPTURE, l’avi Mux effectue l’entrelacement à une vitesse adaptée à la capture vidéo. Vous pouvez également utiliser INTERLEAVE_NONE, ce qui signifie qu’il n’y a pas d’entrelacement : l’avi Mux écrit simplement les données dans l’ordre dans lequel elles arrivent. L’indicateur INTERLEAVE_FULL signifie que le Mux AVI effectue un entrelacement complet ; Toutefois, ce mode est moins adapté à la capture vidéo, car il nécessite le plus d’entendre.

Encodage du flux vidéo

Vous pouvez encoder le flux vidéo en insérant un filtre d’encodeur entre le filtre de capture et le filtre AVI Mux. Utilisez l’énumérateur d’appareil système ou le mappeur de filtre pour sélectionner un filtre d’encodeur. (Pour plus d’informations, consultez Énumération d’appareils et de filtres.)

Spécifiez le filtre d’encodeur comme quatrième paramètre pour RenderStream, illustré en gras dans l’exemple suivant :

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();

Le filtre d’encodeur peut prendre en charge IAMVideoCompression ou d’autres interfaces pour définir les paramètres d’encodage. Pour obtenir la liste des interfaces possibles, consultez Interfaces d’encodage et de décodage de fichiers.

Capture de vidéo dans un fichier