Запись видео в файл AVI
[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]
На следующем рисунке показан самый простой график для записи видео в файл AVI.
Фильтр AVI Mux принимает видеопоток из контакта захвата и упаковывает его в поток AVI. Аудиопоток также может быть подключен к фильтру AVI Mux, в этом случае мультиплекс будет чередовать два потока. Фильтр "Модуль записи файлов" записывает поток AVI на диск.
Чтобы создать граф, начните с вызова метода ICaptureGraphBuilder2::SetOutputFileName следующим образом:
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.
Первый параметр указывает тип файла — в данном случае — AVI. Второй параметр задает имя файла. Для AVI метод SetOutputFileName создает фильтр AVI Mux и фильтр модуля записи файлов и добавляет их в граф. Он также задает имя файла в фильтре записи файлов путем вызова метода IFileSinkFilter::SetFileName и соединяет два фильтра. Метод возвращает указатель на мультиплекс AVI в третьем параметре. При необходимости он возвращает указатель на интерфейс IFileSinkFilter в четвертом параметре. Если этот интерфейс не нужен, можно задать для этого параметра значение NULL, как показано в предыдущем примере.
Затем вызовите метод ICaptureGraphBuilder2::RenderStream , чтобы подключить фильтр захвата к мультиплексии AVI, как показано ниже.
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();
Первый параметр предоставляет категорию контактов, которая PIN_CATEGORY_CAPTURE для записи. Второй параметр задает тип носителя. Третий параметр является указателем на интерфейс IBaseFilter фильтра отслеживания . Четвертый параметр является необязательным; он позволяет направлять видеопоток через промежуточный фильтр, например кодировщик, перед его передачей в фильтр мультиплекса. В противном случае задайте для этого параметра значение NULL, как показано в предыдущем примере. Пятый параметр — это указатель на фильтр мультиплекса. Этот указатель получается путем вызова метода SetOutputFileName.
Чтобы записать звук, вызовите RenderStream с типом мультимедиа MEDIATYPE_Audio. Если вы собираете звук и видео с двух отдельных устройств, рекомендуется сделать аудиопоток master потоком. Это помогает предотвратить смещение между двумя потоками, так как фильтр AVI Mux настраивает скорость воспроизведения в видеопотоке в соответствии с аудиопотоком. Чтобы задать поток master, вызовите метод IConfigAviMux::SetMasterStream в фильтре AVI Mux:
IConfigAviMux *pConfigMux = NULL;
hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux);
if (SUCCEEDED(hr))
{
pConfigMux->SetMasterStream(1);
pConfigMux->Release();
}
Параметр SetMasterStream — это номер потока, который определяется порядком вызова RenderStream. Например, если сначала вызвать RenderStream для видео, а затем для звука, видео будет потоком 0, а звук — потоком 1.
Вы также можете задать способ чередовки аудио- и видеопотоков с помощью фильтра AVI Mux, вызвав метод IConfigInterleaving::p ut_Mode .
IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
if (SUCCEEDED(hr))
{
pInterleave->put_Mode(INTERLEAVE_CAPTURE);
pInterleave->Release();
}
С флагом INTERLEAVE_CAPTURE мультиплекс AVI выполняет чередование со скоростью, подходящей для захвата видео. Вы также можете использовать INTERLEAVE_NONE, что означает отсутствие чередование— мультиплекс AVI будет просто записывать данные в том порядке, в котором они поступают. Флаг INTERLEAVE_FULL означает, что мультиплекс AVI выполняет полное чередование; однако этот режим менее подходит для захвата видео, так как для него требуется больше всего подслушано.
Кодирование видеопотока
Вы можете закодировать видеопоток, вставив фильтр кодировщика между фильтром захвата и фильтром AVI Mux. Используйте перечислитель системных устройств или сопоставитель фильтров , чтобы выбрать фильтр кодировщика. (Дополнительные сведения см. в разделе Перечисление устройств и фильтров.)
Укажите фильтр кодировщика в качестве четвертого параметра для RenderStream, как показано полужирным шрифтом в следующем примере:
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();
Фильтр кодировщика может поддерживать IAMVideoCompression или другие интерфейсы для настройки параметров кодирования. Список возможных интерфейсов см. в разделе Интерфейсы кодирования и декодирования файлов.
Связанные темы