Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Hello, World!
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  08:55[Войти] | [Зарегистрироваться]

IMediaDet — интерфейс для захвата видео и аудио информации

Александр Бусаров
дата публикации 02-03-2007 05:18

IMediaDet — интерфейс для захвата видео и аудио информации

В данной статье я хочу рассмотреть интерфейс IMediaDet, который нам любезно предоставил DirectShow.

Интерфейс специально разработан для того, чтобы захватить часть видео или аудио информации.

Тема небольшая, да и напишу я немного, но думаю, что информация полезная, потому что лично я сталкивался с такой проблемой раньше и не один раз. Выкручивался как всегда какими-нибудь модулями, которые поддерживали от силы 2-3 формата сжатия. Причем один из них позволял сделать одно, скажем, вытащить картинку, другой - сделать видеосэмпл, третий - аудио.

Прежде чем работать с интерфейсом, нужно подключить заголовочный модуль DirectShow (см. файлы к статье). Еще нужно подключить модуль ActiveX. Он идет "в комплекте" с Delphi.

Итак, прежде всего этот интерфейс нужно создать. Создается он с нуля, т.е. не методом какого либо объекта, а прямо с помощью CoCreateInstance.

Объявляем переменную:
Detector:IMediaDet;
И создаем ее:
CoCreateInstance (CLSID_MediaDet,nil, CLSCTX_INPROC_SERVER, IID_IMediaDet, Detector);

После того как детектор создан, мы должны открыть какие то данные. Детектор позволяет нам открывать файлы.

Открываем файл методом
put_Filename(name: PWideChar) 
заметьте, что передается юникод-строка. Получить имя открытого файла можно похожим способом: get_Filename

Далее нам нужно получить информацию о видеофайле. Для этого у нашего детектора есть метод get_StreamMediaType. Вызывается он всего лишь c одним аргументом типа _AMMediaType. В него он возвращает значение. Тип _AMMediaType объеденил в себе ниформацию об аудио- и видео-данных. Для того, чтобы получить информацию о видеофайле можно просто использовать приведение типов.

Вот пример для наглядности:
var
  info:_AMMediaType;
  height, width:word;
Begin
  Detector.get_StreamMediaType(info);
  Width:=VIDEOINFOHEADER(info.pbFormat^).bmiHeader.biWidth;
  Height:=VIDEOINFOHEADER(info.pbFormat^).bmiHeader.biHeight;
End;

Тип VIDEOINFOHEADER предоставляет нам очень много различной информации. И размер изображения, и сжатие, и много еще всего, но он не предоставляет нам длительность ролика. Поэтому используем метод get_StreamLength(out length:double); Здесь длина представлена в секундах, что очень удобно.

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

Используем метод (опять юникод в параметрах)
WriteBitmapBits(time:double; width, height:integer; FIleName:WideString) 

Просто передаем этому методу время в секундах, высоту, ширину, полученную, когда мы вызывали get_StreamMediaType, и имя файла, куда все это добро напишется.

Понятно, что все это запишется сразу же в файл, а вот как получить скриншот сразу в память?

Делается это с помощью метода
GetBitmapBits (time:Double; buffersize:PLongint; buffer:PByte; width, height:integer);

ВНИМАНИЕ!
DirectShow возвращает картинку всегда в 24-битном формате цвета. По байту на каждый канал RGB.

Вызвать метод нужно 2 раза. 1-ый, чтобы определить размер буфера, второй — чтобы записать в него данные. Определять размер можно 1 раз сразу после получения информации по файлу. (Это для оптимизации), так же можно сразу выделять память в буфере под скриншот.

Метод GetBitmapBits для определения размеров буфера нужно вызывать передавая ему параметр nil в качестве buffer. Тогда в переменную buffersize поместится размер буфера. После этого можно выделять память под buffer, и вызывать второй раз метод GetBitmapBits, теперь уже передавая ему в качестве buffer-а наш буфер. (при этом в параметр buffersize передаем nil. Работает вроде даже если передавать не nil, но так советует Microsoft). Height и width передаем все те же, какие были получены через get_StreamMediaType.

Итак, все, в буфере у нас содержится наш рисунок. Осталось только понять как с ним работать, т.е. в каком формате он там хранится. Это формат BITMAPINFOHEADER, который объявлен в Windows.pas.

Битовая информация о каждом пикселе содержится по адресу:
bitinfo:=Pointer(integer(buffer)+SizeOf(BITMAPINFOHEADER));

Так же можно создать HBitmap с нашего buffer используя CreateDIBitmap из Windows.pas В общем, теперь мы с этой памятью можем делать, что захотим.

IMediaDet так же нам предоставляет возможность работать с отрывком (сэмплом) видеофайла. Для этого у него есть метод GetSampleGrabber(grabber: ISampleGrabber). Скажу лишь, что вызывая этот метод, мы создаем объект интерфейса ISampleGrabber. Ну а поскольку это уже другой интерфейс, то о нем я расскажу в другой статье.



К материалу прилагаются файлы:


Смотрите также материалы по темам:
[DirectShow]

 Обсуждение материала [ 09-05-2011 06:49 ] 6 сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования