There is not too complicated way to do this.
FLV files have a specific data structure that allows them to be analyzed in the reverse order, assuming the file is well-formed.
Just copy the file and find 4 bytes to the end of the file.
You will get a 32-digit large-end value representing the size of the tag immediately before these bytes (FLV files are made from tags). You can use the unpack function with the format specification "N".
Then you can return to the number of bytes found, which will lead you to the beginning of the last tag in the file.
The tag contains the following fields:
- one byte signaling tag type
- a large 24-bit integer representing the body length for this tag (there should be a value that you found earlier, minus 11 ... if not, then something is wrong)
- a large 24-bit integer representing the timestamp of the label in the file, in milliseconds, plus an 8-bit integer that increments the timestamp to 32 bits.
So all you have to do is skip the first 32 bits and unzip ('N', ...) the timestamp you are reading.
Since the duration of the FLV tag is usually very short, it should give a fairly accurate duration for the file.
Here is a sample code:
$flv = fopen("flvfile.flv", "rb"); fseek($flv, -4, SEEK_END); $arr = unpack('N', fread($flv, 4)); $last_tag_offset = $arr[1]; fseek($flv, -($last_tag_offset + 4), SEEK_END); fseek($flv, 4, SEEK_CUR); $t0 = fread($flv, 3); $t1 = fread($flv, 1); $arr = unpack('N', $t1 . $t0); $milliseconds_duration = $arr[1];
The last two fseeks can be factorized, but I left them for clarity.
Edit: Fixed code after some testing
SirDarius
source share