(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

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

Источник: delphikingdom
Александр Бусаров

Автор: Александр Бусаров, Королевство Delphi

В данной статье я хочу рассмотреть интерфейс 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. Ну а поскольку это уже другой интерфейс, то о нем я расскажу в другой статье.

И напоследок. Удалять указатель на наш IMediaDet нужно, вызвав метод _Release, который есть у всех интерфейсных объектов.

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

Ссылки по теме

Файлы для загрузки


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 03.03.2009 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Delphi Professional Named User
Enterprise Connectors (1 Year term)
ARCHICAD 21, локальная лицензия на 12 месяцев
IBM DOMINO ENTERPRISE CLIENT ACCESS LICENSE AUTHORIZED USER ANNUAL SW SUBSCRIPTION & SUPPORT RENEWAL
Quest Software. Toad for DBA Suite for Oracle
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
СУБД Oracle "с нуля"
Новости мира 3D-ускорителей
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100