Программирование с C++ Builder



Просмотр видеороликов



Как было сказано выше, компонент MediaPlayer позволяет просматривать видеоролики и сопровождаемую звуком анимацию. В качестве примера использования компонента рассмотрим программу Video Player, при помощи кoторой можно просмотреть небольшой ролик или анимацию. Вид формы программы Video Player приведен на рис. 4.9.

Компонент OpenDialog1 обеспечивает отображение стандартного диалогового окна Открыть файл для выбора файла. Окно Открыть файл становится доступным во время работы программы в результате щелчка на кнопке Eject (speedButtoni). Следует обратить внимание, что для управления процессом воспроизведения кнопки компонента MediaPiayerl не используются, поэтому свойству Visible компонента MediaPiayerl присвоено значение false.



Рис. 4.9. Форма программы Video Player


Для управления работой видеоплеера используются кнопки Play/Stop (speedButtoni) и Eject (speedButton2), представляющие собой компоненты SpeedButton.

Компонент SpeedButton находится на вкладке Additional (рис. 4.10) и представляет собой командную кнопку, на поверхности которой может быть картинка.



Рис. 4.10. Компонент SpeedButton


Кнопка SpeedButton может находиться в одном из четырех состояний: обычное (не нажата и доступна); нажата (пользователь установил указатель мыши на изображение кнопки и нажал кнопку мыши); зафиксирована; недоступна. Каждому состоянию кнопки может соответствовать своя картинка.

Свойства компонента SpeedButton приведены в табл. 4.9.

Таблица 4.9. Свойства компонента SpeedButton


Свойство

Описание

Name

Имя компонента. Используется для доступа к компоненту и его свойствам

Glyph

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

NumGlyphs

Количество картинок в битовом образе Glyph

Flat

Свойство Flat определяет вид кнопки (наличие границы). Если значение свойства равно true, то граница кнопки появляется только при позиционировании указателя мыши на кнопке

Grouplndex

Идентификатор группы кнопок. Кнопки, имеющие одинаковый идентификатор группы, работают подобно радиокнопкам, т. е. нажатие одной из кнопок группы вызывает срабатывание других кнопок этой группы. Чтобы кнопку можно было зафиксировать, значение этого свойства не должно быть равно нулю

Down

Идентификатор состояния кнопки. Изменить значение свойства можно, если значение свойства GroupIndex не равно 0

AllowUp

Признак, показывающий, что нажатую (зафиксированную) кнопку можно отжать

Left

Расстояние от левой границы кнопки до левой границы формы

Top

Расстояние от верхней границы кнопки до верхней границы формы

Height

Высота кнопки

Width

Ширина кнопки

Enabled

Признак доступности кнопки. Если значение свойства равно true, то кнопка доступна. Если значение свойства равно false, то кнопка не доступна

Visible

Позволяет скрыть кнопку (false) или сделать ее видимой (true)

Hint

Подсказка— текст, который появляется рядом с указателем мыши при позиционировании указателя на командной кнопке (для того чтобы текст появился, значение свойства ShowHint должно быть true)

ShowHint

Разрешает (frue) или запрещает (false) отображение подсказки при позиционировании указателя на кнопке


Свойство ciiph представляет собой битовый образ, который содержит картинки для кнопок. Структура битового образа Gliph приведена на рис. 4.11. Следует обратить внимание на то, что смещение картинки на кнопке при ее нажатии, изменение цвета фона нажатой кнопки и цвета картинки на недоступной кнопке делает сам компонент. Поэтому в простейшем случае все картинки образа Gliph могут быть одинаковыми.



Рис. 4.11. Структура битового образа Glyph: картинки, соответствующие состоянию кнопки


Подготовить битовый образ для кнопки speedButton можно при помощи любого графического редактора, в том числе и Image Editor. После запуска Image Editor надо выбрать команду File | New | Bitmap File и в появившемся окне Bitmap Properties задать размер битового образа (например, 19x76 — если размер картинки на кнопке должен быть 19x19 пикселов). В качестве примера на рис. 4.12 приведен битовый образ для кнопки Play (speedButton2). Границы кнопок показаны условно. Обратите внимание, что изображение нажатой и зафиксированной кнопок смещены вверх и вправо относительно изображений нажатой и недоступных кнопок. Сделано это для того, чтобы во время работы программы у пользователя не создавалось впечатление, что кнопка "ушла".



Рис. 4.12. Битовый образ для кнопки Play


В табл. 4.10 приведены значения свойств компонентов SpeedButton1 и SpeedButton2 разрабатываемой программы. Текст программы Video Player приведен в листинге 4.4.

Таблица 4.10. Значение свойств компонентов SpeedButton1 и SpeedButton2


Свойство

SpeedButton1

SpeedButton2

Gliph

ejbtn.bmp

plbtn.bmp

NumGliphs

4

4

Flat

true

true

AllowUp

false

true

Grouplndex

0

1

Enabled

true

false

Width

25

25

Height

25

25

ShowHint

true

true

Hint

Eject

Play


Листинг 4.4. Видеоплеер

//обработка события Create
void __fastcall TForml::FormCreate(TObject *Sender)
{
MediaPlayerl->Display = Forml;
 // отображение ролика на поверхности
// формы
 }
// возвращает размер кадра AVI-файла
void __fastcall GetFrameSize(AnsiString f, int *w, int *h)
{
// в заголовке AVI-файла есть информация о размере кадра
struct {
char RIFF[4]; // строка RIFF 
long int nu_l[5]; //не используется
char AVIH[4]; // строка AVIH
long int nu_2[9]; //не используется
long int w; // ширина кадра
long int h; // высота кадра
} header;
TFileStream *fs; // поток (для чтения заголовка файла)
/* операторы объявления потока и его создания
можно объединить:
 TFileStream *fs = new TFileStream(f,fmOpenRead); */
fs = new TFileStream(f,fmOpenRead};
 // открыть поток для чтения
fs->Read(&header, sizeof(header));
 // прочитать заголовок файла
*w = header.w; *h = header.h;
delete fs; }
// щелчок на кнопке Eject (выбор видеоклипа)
void__fastcall TForral::SpeedButtonlClick(TObject *Sender)
{
OpenDialogl->Title = "Выбор клипа";
OpenDialogl->InitialDir = "";
OpenDialogl->FileName = "*.avi";
if ( ! OpenDialogl->Execute())
return; // пользователь нажал кнопку Отмена
/* При попытке открыть файл клипа, который уже открыт,
возникает ошибка. */
if ( MediaPlayerl->FileName = OpenDialogl->FileName) return;
/* Пользователь выбрал клип.
 Зададим размер и положение "экрана",
 на который будет выведен клип.
 Для этого надо знать размер кадров клипа. */
int fw, fh; // размер кадра клипа
int top,left; // левый верхний угол экрана
int sw, sh; // размер экрана (ширина, высота)
int mw, mh; // максимально возможный размер экрана
// (определяется текущим размером формы)
float kw, kh;
 // коэф-ты масштабирования кадра по ширине и высоте
float k; // коэфф-т масштабирования кадра
GetFrameSize(OpenDialogl->FileName,&fw, &fh);
 // получить размер кадра
/ / вычислим максимально возможный размер кадра
mw = Forml->ClientWidth;
mh = Forml->SpeedButtonl->Top-10;
if ( fw < mw)
kw = 1; // кадр по ширине меньше размера экрана
 else kw = (float) mw / fw;
if ( fh < mh)
kh = 1; // кадр по высоте меньше размера экрана
 else kh = (float) mh / fh;
// масштабирование должно быть пропорциональным
 if ( kw < kh)
k = kw; else k = kh; // здесь масштаб определен
sw = fw * k; // ширина экрана
sh = fh * k; // высота экрана 
left = (Forml->ClientWidth - sw) / 2;
top = (SpeedButtonl-XTop - sh) / 2; 
MediaPlayerl->FileName = OpenDialogl->FileName; 
MediaPlayerl->Open(); 

MediaPlayerl->DisplayRect = Rect(left,top,sw,sh);
SpeedButton2->Enabled = True;
// кнопка Play теперь доступна 
/* если размер кадра выбранного клипа
меньше размера кадра предыдущего клипа, 
то экран (область формы) надо очистить */ 
Forml->Canvas->
FillRect(Rect(0,0,ClientWidth,SpeedButtonl->Top)); 
// активизируем процесс воспроизведения MediaPlayerl->Play() ;
SpeedButton2->Down = True;
SpeedButton2->Hint = "Stop";
 SpeedButtonl->Enabled = False; } 
// щелчок, на кнопке Play/Stop (воспроизведение/стоп) 
void _fastcall TForml::SpeedButton2Click(TObject *Sender)
{
if (SpeedButton2->Down) { 
// нажата кнопка Play 
MediaPlayerl->Play(); 
SpeedButton2->Hint = "Stop"; 
SpeedButtonl->Enabled = False; // кнопка Eject недоступна 
} else 
{
// нажата кнопка Stop MediaPlayerl->Stop() ;
SpeedButton2->Hint = "Play"; 
SpeedButtonl->Enabled = True; // кнопка Eject доступна }
} 
11 сигнал от плеера 
void__fastcall TForml::MediaPlayerlNotify(TObject *Sender) 
{ 
if ( ( MediaPlayerl->Mode == mpStopped) &&
 ( SpeedButton2->Down))
{
SpeedButton2->Down = False; // "отжать" кнопку Play
SpeedButton2->Hint = "Play"; 
SpeedButtonl->Enabled = True; // сделать доступной кнопку Eject
}
 } 

Следует обратить внимание на следующее. В качестве экрана, на котором осуществляется воспроизведение видеороликов, используется поверхность формы. Поэтому установить значение свойства Display компонента MediaPlayer1 во время разработки формы нельзя. Кроме того, размер экрана должен быть равен или пропорционален размеру кадров ролика. Значение свойства Display устанавливает функция Обработки события Create для формы, а размер и положение экрана на форме — функция обработки события click на кнопке Eject (speecffiuttoni). Размер экрана устанавливается максимально возможным и таким, чтобы ролик воспроизводился без искажения (высота и ширина экрана пропорциональны высоте и ширине кадров). Размер кадров ролика возвращает функция GetFrameSize, которая извлекает нужную информацию из заголовка файла.