FLV File Documentation


Summary

A file with the .flv extension is a Flash Video file: a binary container that Adobe Flash used to stream video and audio over the web through the 2000s. It is a linear media stream, not an interactive Flash application, so it holds H.263, VP6, or H.264 video with MP3 or AAC audio in a simple tag-based packet layout. Its MIME type is video/x-flv, and every file begins with the ASCII signature FLV (46 4C 56). Flash Player reached end-of-life on 31 December 2020, but the stream itself still plays in modern players such as VLC.

Technical details

FeatureValue
Full nameFlash Video
File extension.flv
MIME typevideo/x-flv
Format typeBinary multimedia container (tag-based packet stream)
DeveloperAdobe Systems (originally Macromedia; codecs from On2 / Sorenson)
Introduced2002 (Macromedia Flash MX / Flash Player 6)
Standard / specAdobe Flash Video File Format Specification (v10.1)
Open standardPartial (published by Adobe, frozen after Flash EOL)
Byte orderBig-endian
Magic number46 4C 56 01 (“FLV” + version byte)
Signature offset0
Header size9 bytes (standard)
Video codecsSorenson H.263, On2 VP6, H.264/AVC
Audio codecsMP3, AAC, ADPCM, Nellymoser
Tag typesAudio (0x08), Video (0x09), Script/metadata (0x12)
Successor containerF4V (ISO/MP4-based, uses ftyp box)
Flash Player EOL31 December 2020
Related extensions.f4v, .swf, .mp4, .m4v, .avi
File signature (magic bytes)
46 4C 56 01

Offset 0. The first three bytes are the ASCII string FLV (46 4C 56), followed by a version byte, normally 0x01. Byte 4 is a flags byte whose low bits mark whether audio (bit 2) and video (bit 0) are present; bytes 5–8 are a 32-bit big-endian DataOffset giving the header length, normally 00 00 00 09. A 4-byte PreviousTagSize0 of zero follows the header, then the tag stream begins. All multi-byte fields are big-endian. The related F4V container is different: it starts with an ISO/MP4 ftyp box, not FLV.

What is an FLV file?

FLV stands for Flash Video, the container Adobe (then Macromedia) introduced in 2002 with Flash Player 6 to deliver video over the web. For most of the following decade it was the dominant online video format: YouTube, Vimeo, Hulu and countless embedded players streamed FLV through the Flash browser plug-in. Its MIME type is video/x-flv. Inside, an FLV carries a linear video and audio stream, encoded with Sorenson Spark (H.263), On2 VP6, or later H.264 for video, and MP3 or AAC for audio.

The first thing to be clear about is what an FLV is not. It is not an SWF. An SWF is an interactive Flash application built from vector graphics, timelines and ActionScript code; an FLV is a plain video-plus-audio stream that a Flash player simply decoded and played back. Confusing the two is the most common misunderstanding about the format, and it matters for security: the exploit-prone, code-executing part of Flash was the SWF and the plug-in, never the FLV data stream. Everything below is about how the FLV container encodes its media, tag by tag.

The FLV header: signature, flags and DataOffset

Every FLV file begins with a fixed 9-byte header, so a parser can identify and validate the file from its first bytes.

Offset  Size  Field         Value / meaning
0       3     Signature     'F' 'L' 'V'  (46 4C 56)
3       1     Version       0x01
4       1     TypeFlags     bit0 = has video, bit2 = has audio (others reserved)
5       4     DataOffset    uint32 big-endian, header length in bytes (= 9)

The three ASCII bytes FLV are the magic number. The version byte is almost always 0x01. The TypeFlags byte declares which streams the file contains: bit 0 set means a video track is present, bit 2 means an audio track is present, and a value of 0x05 therefore means both. DataOffset is a 32-bit big-endian value giving the length of the header, which is 9 for version 1; it exists so future headers could grow while parsers keep skipping to the first tag correctly. Every multi-byte integer in FLV is big-endian.

PreviousTagSize and the tag stream

After the header, the file body is a back-to-back sequence of tags, each preceded in the stream by a 4-byte PreviousTagSize field. The very first one, PreviousTagSize0, is always zero because no tag precedes it. After every tag comes a PreviousTagSize equal to the total byte length of the tag just written, header included.

[9-byte FLV header]
PreviousTagSize0 = 0            (uint32)
Tag 1
PreviousTagSize1 = len(Tag 1)  (uint32 = 11 + DataSize of Tag 1)
Tag 2
PreviousTagSize2 = len(Tag 2)
...

These back-pointers let a player walk the file backwards as well as forwards, which is how simple seeking works without a separate index: from any point a reader can jump to the previous tag boundary by subtracting the stored size. For FLV version 1 the value is 11 + DataSize, because every tag carries an 11-byte tag header in front of its payload.

The tag header: type, size and timestamp

Each tag opens with an 11-byte header that names the kind of data, its length, and when it should be presented.

Offset  Size  Field
0       1     TagType         0x08 audio, 0x09 video, 0x12 script data
1       3     DataSize        uint24, length of the tag payload
4       3     Timestamp       uint24, milliseconds (lower 24 bits)
7       1     TimestampExt    high 8 bits of the timestamp
8       3     StreamID        always 0
11      ...   Data            the payload (audio / video / script)

The TagType byte is the discriminator: 0x08 is an audio tag, 0x09 a video tag, and 0x12 a script-data (metadata) tag. DataSize is a 24-bit length, so a single tag payload is capped at 16 MB, which is ample for one frame. The timestamp is unusual: it is a 24-bit millisecond value in the header, extended by a separate TimestampExtended byte that supplies the high 8 bits, together forming a 32-bit millisecond clock so long files do not overflow. StreamID is always zero in a file. Because tags are self-describing and interleaved, a player reads audio and video tags in timestamp order and feeds each to the right decoder.

Video and audio tag payloads

A video tag’s payload starts with a one-byte header splitting into a 4-bit FrameType (1 = keyframe, 2 = inter frame) and a 4-bit CodecID. The codec IDs include 2 for Sorenson H.263, 4 for On2 VP6, and 7 for H.264/AVC. When the codec is H.264, the payload is further prefixed with an AVCPacketType byte and a composition-time offset, and the very first video tag carries the AVC sequence header (the SPS and PPS parameter sets) rather than a frame, so the decoder can be initialised before any picture arrives.

An audio tag’s payload begins with a one-byte header that packs the sound format (0 = uncompressed, 2 = MP3, 10 = AAC, 11 = Speex, and others) into the top 4 bits, then sample rate, sample size and mono/stereo flags into the remaining bits. As with H.264 video, AAC audio sends a sequence header first (the AudioSpecificConfig) before the raw AAC frames. This split — a small header describing the stream, followed by coded frames — is what lets one FLV carry several codec combinations without changing the container itself.

Script-data tags and onMetaData

Script-data tags (TagType 0x12) carry metadata encoded in the Action Message Format (AMF), the same serialisation Flash used at runtime. The most important one is the onMetaData object, usually the first tag in the file. It is an AMF-encoded associative array holding fields such as duration, width, height, framerate, videocodecid, audiocodecid and filesize. A player reads onMetaData up front so it can display the running time and dimensions and size its window before decoding any media. Because these values are written after encoding finishes, a live-captured or interrupted FLV sometimes has a missing or zero duration, which is why some old FLV files report the wrong length until they are remuxed.

FLV against SWF and F4V

Three Flash-era extensions are routinely mixed up. An SWF is an interactive application; an FLV is a video stream; and F4V is Adobe’s later video container. F4V abandoned the tag-based FLV layout and adopted the ISO Base Media File Format — the same box structure used by MP4 and MOV — so an F4V file starts with an ftyp box, not the FLV signature. Adobe introduced F4V for H.264 content, but the older .flv extension persisted for legacy files and for H.264-in-FLV streams. Because FLV’s later H.264/AAC payloads are the same coded bitstreams that MP4 stores, converting such an FLV to MP4 is frequently a lossless remux: the coded frames are copied unchanged into an MP4 box structure and only the container is rewritten.

Playing FLV after Flash end-of-life

Flash Player reached end-of-life on 31 December 2020 and has been blocked since January 2021, so the original delivery mechanism no longer exists. This does not make FLV files unreadable, because an FLV is an ordinary media stream, not Flash code. Players that bundle their own decoders — VLC, MPC-HC, PotPlayer — open FLV files with no Flash runtime involved: they parse the tag stream, pull the H.263/VP6/H.264 frames and MP3/AAC audio, and decode them directly. What has disappeared is native browser and device support, since the web moved to HTML5 with MP4/H.264 and WebM. The practical consequence is that FLV survives mainly as archived files, and the common next step is to remux or transcode them into a container modern devices play.

References