Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Передача видео и звука с помощью Indy [D7]


Страницы:   1 2 3 4 5 6 7 8 9 10

3asys ©   (2011-11-26 15:48:00) 

На клиенте получаю видео и звук с web-камеры (с встроенным микрофоном) с помощью DirectShow.
Нужно передать их серверу для рассылки другим клиентам.
Видео и звук с Web-камеры получаю стандартным способом, описанным в примерах к DSPack, - примерно так:

var
 multiplexer: IBaseFilter;
 Writer: IFileSinkFilter;
 PinList: TPinList;
 i: integer;
begin
with MainForm do
begin
 CaptureGraph.Active := true;
 if AudioSourceFilter.FilterGraph <> nil then
 begin
   PinList := TPinList.Create(AudioSourceFilter as IBaseFilter);
   i := 0;
   while i < PinList.Count do
     if PinList.PinInfo[i].dir = PINDIR_OUTPUT then
       begin
         if AudioFormats.ItemIndex <> -1 then
           with (PinList.Items[i] as IAMStreamConfig) do
             SetFormat(AudioMediaTypes.Items[AudioFormats.ItemIndex].AMMediaType^);
         PinList.Delete(i);
       end else inc(i);
   if InputLines.ItemIndex <> -1 then
     with (PinList.Items[InputLines.ItemIndex] as IAMAudioInputMixer) do
       put_Enable(true);
   PinList.Free;
 end;

 if VideoSourceFilter.FilterGraph <> nil then
 begin
   PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
   if VideoFormats.ItemIndex <> -1 then
     with (PinList.First as IAMStreamConfig) do
       SetFormat(VideoMediaTypes.Items[VideoFormats.ItemIndex].AMMediaType^);
   PinList.Free;
 end;

 with CaptureGraph as IcaptureGraphBuilder2 do
 begin
   // set the output filename
   SetOutputFileName(MEDIASUBTYPE_Avi, PWideChar(CapFile), multiplexer, Writer);

   if VideoSourceFilter.BaseFilter.DataLength > 0 then
     RenderStream(@PIN_CATEGORY_PREVIEW, nil, VideoSourceFilter as IBaseFilter,
       nil , form1.VideoWindow as IBaseFilter);

   if VideoSourceFilter.FilterGraph <> nil then
     RenderStream(@PIN_CATEGORY_CAPTURE, nil, VideoSourceFilter as IBaseFilter,
       nil, multiplexer as IBaseFilter);

   if AudioSourceFilter.FilterGraph <> nil then
   begin

     RenderStream(nil, nil, AudioSourceFilter as IBaseFilter,
       nil, multiplexer as IBaseFilter);
   end;
 end;
 CaptureGraph.Play;

В RenderStream получаем потоки, но как их передать через IdTCPClient, IdTCPServer я сообразить не могу.
Как это сделать?


3asys   (2011-11-30 21:54:00) [121]

> DVM ©
При запуске выдается ошибка "Access violation" на включении критической секции FLock.Enter
Если комментирую включение и выключение критической секции, выдает такую же ошибку на JPG.SaveToStream(Buffer);


DVM   (2011-11-30 10:09:00) [122]


> 3asys ©   (30.11.11 00:47) [62]
> Удалось подключиться к серверу через FireFox и, кстати,
> через IE 8
> Браузеры подключаются, но часы не визуализируются.

Значит что-то еще у тебя не так. Отладчик бери и смотри. Еще снифер можно тоже, чтоб убедиться что все передается правильно. То что я тебе привел выше работало.


> Eraser ©   (30.11.11 00:37) [61]

При предложенном мной подходе с видео у него проблем не возникнет. Метод старый, проверенный десятилетием производителями сетевых камер. Ну и у меня есть софт кое-какой который в том же формате вещает. RTSP/RTP конечно лучше, но его не так просто реализовать. Да и JPEG передать по RTP сложнее, лучше брать MPEG4.

Сложнее будет со звуком. Звук он штука не дискретная как видео а непрерывная, поэтому надо будет городить более сложные буферы, иначе все будет заикаться.

С синхронизацие видео и звука проблем быть не должно, это же реалтайм видео, не запись и потоки не имеют возможности рассинхронизироваться сколько нибудь значительно.


Германн   (2011-11-30 01:40:00) [123]

Проще, но дороже тут http://vidicor.ru/


Eraser   (2011-11-30 01:06:00) [124]

> [63] 3asys ©   (30.11.11 00:52)

думаю не ошибусь, если скажу, что видео/аудио подсистема самая запутаная вещь в ОС. для себя я вывел правило не искать в этом направлении легких путей. очередной легкий путь приводит к тому, что все нужно будет потом переписывать практически заново.


3asys   (2011-11-30 00:52:00) [125]

> Eraser ©
Согласен, что непросто это все, но нужно достичь какого-то базового результата - видео и звук в минимально приемлемом качестве между несколькими участниками, а потом можно будет улучшать и допиливать ориентируясь на конкретные требования пользователей.


3asys   (2011-11-30 00:47:00) [126]

Удалось подключиться к серверу через FireFox и, кстати, через IE 8
Браузеры подключаются, но часы не визуализируются.


Eraser   (2011-11-30 00:37:00) [127]

> [19] 3asys ©   (28.11.11 16:52)

это проект не на один день и не на один месяц думаю. по быстрому сделать скайп или тимвьювер не получится. все упрется в то, что нужно полностью прорабатывать каждую деталь, начиная от захвата/сжатия (для этого нужно привинтить современные кодеки) и заканчивая передачей данных. Не стоит забывать, что помимо картинки, нужно передавать еще и звук, также нужно чтобы они воспроизводились синхронно. Короче, сталкивался, не завидую )


3asys   (2011-11-30 00:22:00) [128]

Может быть, поскольку для системы нужен будет собственный клиент, не тратить время на firefox, а сделать клиента и уже его отлаживать. Только с чего начать?


3asys   (2011-11-30 00:18:00) [129]

> DVM ©
Добрый день, наконец попробовал подключиться к запущенному серверу через FireFox - не может подключиться.
Что может быть?


3asys   (2011-11-29 15:52:00) [130]

> У тебя сервер то заработал? Пробовал его смотреть?

смогу увидеть сегодня вечером (к 21 по Москве)


DVM   (2011-11-29 15:36:00) [131]


> Правильно ли я понимаю, что в схеме, которая получается,
>  клиент, имея сервер http на борту транслирует поток по
> 8081 порту и принимает такой же поток от другого клиента
> (я имею в виду, что возможно бросить на форму TWebBrowser
> и принимать поток контрагента).

Каждый экземпляр твоей системы конференцсвязи имеет 1 сервер, который вещает видео+звук для всех кто к нему подключится. Также имеет N клиентов, которые получают данные от собеседников данного, подключаясь к их серверам.

Только кидать TWebBrowser не стоит. Во-первых, он не понимает такого типа передачи (понимает только Firefox да и то только jpeg). Надо написать своего клиента, который a) будет принимать поток с указанного сервера b) будет разбирать поток c) будет воспроизводить поток.


> А как обеспечить участие 3х и более активных клиентов (которые
> и принимают потоки от всех других участников и сами передают
> участникам свое видео и звук)?

По-моему, я уже ответил. Сколько угодно так может общаться людей. Их будет столько сколько потянет сеть и их комьютеры.


> я имею в виду, что портов должно стать больше, а если каждый
> будет вещать по своему порту, как всех принять. Если же
> все по одному порту - как разделить потоки от разных клиентов
> (которые будут смешиваться ... ?

Это все независимые друг от друга потоки, с какого перепуга они будут смешиваться.


> И еще, было сказано "берем Firefox (и только его, другие
> браузеры не понимают этот формат)" - TWebBrowser - не подходит?
>

Нет. И Firefox не подходит. Еще туда-сюда VLC ActiveX подойдет (вроде есть такой), но написать своего клиента не долго.

У тебя сервер то заработал? Пробовал его смотреть?


3asys   (2011-11-29 14:32:00) [132]

я имею в виду, что портов должно стать больше, а если каждый будет вещать по своему порту, как всех принять. Если же все по одному порту - как разделить потоки от разных клиентов (которые будут смешиваться ... ?

И еще, было сказано "берем Firefox (и только его, другие браузеры не понимают этот формат)" - TWebBrowser - не подходит?


3asys   (2011-11-29 14:27:00) [133]

Спасибо большое. Попробую расписать.
Правильно ли я понимаю, что в схеме, которая получается, клиент, имея сервер http на борту транслирует поток по 8081 порту и принимает такой же поток от другого клиента (я имею в виду, что возможно бросить на форму TWebBrowser и принимать поток контрагента).
Т.е. имеем двух активных клиентов-серверов и неограниченое число пассивных клиентов.
А как обеспечить участие 3х и более активных клиентов (которые и принимают потоки от всех других участников и сами передают участникам свое видео и звук)?


DVM   (2011-11-29 13:48:00) [134]


> 3asys ©

Кстати, если натравить на этот сервер VideoLan VLC Player то оно тоже будет показывать. Звук он по идее тоже должен воспроизводить.


DVM   (2011-11-29 13:46:00) [135]


> потом можно перейти на несжатые кадры.

на сжатые то есть


DVM   (2011-11-29 13:40:00) [136]


> - процедура idhtpsrvrMainCommandGet задает структуру потока
> и отправляет его клиенту;

Это обработчик GET запросов к серверу, в принципе там можно еще проверять URI переданный серверу в запросе, чтоб обращаться например не к корню сервера а по какому то пути, например /GetVideo или /GetAudio . Да, он формирует структуру потока и отправляет его клиенту. Отправка не прекращается никогда.


> - в процедуре tmrUpdateFrameTimer создается bitmap, "конвертируется"
> в jpeg, который сохраняется в Buffer (он же поток);

Да, мне надо было где то взять кадры, причем разные, сделал вот такой их генератор. В твоем же случае источником кадров будет выступать отдельный поток, в котором будут грабиться кадры с камеры.


> - нужна отдельная процедура для получения видео и звука
> с web-камеры?

Не обязательно, можно все сделать по аналогии с видео, но разделить обработчики GET запросов по переданному URL (он содержится в TRequestInfo вроде бы) . Я бы аудио стал передавать отдельно от видео, отдельным запросом у серверу по другому пути, так оно правильнее, так как кому то нужен только звук возможно, кому то только картинка.

Для аудио все делается аналогично, порция данных передается вместе с подзаголовком. Content-type там должен быть, что то вроде audio/что-то там, зависит от кодека. Вот выше в документе Axis можно поглядеть там есть про аудио.


> - картинки с камеры сохраняем в bmp?

По идее можно передавать и несжатый BMP тогда Content-Type надо указать: image/bitmap, но это имхо уже черезчур. Очень большой поток получиться, лучше сжимать в jpeg например. Intel Jpeg Library советую для сжатия - она в разы быстрее встроенного модуля jpeg.


> - как сохранять звук?

В каком формате сжатия ты хочешь сказать? Для начала попробуй просто PCM, потом можно перейти на несжатые кадры. Для перекодирования как звука так и видео, можно воспользоваться например ffmpeg (заголовочные файлы для него есть в интернет), но тут конечно придеться повозиться над изучением ffmpeg.


3asys   (2011-11-29 12:09:00) [137]

На Indy 10 перешел. Все скомпилировалось. Правда, я убрал пространства имен в uses и удалил strict из объявления TSafeBuffer (выдавало ошибку - подумал, что опечатка).

Правильно ли я понимаю, что:
- процедура idhtpsrvrMainCommandGet задает структуру потока и отправляет его клиенту;
- в процедуре tmrUpdateFrameTimer создается bitmap, "конвертируется" в jpeg, который сохраняется в Buffer (он же поток);
- нужна отдельная процедура для получения видео и звука с web-камеры?

Если да, то:
- картинки с камеры сохраняем в bmp?
- как сохранять звук?


3asys   (2011-11-29 00:50:00) [138]

ок меняю.


DVM   (2011-11-29 00:37:00) [139]


> у вас Indy 10 ?

10

Советую 9 поменять на 10. Это возможно в любой версии Delphi. В 9 полно ошибок и она не развивается.


3asys   (2011-11-29 00:35:00) [140]

у вас Indy 10 ? - многие модули из uses не находятся


Страницы:   1 2 3 4 5 6 7 8 9 10

Наверх

Титульная страница Поиск, карта сайта Написать письмо