Проблему решил. Если кому будет потом интересно, расскажу как. Так как найти готовый, но при этом бесплатный контрол я отчаялся, то решил хватать поток с помощью DirectShow, а именно DirectShowLib. Для этого пришлось по верхам ознакомиться с графостроительством Итак, вначале создаю необходимые переменные и объекты:
Код | int WM_GRAPHNOTIFY = 0x00008001; FilterGraph fgFilter; // Основной com-объект IGraphBuilder igbBuilder; // GraphBuilder интерфейс IMediaControl mcControl; // Mediacontrol интерфейс IMediaEventEx meEventEx; // Mediaevent интерфейс IPin pinIn; // Пин входа IPin pinOut; // Пин выхода
|
Затем их инициализирую:
Код | fgFilter = new FilterGraph(); igbBuilder = (IGraphBuilder)fgFilter; mcControl = (IMediaControl)fgFilter; meEventEx = (IMediaEventEx)fgFilter;
|
А потом создаю два фильтра, один для захвата потока, другой для вывода в файл. Так как потоки Windows Media, то использую WM Reader и WM Writer.
Код | meEventEx.SetNotifyWindow(this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero); // Фильтр захвата WMAsfReader asfReader = new WMAsfReader(); IBaseFilter ibfReader = (IBaseFilter)asfReader; IFileSourceFilter fsIn = (IFileSourceFilter)asfReader; fsIn.Load(sSourceURL, null); igbBuilder.AddFilter(ibfReader, "WM Asf Reader"); // Добавление фильтра к графу // Фильтр вывода WMAsfWriter asfWriter = new WMAsfWriter(); IBaseFilter ibfWriter = (IBaseFilter)asfWriter; IFileSinkFilter fsOut = (IFileSinkFilter)asfWriter; fsOut.SetFileName(sFilename, null); // Задание имени выходного файла igbBuilder.AddFilter(ibfWriter, "WM Asf Writer"); // Добавление фильтра к графу
|
Затем нужно соединить два фильтра, для этого пришлось написать свою функцию, возвращающую пин по его имени или части имени.
Код | // Соединение аудио входа и выхода FindPinByName(ibfReader, null, "Raw Audio", out pinOut); FindPinByName(ibfWriter, null, "Audio Input", out pinIn); igbBuilder.Connect(pinOut, pinIn); // Соединение видео входа и выхода FindPinByName(ibfReader, null, "Raw Video", out pinOut); FindPinByName(ibfWriter, null, "Video Input", out pinIn); igbBuilder.Connect(pinOut, pinIn);
|
Осталось только запустить граф на выполнение:
И, когда нужно, остановить захват:
Код | mcControl.Stop(); meEventEx.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero);
|
Кода, конечно, многовато для такого простого случая, но зато все понятно и работает
|