Запись видео в 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 Mux в третьем параметре. При необходимости он возвращает указатель на интерфейс IFileSinkFilter в четвертом параметре. Если этот интерфейс не нужен, этот параметр можно задать для null, как показано в предыдущем примере.
Затем вызовите метод ICaptureGraphBuilder2::RenderStream для подключения фильтра захвата к AVI Mux следующим образом:
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. Если вы записываете звук и видео с двух отдельных устройств, рекомендуется сделать аудиопоток главным. Это помогает предотвратить смещение между двумя потоками, так как фильтр AVI Mux настраивает частоту воспроизведения в видеопотоке, чтобы соответствовать звуковому потоку. Чтобы задать главный поток, вызовите метод 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::put_Mode.
IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
if (SUCCEEDED(hr))
{
pInterleave->put_Mode(INTERLEAVE_CAPTURE);
pInterleave->Release();
}
С флагом INTERLEAVE_CAPTURE AVI Mux выполняет чередование с частотой, подходящей для видеозахвата. Вы также можете использовать INTERLEAVE_NONE, что означает отсутствие чередования — AVI Mux просто записывает данные в том порядке, в котором они поступают. Флаг INTERLEAVE_FULL означает, что AVI Mux выполняет полное чередование; однако этот режим менее подходит для видеозахвата, так как он требует наибольшей нагрузки.
Кодирование видеопотока
Видеопоток можно закодировать, вставив фильтр кодировщика между фильтром записи и фильтром 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 или другие интерфейсы для настройки параметров кодирования. Список возможных интерфейсов см. в разделе Кодировка файлов и декодирование интерфейсов.
Связанные разделы