[1.7.7/1.7.8b1] Multiple large FLV files bog down servers

Think you found a bug in getID3()? Post here with details.
Post Reply
mjs
User
Posts: 9
Joined: Thu Nov 30, 2006 8:19 am

[1.7.7/1.7.8b1] Multiple large FLV files bog down servers

Post by mjs » Mon Mar 03, 2008 11:59 pm

If I have a directory with many FLV files (say a dozen or so) and they all have long durations or large file sizes, the server starts to choke on reading all the FLV metadata. It appears that the getID3 FLV metadata reader starts to read the metadata of the FLV file from the beginning and continues through the entire file until it reaches the end, as seems apparent in line 184 of module.audio-video.flv.php...

fseek($fd, $NextOffset, SEEK_SET);

For my needs with FLV files, I only need a few metadata info; duration, width, height, frame-rate and any available audio metadata. If I change the above line to...

fseek($fd, $NextOffset, SEEK_CUR);

it stops the continual building of metadata reading of the entire file but still gives me all of the other available metadata info I need *except* for duration.

But since I still need to get the FLV's duration, I've used a different script that's floating on the net for this, which looks like this...

Code: Select all

function GetFLVDuration($file) {
	if (file_exists($file)) {
		$handle   = fopen($file, "r");
		$contents = fread($handle, filesize($file));
		fclose($handle);
		
		if (strlen($contents) > 3) {
			if (substr($contents, 0, 3) == "FLV") {
				$taglen = hexdec(bin2hex(substr($contents, strlen($contents) - 3)));
				if (strlen($contents) > $taglen) {
					$duration = hexdec(bin2hex(substr($contents, strlen($contents) - $taglen, 3)));
					return $duration;
				}
			}
		}
	}
	return false;
}
However this method reads the entire FLV file in one gulp, which can cause the server to not read it if the file is too big (like one of my servers does). It gives me an error on line 4 if the file is too big. If the file isn't too big, this reads the metadata much, much faster than the getID3 method.

So either I use getID3 to read the metadata in build-form but can choke the server on big files OR I use the above script to read the entire file and refuses large files altogether.

Doing some further testing, I found that if I change the above script's line 4 to the following...

$contents = fread($handle, 15000);

so it reads the first 15k of the metadata contents from the file, I get a little metadata although encrypted. It gives the following if I echo $contents...

FLV��� ������

mjs
User
Posts: 9
Joined: Thu Nov 30, 2006 8:19 am

Post by mjs » Tue Mar 04, 2008 8:04 am

I think I've found a fix. I added this line after line 172...

$ThisFileInfo['video']['trt_duration'] = $ThisFileInfo['meta']['onMetaData']['duration'];

I then terminated the fseek loop by commenting out line 184. Of course this method relies on the idea that the user is encoding the FLV video with an encoder that embeds the duration metadata (some older FLV encoders do not), but this parses very fast on large FLV files where the regular method chokes server cycles (to a stand still in some cases) on large FLV files.

To call the FLV duration, I simply use the standard call based on the above extraction...

$fileData = $getID3->analyze($file);
$trt = $fileData['video']['trt_duration'];

This method may not work for everyone, but it solved my problem.

Thanks,

///Marco

Post Reply