![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Передача видео и звука с помощью Indy [D7]
3asys © (2011-11-26 15:48:00)
Страницы: < 1 2 3 4 5 6 7 8 9 10 >
На клиенте получаю видео и звук с 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 не находятся