(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)
Microsoft Windows Professional 10, Электронный ключ
NERO 2016 Classic ESD. Электронный ключ
GFI FaxMaker и 1 год поддержки (10-49 лицензий)
 
Другие предложения...
 
Курсы обучения   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 "с нуля"
Новые программы для Windows
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100