s Flash becomes more and more popular as a Web video delivery platform, I receive more and more questions regarding its use. In fact, I receive more inquiries about video than any other Flash-related topic. When you consider the video delivery marketplace, it’s easy to understand why. The Flash Player reaches more users than any other video player, including QuickTime, Windows Media Player, and Real Player, so developers are looking to Flash in increasing numbers for their video needs.
I may not be able to respond to every email I get, but I can dedicate my next several articles to answering many of the Flash video-related questions that readers and students ask me. This month, I’ll discuss Metadata in FLV files: why it’s important, why it’s not always there, and how you can create metadata when it’s absent.
What is Metadata?
Metadata essentially means data about data. In this case, the information that composes an FLV file is the primary data, and the metadata is information about that video. The length of the video (duration), the number of frames per second that the video displays (frame rate), and the number of kilobytes of data transferred per second when the video plays (video and audio data rates, where applicable) are all examples of video metadata.
In many cases metadata is useful non-essential information that comes in handy when searching for or querying a data asset. For example, think about a digital image database, and think of a keyword field in which you can add descriptive words about the image. Other examples of metadata, however, can border on indispensable. Reconsider the same digital image library, and think about the width and height fields in that database. Without that information, it would be much harder to display the image properly. The same types of metadata and, unfortunately, the same kinds of problems, apply to FLVs.
Video without Progress
To understand what happens when metadata isn’t properly added to an FLV during the encoding process, consider an example using Flash’s MediaPlayback component. Just as scientific progress stalls without data, the progress of an FLV is not automatically reflected by the component without metadata. If you began using the component when it was introduced, for example, you had to enter a duration in the Component Inspector for the preload and progress bars (in the component scrubber, as pictured in Figure 1) to function. Because no metadata existed in the FLV the component couldn’t calculate the width of these bars during playback without someone manually entering the duration.
|Figure 1. Declaring Duration: When duration metadata is not properly added to the FLV during encoding, the progress bar (seen in green above the pause and rewind buttons) in media components cannot calculate its correct width. In these cases, you must manually enter the duration of the FLV in the Component Inspector or inject the correct metadata using third-party tools.|
The same is true with width and height. Components and custom players alike, that rely on retrieving the width and height of the FLV from the file, fail to correctly size themselves and/or the FLV when the relevant metadata is missing or incorrect. This is especially important for FLV files because unlike QuickTime, for example, you can’t easily open an FLV in a player and determine the dimensions of the file.
Among the early FLV encoding tools, the following versions did not add metadata to FLVs properly:
- Flash Video Exporter and Encoder (a free FLV codec for QuickTime and standalone encoding application, respectively, that shipped with Flash MX 2004) prior to 1.2
- Sorenson Squeeze (a commercial third-party encoding application that supports FLV compression) prior to 4.0
- Flix Pro (formerly from Wildform, now developed by On2) prior to version 8
Problems also exist in later versions of some of these applications. For example, versions of Sorenson Squeeze between 4.0 and 4.2 added metadata but did not do so properly. Notably, the size of the video was added incorrectly. In a 320 x 240 test FLV created for this article in version 4.1, for instance, the file reported its size as 320 x 320.
Where does that leave you today? Fortunately, current versions of these tools all add metadata to FLVs correctly, which is fine if your software is up to date. But what should you do if you find yourself just shy of compatibility? Fortunately, two generous, talented programmers have donated to the Flash community a pair of free command-line utilities that inject metadata into existing FLVs. Using these utilities metadata can be added to previously created FLVs; it also means that additional metadata, including custom information, can be added.
FLV Metadata Injector
The first tool is Burak Kalayci’s FLV Metadata Injector, from the Manitu Group. FLV Metadata Injector, or FLVMDI for short, is a command-line tool for the Windows platform. Usage is simple, starting with the necessary command, followed by the FLV pathname and a series of optional parameters:
flvmdi inputFile [outputFile] [/s] [/x] [/e] [/k]
The first optional parameter is a pathname for an output file. This allows you to create a new FLV without altering the original. This is handy if you want to try a variety of options, and to make sure you can recover from any possible corruption. If this parameter is omitted, the original FLV will be overwritten with the new data included.
The remaining four optional parameters are one-character parameters, or switches, that issue specific processing instructions to the utility. The first parameter, /s, controls the result string returned by the utility. After every operation, a result string is returned to the console. By default, the result appears as seen in the first column of Table 1. Using the /s switch returns an abbreviated single-character result string, as seen in column two of Table 1.
Table 1. Setting Parameters: This table shows the result string (column one) returned by FLV Metadata Injector when used from the command line. Column two is the corresponding single-character abbreviated string returned when the /s switch is used, and column three is the meaning of the result.
|Result String||Result as One Character||Meaning|
|An error occurred. [filename]||1||Some error occurred while processing, no details available.|
|usage: flvmdi inputFilename [outputFilename] [/s] [/x] [/k] [/eExtraData]||2||Error with parameters supplied|
|directory does not exist : [outputFolder]||3||The folder specified cannot be found.|
The /x switch also writes an XML file itemizing the metadata added to the FLV. (Flash 8 cue points and any other imported non-standard values are not exported to the XML file). The file is written into the same directory as the FLV file.
The /e switch allows you to add a custom string, such as copyright information, to the metadata.
Finally, the /k switch adds a keyframe object, which lists the offset in seconds, from the beginning of the file, for every keyframe. This prepares the file for use in a pseudo-streaming environment when used with additional server-side scripting. With such a setup, you can seek to specific keyframes during playback, without the Flash Media Server, which brings with it significant additional expense. (I’ll discuss the Flash Media Server in more detail in a future article.)
So, an example usage, with local relative paths and adding the keyframe arrays, is:
flvmdi nero.flv nero_md.flv /k
That’s all there is to it. When you execute the command line, metadata will be injected into (or updated in the case of existing data) in the previously created FLV. A table of the metadata injected, including property, datatype, and description, can be seen in Table 2. Also, a Flash 8-compatible source file, in the Zip archive accompanying this article, will trace the metadata to the output window so you can see what any FLV looks like and try to spot incorrect values, like the video height discussed previously.
Table 2. FLVMDI Metadata: This table details the property, datatype, and description of the metadata injected into existing FLVs by the FLV Metadata Injector.
|Duration||Number||Length of the FLV in seconds. FLVMDI computes this value.|
|Width||Number||Width of the video in pixels.|
|Height||Number||Height of the video in pixels.|
|Videodatarate||Number||FLVMDI does not compute this value and imports it if present.|
|audiodatarate||Number||FLVMDI does not compute this value and imports it if present.|
|framerate||Number||FLVMDI computes this value, but uses imported value if present.|
|creationdate||String||FLVMDI does not compute this value and imports it if present.|
|lasttimestamp||Number||TimeStamp of the last tag in the FLV file.|
|lastkeyframetimestamp||Number||TimeStamp of the last video tag which is a key frame. Useful because seeking a frame after this time usually does not work.|
|filesize||Number||Filesize in bytes (including the injected data).|
|videosize||Number||Total size of video tags in the file in bytes.|
|audiosize||Number||Total size of audio tags in the file in bytes.|
|datasize||Number||Total size of data tags in the file in bytes.|
|metadatacreator||String||Set to ‘Manitu Group FLV Metadata Injector 2’.|
|metadatadate||Date||Date and time Metadata added.|
|xtradata||string||Additional string data if specified.|
|videocodecid||Number||Video codec ID number used in the FLV. (Sorenson H.263 =2, Screen Video =3, On2 VP6 = 4 and 5, Screen Video V2 = 6).|
|audiocodecid||Number||Audio codec ID number used in the FLV. (Uncompressed = 0, ADPCM = 1, MP3 = 2, NellyMoser = 5 and 6).|
|audiodelay||Number||Audio delay in seconds. Flash 8 Video Encoder delays the video for better synch with audio. Cue points added with F8VE are shifted by this delay to match their intended position when encoding.|
|canSeekToEnd||Boolean||True if the last video tag is a keyframe and, therefore, can be seeked.|
|keyframes||Object||This object is added only if you specify the /k switch, and contains two parallel arrays: ‘times’ in seconds, and ‘fileposition’ in bytes, that corresponds to each video keyframe.|
FLVMDI also has a GUI front end, seen in Figure 2, if you prefer not to work with command-line applications. It requires FLVMDI, but all you need to do to use it is put it in the same directory as FLVMDI. It puts a pretty face on the command-line interface and will be comfortable to designers and visual developers.
|Figure 2. Beyond the Command Line: The FLVMDIGUI is a graphical user interface for the FLVMDI command-line tool.|
Although FLVMDI is a Windows-only application, developers on other platforms are not lost. Norman Timmler’s flvtool2 is a similar command-line application that was developed with Ruby and will run on Windows, Mac OS X, and Linux.
flvtool2 works in much the same way that FLVMDI does, but without a GUI interface option. Developer Timmler’s Web site mentions a GUI in the works, but no firm details are available. However, using the command line is very simple. Just like with FLVMDI, a series of commands and optional switches may be used to achieve specific tasks.
Adding metadata is very similar to the approach used with FLVMDI, but with two differences: flvtool2 allows you to add any number of custom metadata key-value pairs, by reading them in from an XML file, and it also allows you to overwrite any specific generated key-value pair.
flvtool2 also offers a few additional features. It provides a few ways to gather information about the process. In addition to the option of printing all metadata to the terminal/console, it offers a verbose mode and debug mode. It also offers a simulation mode, which will go through the process without actually updating the FLV file. This allows you to check the results before making your changes final.
Most interesting, however, is the ability to segment FLV files into smaller files. You can provide in and out points, in milliseconds, and end up with as many new FLV files as you require, generated from your original.
An example usage, similar to the approach described previously for FLVMDI, is:
flvtool2 -UP nero.flv
This example updates the metadata in the FLV file and prints the metadata back to the terminal/console. A complete list of commands and switches can be seen in Table 3.
Table 3. flvtool2 Commands and Switches: This table details the commands and switches used by flvtool2.
|-U||Updates FLV with an onMetaTag event|
|-A||Adds tags from -t tags-file|
|-P||Prints out meta data to stdout|
|-D||Debugs file (writes a lot to stdout)|
|-C||Cuts file using -i inpoint and -o outpoint|
|-H||Helpscreen will be shown|
|-key:value||Key-value-pair for onMetadata tag (overwrites generated values)|
|-k||Keyframe mode slides onCuePoint(navigation) tags added by the add command to nearest keyframe position|
|-t path||tag file (MetaTags written in XML)|
|-x||XML mode instead of YAML mode|
|-c||Compatibility mode calculates some onMetaTag values differently|
|-i timestamp||In point for cut command in milliseconds|
|-o timestamp||Out point for cut command in milliseconds|
|-a||Collapse space between cut regions|
|-r||Recursion for directory processing|
|-p||Preserve mode only updates FLVs that have not been processed before|
|-s||Simulation mode never writes FLV data to out-path|
|-l||Logs FLV stream reading to stream.log in current directory|
|-n||Number of tag to debug|
There are a couple of wonderful extra features/benefits common to both tools. The first is the ability to batch process a large number of FLV files. The second is, because both tools use command-line instructions, they can be used in an automated workflow, including server-based operations. As mentioned previously, I’ll discuss server video options in a future article.
So, now you know how to make sure your metadata is in tip-top shape for optimal FLV use. If you have Flash 8, you already have a version of the Flash Video Encoder that will inject the correct minimal metadata into each FLV. If you’re using a third-party tool, like Flix Pro or Squeeze, be sure to use the most current version of your tool of choice to avoid problems. If, however, you’re late to upgrade or if you want to add custom tags or keyframe data for scripted seeking of video keyframes, the tools discussed herein should do the job.
This article just touches the surface of the Flash video world, focusing strictly on FLV metadata, how to use it, and how to add it when needed. Future articles will include a round up of encoding options, streaming and pseudo-streaming server options, using alpha data in Flash 8 videos, and more. If you would like to suggest topics for future Flash video coverage, let me know!