Скачать заголовочные файлы DirectShow можно здесь.const
//задаем системные константы для интерфейсов (посмотреть можно с помощью программы graphstudio или graphedit в //свойствах фильтров)CLSID_ASFReader : TGUID = '{187463A0-5BB7-11D3-ACBE-0080C75E246E}';
var
Form1: TForm1;
//интерфейсы FGraphBuilder: IGraphBuilder = nil;//сам граф
FCaptureGraphBuilder: ICaptureGraphBuilder2 = nil;
//вспомогательный интерфейс для построения графа захвата FMediaControl: IMediaControl = nil;
//интерфейс управления воспроизведением в графе FVideoWindow: IVideoWindow = nil;
// интерфейс управления окном вывода видео FTee_Audio : IBaseFilter = nil;
//интерфейс фильтра для расщепления аудио потока FTee_Video : IBaseFilter = nil;
// интерфейс фильтра для расщепления видео потока FASFReader : IBaseFilter = nil;
//интерфейс source фильтра FAudioRender : IBaseFilter = nil;
//интерфейс фильтра вывода звука FVideoRender : IBaseFilter = nil;
// интерфейс фильтра вывода видео FMux :IBaseFilter = nil;
// интерфейс фильтра мультиплексора FSink : IFileSinkFilter = nil;
// интерфейс фильтра для записи в файл //каналы Url, Name_ch:string;
//флаг записи RecMode: Boolean = False;
//имя файла для записи FileName:String;
implementation
{$R *.dfm}
//функция построения графаfunction TForm1.CreateGraph;
var
pConfigMux: IConfigAviMux;
//интерфейс управления мультиплексоромbegin
//освобождаем подключенные интерфейсы if Assigned(FMediaControl) then FMediaControl:= NIL;
if Assigned(FVideoWindow) then FVideoWindow := NIL;
if Assigned(FAudioRender) then FAudioRender := nil;
if Assigned(FVideoRender) then FVideoRender:= nil;
if Assigned(FTee_Audio) then FTee_Audio:= nil;
if Assigned(FTee_Video) then FTee_Video:= nil;
if Assigned(FASFReader) then FASFReader:= nil;
if Assigned(FSink) then FSink:= NIL;
if Assigned(FMux) then FMux:= NIL;
if Assigned(FCaptureGraphBuilder) then FCaptureGraphBuilder := NIL;
if Assigned(FGraphBuilder) then FGraphBuilder:= NIL;
//Выходим если канал не выбран if Url='' then exit;
//создаем объект для построения графа фильтров FGraphBuilderCoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, FGraphBuilder);
//создаем объект для построения графа захвата FCaptureGraphBuilderCoCreateInstance(CLSID_CaptureGraphBuilder2, NIL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, FCaptureGraphBuilder);
//указываем графу захвата граф фильтровFCaptureGraphBuilder.SetFiltergraph(FGraphBuilder);
//создаем объект для построения фильтра источника FASFReaderCoCreateInstance(CLSID_ASFReader, nil, CLSCTX_INPROC, IID_IBaseFilter, FASFReader);
//Добавляем его в графFGraphBuilder.AddFilter(FASFReader, 'SourceUrl');
//загружаем в него mms поток из Url(FASFReader as IFileSourceFilter).Load(StringToOleStr(Url), nil);
//создаем объект для построения фильтра разделителя audio потокаCoCreateInstance(CLSID_InfTee, nil, CLSCTX_INPROC, IID_IBaseFilter, FTee_Audio);
// Добавляем его в графFGraphBuilder.AddFilter(FTee_Audio, 'Infinite Pin Tee Filter Audio');
//создаем объект для построения фильтра разделителя video потокаCoCreateInstance(CLSID_InfTee, nil, CLSCTX_INPROC, IID_IBaseFilter, FTee_Video);
// Добавляем его в граф FGraphBuilder.AddFilter(FTee_Video, 'Infinite Pin Tee Filter Video');
//создаем объект для построения фильтра вывода звука FAudioRenderCoCreateInstance(CLSID_AudioRender, nil, CLSCTX_INPROC, IID_IBaseFilter, FAudioRender);
// Добавляем его в граф FGraphBuilder.AddFilter(FAudioRender, 'DirectSound Audio Renderer');
//создаем объект для построения фильтра вывода видео FVideoRenderCoCreateInstance(CLSID_VideoMixingRenderer, nil, CLSCTX_INPROC, IID_IBaseFilter, FVideoRender);
// Добавляем его в граф FGraphBuilder.AddFilter(FVideoRender, 'Video Renderer');
//начинаем строить графwith FCaptureGraphBuilder do
begin
//строим участок графа от фильтра FASFReader до фильтра FTee_Video Result:=RenderStream(nil, @MEDIATYPE_Video, FASFReader, nil, FTee_Video);
if FAILED(Result) then
Begin
ShowMessage('Внимание! Произошла ошибка при инициализации потока видео.');
Exit;
End;
// строим участок графа от фильтра FASFReader до фильтра FTee_ Audio Result:=RenderStream(nil, @MEDIATYPE_Audio, FASFReader, nil, FTee_Audio);
if FAILED(Result) then
Begin
ShowMessage('Внимание! Произошла ошибка при инициализации потока аудио');
Exit;
End;
// строим участок графа от фильтра FTee_ Audio до фильтра FAudioRender Result:=RenderStream(nil, @MEDIATYPE_Audio, FTee_Audio, nil, FAudioRender);
if FAILED(Result) then
Begin
ShowMessage('Внимание! Произошла ошибка при выводе потока аудио');
Exit;
End;
// строим участок графа от фильтра FTee_Video до фильтра F VideoRender Result:=RenderStream(nil, @MEDIATYPE_Video, FTee_Video, nil, FVideoRender);
if FAILED( Result ) then
Begin
ShowMessage('Внимание! Произошла ошибка при выводе потока видео');
Exit;
End;
end;
//запись
//проверяем флаг записиif RecMode then
begin
//Создаем файл для записи данных из графа в виде даты со временемDateTimeToString(FileName,'hh.mm.ss_dd.mm.yyyy',now);
FileName:=FileName+'.avi';
//задаем выходной файл для записи и добавляем в граф фильтр мультиплексораFCaptureGraphBuilder.SetOutputFileName(MEDIASUBTYPE_Avi, PWideChar(StringToOleStr(AnsiString(FileName))), FMux, FSink);
//строим граф фильтров для захвата изображения от фильтра FTee_ Video до фильтра FVideoRenderResult:=FCaptureGraphBuilder.RenderStream(nil, @MEDIATYPE_Video, FTee_Video, Nil, FMux);
if FAILED(Result) then
Begin
ShowMessage('Внимание! Произошла ошибка при выводе видео в файл');
Exit;
End;
//строим граф фильтров для захвата звука от фильтра FTee_ Audio до фильтра FAudioRenderResult:=FCaptureGraphBuilder.RenderStream(nil, @MEDIATYPE_Audio, FTee_Audio, Nil, FMux);
if FAILED( Result ) then
Begin
ShowMessage('Внимание! Произошла ошибка при выводе аудио в файл');
Exit;
End;
pConfigMux := NIL;
//получаем интерфейс управления мультиплексором Result:=FMux.QueryInterface(IID_IConfigAviMux, pConfigMux);
if FAILED( Result ) then
begin
// При захвате видео со звуком устанавливаем звуковой поток в
// качестве основного для синхронизации с другими потоками в файле pConfigMux.SetMasterStream(1);
pConfigMux := NIL;
end;
end;
//получаем интерфейс ImediaControl FGraphBuilder.QueryInterface(IID_IMediaControl, FMediaControl);
//получаем интерфейс IVideoWindow FGraphBuilder.QueryInterface(IID_IVideoWindow, FVideoWindow);
//располагаем окно вывода на Panel1 FVideoWindow.put_Owner(Panel1.Handle);
FVideoWindow.put_WindowStyle(WS_CHILD or WS_CLIPSIBLINGS);
FVideoWindow.put_MessageDrain(Panel1.Handle);
FVideoWindow.SetWindowPosition(0, 0, Panel1.ClientRect.Right,Panel1.ClientRect.Bottom);
//запускаем на воспроизведение FMediaControl.Run;
end;
Полный код исходника можно скачать
здесь. Сразу хочу сказать, что код достаточно сырой и будет постепенно совершенствоваться, поэтому прошу сильно меня не ругать. Каждый может доработать этот код под себя.
Автор статьи xaramamburu, сайт автора http://basicsprog.ucoz.ru .