Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Захват потокового видео с Интернет


Автор: Brain89 5.5.2011, 13:10
Мне требуется захватить видео из Интернет потоков типа mms://live.rfn.ru/vesti_24 и сохранить на диске. Искал в сети, видимо плохо, потому что толком ничего не нашел. В основном, все примеры захватывают видео с камеры и тюнера, а вот примеров захвата и сохранения Интернет-потока нет. Может, кто-нибудь сталкивался с такой задачей? Или может посоветовать, в каком направлении смотреть? Или есть какой-нибудь готовый компонент для таких целей? Заранее спасибо.

Автор: jonie 5.5.2011, 13:25
можно взять проект VLC и посмотреть как в нём - у него даже API есть..

Автор: Brain89 5.5.2011, 14:12
2jonie
Я не уверен, но вроде бы VLC не поддерживает захват потокового видео. Открывать - открывает, но не позволяет сохранять. 

Я нашел платный компонент http://www.visioforge.com/video-capture-sdk-net2.html. Может, кто знает его бесплатный аналог или может подсказать, на основе чего он работает?

Автор: jonie 5.5.2011, 14:14
Цитата(Brain89 @  5.5.2011,  14:12 Найти цитируемый пост)
2jonie
Я не уверен, но вроде бы VLC не поддерживает захват потокового видео. Открывать - открывает, но не позволяет сохранять. 

а я уверенч то умеет)) 
http://forum.videohelp.com/threads/257045-How-to-record-streaming-WMV-ASF-MMS-links-using-VLC-Media-Player

ну иль mplayer тоже вроде бы умел всё что надо....

вообще своё городить тут сомнительное удовольствие, разве что API юзать

Автор: Brain89 5.5.2011, 18:25
2jonie
Конечно, с нуля писать неохота, но если не будет других вариантов... VLC действительно умеет сохранять, но при этом через раз вылетает. Тем более, разработка идет на .NET, а обертки VLC подключаются с трудом, а потом на каждом шаге выдают кучу ошибок. Мне нужен более стабильный вариант. 
MPlayer смотрится лучше, но обертки для него также не назовешь стабильными. 

Автор: Fitc 5.5.2011, 23:02
прошу прощения за оффтоп, а VLC может также сохранять музыку с интернет потоков?

Автор: jonie 6.5.2011, 09:46
Fitc, вообще умеет, но это умеет ничем не хуже и winamp

Автор: Brain89 11.5.2011, 18:35
Проблему решил. Если кому будет потом интересно, расскажу как.
Так как найти готовый, но при этом бесплатный контрол я отчаялся, то решил хватать поток с помощью DirectShow, а именно DirectShowLib. Для этого пришлось по верхам ознакомиться с графостроительствомsmile
Итак, вначале создаю необходимые переменные и объекты:
Код

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

И, когда нужно, остановить захват:
Код

mcControl.Stop();
meEventEx.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero);  

Кода, конечно, многовато для такого простого случая, но зато все понятно и работаетsmile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)