Среда, 22.11.2017, 01:42
Приветствую Вас Гость

Не ошибается тот, кто ничего не делает.
Но и ничего не делать - ошибка.

Эмиль Кроткий

Меню сайта
Категории раздела
Работа с библиотеками BASS и DirectShow [14]
Статьи по написанию mp3 плеера, видеоплеера, работе с WEB камерой и т.д.
Форма входа

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0


















Тиц
Главная » Статьи » Мультимедиа » Работа с библиотеками BASS и DirectShow

Урок 4.2. Создаем видеоплеер для просмотра Online TV с возможность записи потока в файл.
Cодержание

Урок 4.1. Создаем видеоплеер для просмотра Online TV.
Урок 4.2. Создаем видеоплеер для просмотра Online TV с возможность записи потока в файл.

Урок 4.2.

Создаем видеоплеер для просмотра Online TV
с возможность записи потока в файл.

      На этом уроке мы усовершенствуем наш OnLine видеоплеер, созданный на прошлом уроке, добавим к нему возможность записи mms потока. Но для этого придется полностью перестроить граф фильтров. Граф будем строить двух видов. Первый для воспроизведения, он будет выглядеть так:

DirectShow схема графа для воспроизведения mms потока.

     Если в прошлой версии я использовал полностью автоматическое построение графа (метод RenderFile, который сам подбирает фильтры и строит граф), то сейчас я буду добавлять часть фильтров в ручную, это Source фильтр (WM ASF Reader), фильтр для разделения потока Infinite Pin Tee Filter и фильтры для video и audio renderer. Промежуточные фильтры дадим возможность поставить самому графу на его усмотрение. В результате на выходах разделителя потока Infinite Pin Tee Filter мы получим возможность снимать аудио и видео поток для записи.



Ниже приведу часть кода с комментариями, который строит граф показанный выше.

Скачать заголовочные файлы 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;
//создаем объект для построения графа фильтров FGraphBuilder
CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, FGraphBuilder);
//создаем объект для построения графа захвата FCaptureGraphBuilder
CoCreateInstance(CLSID_CaptureGraphBuilder2, NIL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, FCaptureGraphBuilder);

//указываем графу захвата граф фильтров
FCaptureGraphBuilder.SetFiltergraph(FGraphBuilder);

//создаем объект для построения фильтра источника FASFReader
CoCreateInstance(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');
//создаем объект для построения фильтра вывода звука FAudioRender
CoCreateInstance(CLSID_AudioRender, nil, CLSCTX_INPROC, IID_IBaseFilter, FAudioRender);
// Добавляем его в граф
FGraphBuilder.AddFilter(FAudioRender, 'DirectSound Audio Renderer');
//создаем объект для построения фильтра вывода видео FVideoRender
CoCreateInstance(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 до фильтра FVideoRender
Result:=FCaptureGraphBuilder.RenderStream(nil, @MEDIATYPE_Video,  FTee_Video, Nil, FMux);
if FAILED(Result) then
 Begin
      ShowMessage('Внимание! Произошла ошибка при выводе видео в файл');
      Exit;
 End;

//строим граф фильтров для захвата звука от фильтра FTee_ Audio  до фильтра FAudioRender
Result:=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 .




Категория: Работа с библиотеками BASS и DirectShow | Добавил: xaramamburu (19.01.2012)
Просмотров: 5919 | Комментарии: 13 | Теги: Online TV, DirectShow, граф фильтров | Рейтинг: 5.0/4
Всего комментариев: 13
13  
На счет записи: Пауза записи могла бы понадобится для того чтобы пропустить рекламу.

11  
Я только хотел задать вопрос о записи патока и уже есть ответ. А можно ли вести запись патока с паузами и в avi файл?

12  
Поток и так пишется в Avi файл. А насчет пауз не знаю, не пробовал. Да, многие адреса mms потоков со времен написания статьи изменились, поэтому нужно их проверять.))))))))))

7  
Доброго времени чуток smile у меня такой вопрос... А возможно ли изменить программу так чтобы она воспроизводила потоковое видео например с контакта и ютуба?
У меня просто мечта: хочу сделать плеер такой, чтоб на нём можно было мульты он-лайн смотреть smile

8  
Думаю, что можно, но у меня пока руки не дошли до этого. Здесь нужно разбираться с фильтрами для работы с потоковым видео RTSP и Url File Source фильтром. Если найдете хороший фильтр, то построить граф больших проблем не составит. smile

9  
хм...попробую что-нить в интернете найти smile

10  
буду очень благодарен если Вы поможете мне осуществить мою мечту smile

3  
ну не знаю у меня работал под Windows 7 под Windows vista не пробовал))))

1  
ух ти прикольно)))) протестируем))))

2  
Протестируешь, отпишись. Думаю что ошибок много, я только еще разбираюсь с DirectShow да и интерфейс нужно продумать. Первая версия из урока 4.1. У меня почему то под Windows Vista и под Windows 7, работать так и не захотела, а эта вроде по крайней мере под Windows Vista работает. Правда код нужно дорабатывать, поэтому в уроке выложил только его часть, чтоб потом не переписывать.))))

4  
Все отлично работает но при начало записи картинка исчезает и начинает программка виснуть затем когда картинка появляется программа начинает нормально работать и не виснет я пробовал под windows 7 и под windows xp )))) результат одинаковый только под windows 7 бывает так что программа либо сама закрывается либо виснет и закрывать только через диспетчер задач smile ну это не страшно)))) заметил еще один дефект видео которое записано через эту программу при записи на windiws 7 дефектов нет а под windows xp появляются дырки в видео при передвижение они исчезают smile ну может это у меня с кодеками проблемки smile

5  
Это уже хорошо, а то у меня скорость интернета не какая, поэтому, что то хорошо протестировать сложно, плюс похоже висту на ноутбуки надо убивать.)))))

6  
да у меня тоже с инетом туго сам сижу с 3G ))))) но тв тянет smile

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск
Наш опрос
Оцените мой сайт
Всего ответов: 532
Уголок общения



Copyright MyCorp © 2017Конструктор сайтов - uCoz