|
AVI Files with Hot Spots
Abstract
The AVI Hotspot
Editor (AVIHED.EXE) and its accompanying dynamic-link libraries (DLLs)
AVIHVWR.DLL and AVIHAPP.DLL provide you with the ability to specify hot
spots for audio-video interleaved (AVI) files, much as you can specify hot
spots for device-independent bitmap (DIB) files with the segmented
hypergraphics hot-spot editor (SHED.EXE). The AVI hot-spot kit can be used
with Microsoft® Multimedia Viewer or with a stand-alone application by using
the correct DLL.
The AVI Hotspot
Editor allows you to draw hot spots easily on your AVI file and save them in
a hot-spot information file, which you specify when you call the
hspPlayAVI function in the AVI hot-spot DLL.
www.tartoos.com
The AVI hot-spot
kit allows you to:
-
Specify Begin
and End frames for each hot spot so that, for example, two hot spots can
cover an overlapping space as long as their Begin and End frames do not
overlap;
-
Execute any
Viewer command or send a message to your calling stand-alone application
when a hot spot is selected; additionally, you can continue or terminate
playing when a hot spot is selected, or jump to another location in the
same AVI file.
www.tartoos.com
The AVI
Hotspot Editor
You use the AVI
Hotspot Editor to create and edit the hot spots for an audio-video
interleaved (AVI) file. Hot spots can cover overlapping areas in an AVI file
as long as their Begin and End frames do not overlap. For each hot spot, you
specify a command string, a hot-spot ID, and (optionally) a beginning and
ending frame.www.tartoos.com
Using the
Hotspot Editor
After loading the
Hotspot Editor, choose File Open to open an AVI file. You will be prompted
for a hot-spot (.INI) file. If you are creating hot spots for the first time
for the specified AVI file, choose Cancel because you do not need to open an
.INI file.www.tartoos.com
Once the AVI file
is loaded, you can start drawing hot spots on this file. To do so, click the
left mouse button, hold it down, and draw the hot spot that you want. To
specify hot-spot attributes, double-click inside the rectangle you have
created. To adjust the position of a hot spot, put the mouse cursor inside
the rectangle, click the mouse button, and move the rectangle while holding
the button down. To change the size of the hot spot, click and drag one of
the hot spot's edges. You can delete a hot spot by clicking inside its
rectangle and pressing the Delete key or choosing Delete Specified Hotspot
from the Hotspots menu.
When a hot spot is
selected, its rectangle coordinates will appear in the Selected Hotspot Info
window.www.tartoos.com
Hot-Spot
Attributes
In the Hotspot
Attributes dialog box, you can specify the following information:
www.tartoos.com
-
A command
string, which is the command that is executed in Viewer when the hot spot
is selected (for example, you might specify sndPlaySound(‘hello.wav’,1) ).
-
A hot-spot ID
(for example, Hotspot 1).
-
The hot spot's
bounding box, that is, its rectangle coordinates.www.tartoos.com
-
The hot spot's
active frames (so that more than one hot spot can be specified for
overlapping rectangle areas during different frames).
-
Hot-spot
selection options that change the action of the AVI file when the hot spot
is selected, to continue playing, terminate playing, or jump to a
specified frame in the same AVI file.
Saving
Hot-Spot Files
Once you have
drawn hot spots for the specified AVI file, make sure you have specified a
hot-spot ID and, if applicable, a command string for each hot spot. Then
choose Save from the File menu and enter a filename. If you have not
specified an ID for each hot spot, you will receive an error message.www.tartoos.com
Other
Features
The kit allows you
to specify different active frames for each hot spot, so you can choose to
see only the hot spots that are active for the frame currently displayed in
the editor (choose the Only Show Hotspots in Current Frame option from the
Hotspots menu) or all hot spots in the AVI file, independent of the frame
displayed.www.tartoos.com
The
Hot-Spot Information File Format
The AVI Hotspot
Editor writes the hot-spot information file using
WritePrivateProfileString, so all entries in the file have the regular
.INI file format. The .INI file must contain a [Configuration]
section, a [Hotspots] section, and information for at least one hot
spot. Each hot spot is saved under its hot-spot ID.
The [Configuration]
section has the format:www.tartoos.com
[Configuration]
Version=1.00
Editor=AVIHED
The current
version number is 1.00. The Editor entry will normally be AVIHED.
The [Hotspots]
section is in the form: HotspotID=1. Hot-spot IDs can be anything as
long as =1 is specified, for example:
[Hotspots]
Ears=1
Eyes=1
Door=1
Window=1
For each entry in
the [Hotspots] section, there must be a corresponding hot-spot entry,
for example:
[Door]
Rect=247,17,281,71
Command=sndPlaySound(`n.wav', 1)
BeginFrame=0
EndFrame=101
OnClick=1018
ToFrame=0
where:
-
Rect is
the position of the hot spot in the form Left,Top,Right,Bottom.www.tartoos.com
-
Command
is the command to be executed when the hot spot is selected.
-
BeginFrame
is the first frame for the hot spot to be active.www.tartoos.com
-
EndFrame
is the last frame for the hot spot to be active.
-
OnClick
can be one of three values: ID_CONTINUE, ID_STOP, or ID_JUMP. These values
are defined in the RESOURCE.H file.
-
ToFrame
is the frame to jump to if ID_JUMP is specified for OnClick.
www.tartoos.com
Programming Issues
Drawing on an
AVI frame
The most effective
way I have found for drawing on top of an AVI file is to have Video for
Windows™ paint the AVI file to a window that you have created. When you
receive a WM_PAINT message in your window procedure, use the MCI_UPDATE
command to update the window, given the handle of the device context
returned by BeginPaint. After the command returns (using the MCI_WAIT
flag), draw the hot-spot rectangles (or whatever you want to draw).www.tartoos.com
The editor uses
the MCI_STOP command to stop playing the AVI file instead of the MCI_PAUSE
command, because using MCI_PAUSE will result in incorrect painting of the
hot-spot rectangles. Even if you use MCI_PAUSE with the MCI_WAIT flag, Video
for Windows finishes painting after the mciSendCommand when
MCI_PAUSE returns, which results in the rectangles being hidden. You could
also use MCI_STEP to step to the current frame, although MCI_STOP does the
job in one step.www.tartoos.com
If you want to use
a window that Video for Windows creates instead of your own, you will need
to subclass Video's window. Do this by getting the AVI window from the
return information provided by the MCI_OPEN command. In the subclass
procedure, intercept the WM_PAINT message and then call mciSendCommand
with the MCI_UPDATE command there. Do not call the old window procedure
because this will result in the output you have drawn being hidden beneath
the AVI file.www.tartoos.com
Unfortunately,
there is still no good way to keep drawn objects on top of an AVI file while
it is playing. Doing so on a frame-by-frame basis would slow down the
display of the AVI file and cause flicker.
Painting the
hot spots
Originally, I used
the rectangle painting function in the Microsoft® Windows Software
Development Kit (SDK) SHOWDIB sample. However, when I started dealing with
AVI files that used very light colors or a variety of colors, inverting the
hot-spot rectangles did not show them clearly enough. Using PatBlt
after selecting a multicolored brush into the device context (DC) made
inverting much clearer. Another possibility would be to store an off-screen
DC of the current frame, draw colored lines onto the window DC, and then
BitBlt from the off-screen DC onto the window when a line’s position
changes. This would be possible by calling mciSendCommand to have
Video for Windows paint the current frame to an off-screen DC, but this
process could be time-consuming, resulting in slow rectangle movement.
Suggested
Improvements
-
Undo ability.
-
Printing of
current hot-spot information/AVI frame.www.tartoos.com
-
Visual selection
of hot spots.
-
Multiple-document interface (MDI) support for dealing with multiple AVI
files at the same time.
-
Polygon support
using the CreatePolygonRgn function and a series of points.
The AVI
Hot-Spot DLLs
There are two AVI
hot-spot dynamic-link libraries (DLLs): AVIHVWR.DLL, which can be used with
Viewer applications by specifying it in the Viewer application's MVP project
file, and AVIHAPP.DLL, which you can link with your stand-alone application.
Visual Basic® support has not yet been implemented, but suggestions on how
to do so are described in the “Suggested Improvements” section later in this
article.www.tartoos.com
Programming Issues
Multiple
Viewer/application instances with the same DLLwww.tartoos.com
Because there can
be only one instance of each DLL but multiple applications or instances of
an application calling each DLL, the hot-spot DLL associates a structure
with each application (instance) that calls it. The structure it uses is
called a MOVIEINFO structure, defined in HOTSPOT.H. There are two
ways to associate information with a window: Either write your own functions
to match up a global handle to data with a window handle and have a list of
these associations, or use the SetProp/GetProp/RemoveProp
functions, which allow you to specify 16-bit values (such as handles to
globally allocated memory) for a window. The DLLs’ exported function
hspPlayAVI calls SetProp; the subclass procedure calls GetProp
every time it is called so that it can obtain information about the movie,
such as the address of the old procedure to call. Finally, when the subclass
procedure receives a WM_DESTROY message, it calls RemoveProp to
remove the movie information from the window.wwww.tartoos.com
Visual Basic
support
Although the DLL
can be used with Visual Basic already, unfortunately, it has no way to send
information back to a Visual Basic application when a hot spot is selected.
To send a message to the Visual Basic application using SendMessage
or to use a callback function from the DLL to the application (as done with
non-Visual Basic stand-alone applications), you must either add basic VBX
functionality to the DLL or you must write a separate VBX that can export
callbacks from a Visual Basic application or intercept new messages
(messages that are not already implemented in Visual Basic) by subclassing
the form on which it is placed.
Hot spotswww.tartoos.com
The hot spots for
an AVI file are read in from an .INI file and stored in a doubly-linked
list. Each time the user clicks in the movie window (causing a
WM_LBUTTONDOWN message to be sent), the subclass procedure calls a function
that calls the PtInRect function for each hot spot in the list to
determine which hot-spot rectangle, if any, the mouse cursor was positioned
in when the user pressed the mouse button. While going through the hot-spot
list, before determining whether the point was in a hot-spot rectangle, the
function checks to see if the hot spot is valid for the currently displayed
frame, that is, if the current frame is between the beginning and ending
frames for the hot spot.
For the Viewer DLL
(AVIHVWR.DLL), the function calls VwrCommand as follows:
VwrCommand (VwrFromHinst (GetWindowWord (hwnd, GWW_HINSTANCE) ),www.tartoos.com
NULL, pHotspot->pszCommand, cmdoptNONE)
Because Viewer
requires a VWR structure to be specified as the first parameter to
VwrCommand, the function obtains the instance handle by using
GetWindowWord; the hwnd parameter is obtained from the following
calls:
hwnd
= GetParent(pMovieInfo->hwndParent);
if
(!hwnd) hwnd = pMovieInfo->hwndParent;www.tartoos.com
where
pMovieInfo is a pointer to a MOVIEINFO structure passed to the
function from the subclass procedure.
For the
stand-alone application DLL (AVIHAPP.DLL), the DLL executes the callback
function passed as the last parameter to the hspPlayAVI DLL function.
The callback function is defined in the application by exporting a function
in the .DEF file and then calling MakeProcInstance and passing its
return value to the hspPlayAVI function. When the application
receives the WM_DESTROY message, it should call FreeProcInstance.
Using SendMessage with a WM_USER+xxxx message or (as a hack)
WM_COMMAND with a certain value for wParam is another possibility,
but a callback appears to be the most straightforward and efficient
solution.
Using the
DLLs
There are separate
DLLs for Viewer (AVIHVWR.DLL) and for stand-alone applications
(AVIHAPP.DLL).
With Viewer
To use the
hot-spot DLL with Viewer, specify the following command in the [CONFIG]
section of the your Viewer application's .MVP project file:
RegisterRoutine("AVIHVWR","hspPlayAVI","I=USS")
In your Viewer
.RTF file, specify some text or bitmap; then specify the following in hidden
text:
!hspPlayAVI(hwndContext,'AVIFILE.AVI','HSPFILE.INI')
where AVIFILE.AVI
is the name of the AVI file to play and HSPFILE.INI is the name of the INI
file containing hot-spot information for the AVI file. hwndContext is
a Viewer-defined variable; see the Viewer documentation for further details.
With
stand-alone applicationswww.tartoos.com
To use the
hot-spot DLL with stand-alone applications, add AVIHAPP.LIB to your link
statement. Include AVIHAPP.H, which defines the prototype for the
hspPlayAVI function. To call the hspPlayAVI function, you will
need to export a callback function that the DLL will call to notify you that
a hot spot has been selected. To play an AVI file with hot spots, call the
hspPlayAVI function with the name of the AVI file as the first
parameter, the name of the .INI file containing hot-spot information as the
second parameter, and the address returned from MakeProcAddress
called with the name of your exported callback function. When your
application's window receives a WM_DESTROY message, it should call
FreeProcAddress.
The callback
function must have the following syntax:
BOOL
__export hspAVICallback (HWND hwndParent, HWND hwndMovie, WORD wMessage,
FAR * lParam1, LONG FAR *lParam2)
The callback
should handle the WM_SIZE and and WM_LBUTTONDOWN messages. (Note that these
are not used as messages but as command identifiers, defining what action
should be taken on the given parameters, if any.) If the callback processes
a message successfully, it should return TRUE; if it does not, it should
return FALSE.
If wParam
is WM_SIZE: The callback is being given an opportunity to adjust the size of
the window in which the movie will be played before the movie is displayed.
lParam1 is a far pointer to a RECT structure that gives the
dimensions of the movie.
If wParam
is WM_LBUTTONDOWN: The user has selected a hot spot. lParam1 is an
LPSTR containing the hot-spot ID; lParam2 is an LPSTR
containing the command for the hot spot.
The AVIHRUN
sample (stand-alone)www.tartoos.com
The AVIHRUN sample
program demonstrates how to call hspPlayAVI, how to implement a
callback function, and how to process the messages in the callback function.
In addition, it implements a simple command language, which supports the
following two commands:
-
sndPlaySound
-
ExecProgram
(or WinExec)
Both commands have
the same syntax as their Viewer counterparts.
Suggested
Improvements
The AVI Hotspot
Editor and DLLs provide the framework and basic but usable functionality for
an AVI hot-spot interface in Viewer and stand-alone applications. Suggested
improvements to the current code include:
-
Visual Basic
support by means of a VBX.
www.tartoos.com
-
Multiple command
support so that, for example, you could play a .WAV file and execute a
command.
-
Better device
independence; support for specifying coordinates.www.tartoos.com
-
Extending the
command language of AVIHRUN into a full-fledged run-time application that
can be distributed with AVI and hot-spot files would add tremendous
functionality. Some sort of extensible module interface beyond merely
calling WinExec (for example, support for external functions in
DLLs) would be valuable.www.tartoos.com
-
Using resource
interchange file format (RIFF) to combine hot-spot information with AVI
files and perhaps commands implemented by the AVIHRUN application would be
an excellent extension to the AVI interface. At a bare minimum, use some
sort of compiled or binary files instead of .INI files to store the
hot-spot information.
|