There's a not too complicated way to do that.
FLV files have a specific data structure which allow them to be parsed in reverse order, assuming the file is well-formed.
Just fopen the file and seek 4 bytes before the end of the file.
You will get a big endian 32 bit value that represents the size of the tag just before these bytes (FLV files are made of tags). You can use the unpack
function with the 'N' format specification.
Then, you can seek back to the number of bytes that you just found, leading you to the start of the last tag in the file.
The tag contains the following fields:
- one byte signaling the type of the tag
- a big endian 24 bit integer representing the body length for this tag (should be the value you found before, minus 11... if not, then something is wrong)
- a big endian 24 bit integer representing the tag's timestamp in the file, in milliseconds, plus a 8 bit integer extending the timestamp to 32 bits.
So all you have to do is then skip the first 32 bits, and unpack('N', ...) the timestamp value you read.
As FLV tag duration is usually very short, it should give a quite accurate duration for the file.
Here is some 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 two last fseek can be factorized, but I left them both for clarity.
Edit: Fixed the code after some testing
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…