| Server IP : 180.180.241.3 / Your IP : 216.73.216.35 Web Server : Microsoft-IIS/7.5 System : Windows NT NETWORK-NHRC 6.1 build 7601 (Windows Server 2008 R2 Standard Edition Service Pack 1) i586 User : IUSR ( 0) PHP Version : 5.3.28 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/AppServ/www/news/components/com_youtubegallery/includes/flv4php/ |
Upload File : |
<?php
/**
* @Copyright 2006 Iván Montes
* @GNU General Public License
**/
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/*
Copyright 2006 Iván Montes, Morten Hundevad
This file is part of FLV tools for PHP (FLV4PHP from now on).
FLV4PHP is free software; you can redistribute it and/or modify it under the
terms of the GNU General var License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
FLV4PHP is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General var License for more details.
You should have received a copy of the GNU General var License along with
FLV4PHP; if not, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
define('FLV_INCLUDE_PATH', dirname(__FILE__) . '/');
define('FLV_SECRET_KEY', 'flv_key');
define('FLV_VERSION', 'V0.21');
require_once(FLV_INCLUDE_PATH . 'Tag.php');
require_once(FLV_INCLUDE_PATH . 'Util/AMFSerialize.php');
require_once(FLV_INCLUDE_PATH . 'Util/AMFUnserialize.php');
require_once(FLV_INCLUDE_PATH . 'getid3/getid3.php');
define('FLV_HEADER_SIGNATURE', 'FLV');
define('FLV_HEADER_SIZE', 9);
define('FLV_ERROR_BLOCKED', 'ERROR CODE: 1');
define('FLV_ERROR_INVALID', 'ERROR CODE: 2');
/**
* Parse a .flv file to extract all the 'tag' information
*/
class FLV {
/** The FLV header signature */
var $FLV_HEADER_SIGNATURE = FLV_HEADER_SIGNATURE;
/** The FLV main header size */
var $FLV_HEADER_SIZE = FLV_HEADER_SIZE;
/** The FLV tag header size */
var $TAG_HEADER_SIZE = FLV_TAG_HEADER_SIZE;
/**
Maximun number of bytes to process as tag body. This is a safety meassure against
corrupted FLV files.
*/
var $MAX_TAG_BODY_SIZE = FLV_TAG_MAX_BODY_SIZE;
var $filename;
var $_tempfilename;
var $metadata;
var $metadataend;
var $config;
var $_db_link_id;
var $lock_key;
// var $lock_id;
var $_fh;
var $_lastTagSize = 0;
var $_getID3 = NULL;
var $FileInfo = NULL;
var $error = NULL;
var $_nocashe = false;
function FLV( $fname = false, $timeout = 30 )
{
if($fname) return $this->open($fname,$timeout);
return false;
}
/*
*
* @param string $fname Locatsion of file
* @param int $timeout Script Time out default 30, when using external ling for downloading..
*
* @return true/false if success/failed.
*/
function open( $fname = false, $timeout = 30 )
{
$this->error = array();
if($fname) {
$this->filename = $fname;
$this->setKey(basename($fname, ".flv"));
$this->_nocashe = false;
$url = parse_url($fname);
if(!empty($url['scheme'])) {
if( !is_readable(FLV_INCLUDE_PATH) || !is_writable(FLV_INCLUDE_PATH) ) {
$this->_error_die('To Use External files you need to have: '. FLV_INCLUDE_PATH . ' chmod:777 ');
} elseif( $this->_tempfilename = tempnam(FLV_INCLUDE_PATH, "FLV") ) {
$this->_fh = @fopen($this->_tempfilename, "r+");
if (!$this->_fh) $this->_error_die('Unable to Open temporary file');
$tempcontent = file_get_contents($fname);
fwrite($this->_fh, $tempcontent);
$fname = $this->_tempfilename;
rewind($this->_fh);
} else $this->_error_die('Unable to Make temporary file');
} else {
$this->_fh = @fopen( $fname, 'r' );
if (!$this->_fh) $this->_error_die('Unable to open the file');
}
$this->_getID3 = new getID3();
$this->_getID3->setOption(array('encoding' => 'UTF-8'));
$AutoGetHashes = (bool) (filesize($fname) < 52428800); // auto-get md5_data, md5_file, sha1_data, sha1_file if filesize < 50MB
$this->_getID3->setOption(array('option_md5_data' => $AutoGetHashes,'option_sha1_data' => $AutoGetHashes));
$this->FileInfo = $this->_getID3->analyze($fname);
$hdr = fread( $this->_fh, $this->FLV_HEADER_SIZE );
//check file header signature
if ( substr($hdr, 0, 3) !== $this->FLV_HEADER_SIGNATURE ) $this->_error_die('The header signature does not match');
$this->version = ord($hdr[3]);
$this->hasVideo = (bool)(ord($hdr[4]) & 0x01);
$this->hasAudio = (bool)(ord($hdr[4]) & 0x04);
$this->bodyOfs = (ord($hdr[5]) << 24) +
(ord($hdr[6]) << 16) +
(ord($hdr[7]) << 8) +
(ord($hdr[8]));
$this->eof = false;
$this->getMetaData();
return true;
}
return false;
}
/**
* Move to beginning of the File ( after first header )
*/
function start()
{
fseek( $this->_fh, $this->bodyOfs );
$this->eof = false;
}
/**
* Close a previously open FLV file
*/
function close()
{
fclose( $this->_fh );
if(!empty($this->_tempfilename)) unlink($this->_tempfilename);
}
/**
* Close a previously open FLV file
*/
function _error_die($msg)
{
$this->close();
$this->error[] = $msg;
die($msg);
}
/**
* Returns the MetaData Tag
*
* @return object return metadata object
*/
function getMetaData()
{
$this->start();
$hdr = fread( $this->_fh, $this->TAG_HEADER_SIZE );
if (strlen($hdr) < $this->TAG_HEADER_SIZE) {
$this->eof = true;
return NULL;
}
// Get the tag object by skiping the first 4 bytes which tell the previous tag size
$tag = FLV_Tag::getTag( substr( $hdr, 4 ) );
// Read at most MAX_TAG_BODY_SIZE bytes of the body
$bytesToRead = min( $this->MAX_TAG_BODY_SIZE, $tag->size );
$tag->setBody( fread( $this->_fh, $bytesToRead ) );
// Check if the tag body has to be processed
$tag->analyze();
// If the tag was skipped or the body size was larger than MAX_TAG_BODY_SIZE
if ($tag->size > $bytesToRead) fseek( $this->_fh, $tag->size-$bytesToRead, SEEK_CUR );
$this->_lastTagSize = $tag->size + $this->TAG_HEADER_SIZE - 4;
$this->metadata = $tag->data;
$this->metadataend = ftell($this->_fh);
return $tag;
}
/**
* Returns the MetaData string
*
* @param array $newMetaData Array with new metadata
* @param string $merge Merge original array with new one
*
* @return string New Metadata + next tag's previous size
*/
function createMetaData($newMetaData = false,$merge = true)
{
//if the metadata is pressent in the file merge it with the generated one
$amf = new FLV_Util_AMFSerialize();
if (is_array($newMetaData)) {
if($merge && is_array($this->metadata)) $newMetaData = array_merge( $this->metadata, $newMetaData );
$metadata = $newMetaData;
} else $metadata = $this->metadata;
$metadata['metadatacreator'] = 'FLV Editor for PHP '.FLV_VERSION.' (Project: Flv4php)';
$serMeta = $amf->serialize('onMetaData') . $amf->serialize($metadata);
$out = pack('N', 0); // PreviousTagSize
$out.= pack('C', FLV_TAG_TYPE_DATA); // Type
$out.= pack('Cn', "\x00", strlen($serMeta)); // BodyLength assumes it's shorter than 64Kb
$out.= pack('N', 0); // Time stamp (not used)
$out.= pack('Cn', 0, 0); // Stream ID (not used) <---- WHERE IS THIS comming from
$out.= $serMeta; // Metadata Body
$out.= pack('N', strlen($serMeta) + 1 + 3 + 4 + 3); // PreviousTagSize
return $out;
}
/**
* Play the flv and close file after
*
* @param int $limitSpeed Limit speed of downloading, calculated off videorate + audiorate + $limitSpeed
* @param int $seekat Start playback at..
* @param array $newMetaData Array with new metadata
* @param bool $merge Merge original array with new one
*/
function playFlv($limitSpeed = 0,$seekat = 0,$newMetaData = false,$merge = true)
{
session_write_close();
if ($seekat != 0) {
fseek($this->_fh, $seekat);
} else {
if (!is_array($newMetaData)) $newMetaData = $this->defaultMetaData();
$metadata = $this->createMetaData($newMetaData,$merge);
rewind($this->_fh); // Rewind the movie
fseek($this->_fh, $this->metadataend+4); // Skip the Original metadata
}
if ($limitSpeed) {
if ($this->FileInfo['bitrate']) $limitSpeed = ceil(($this->FileInfo['bitrate']/100)/8)+$limitSpeed-1;
else $limitSpeed = false;
}
if ($metadata) $size = strlen($metadata) + ( filesize($this->filename) - ftell($this->_fh) ) + 9;
else $size = filesize($this->filename) - ftell($this->_fh) + 9;
$this->setHeader($size);
header("Content-Disposition: filename=".basename($this->filename));
print("FLV");
print(pack('C', 1 ));
print(pack('C', 5 ));
print(pack('N', 9 ));
if ($seekat) {
print(pack('N', 9 ));
} else {
print($metadata);
}
set_time_limit(0);
// print(fread($this->_fh, 50000));
print(fread($this->_fh, 5000));
while(!feof($this->_fh)) {
if ($limitSpeed) {
print(fread($this->_fh, round($limitSpeed*(1024/32))));
flush();
usleep(31250);
} else {
print(fread($this->_fh, 1024));
}
}
$this->close();
}
/**
* Play the flv with lock and close file after
*
* @param int $limitSpeed Limit speed off downloading, calculated off videorate + audiorate + $limitSpeed
* @param int $seekat Start playback at..
* @param array $newMetaData Array off new metadata
* @param bool $merge Merge original array with new one
* @param bool $usedb use database for key veryfying
*/
function playFlvLock($limitSpeed = 0,$seekat = 0,$newMetaData = false,$merge = true,$usedb = false)
{
$this->_nocashe = true;
if ( $this->validLock($usedb) ) {
$this->playFlv($limitSpeed,$seekat,$newMetaData,$merge);
} else {
$this->error[] = FLV_ERROR_INVALID;
$this->close();
}
}
/**
* Get Flv Thumb output's a thumb clip from offset point, locate a key frame and from there output's duration
* if no key frame is found it use the first key frame.
*
* @param int $offset Offset in ms
* @param bool $usemetadata Use metadata to attempt to find first keyframe
*
* @return string Single Flv keyframe
*/
function getFlvThumb($offset=2000,$usemetadata=true) {
session_write_close();
$this->start();
$skipTagTypes = array();
$skipTagTypes[FLV_TAG_TYPE_AUDIO] = FLV_TAG_TYPE_AUDIO;
if ($usemetadata && $offset && $this->metadata['keyframes']['times']) {
foreach ( $this->metadata['keyframes']['times'] as $key => $value){
if ( $value >= ($offset/1000) ) {
$offset = $value*1000;
fseek($this->_fh,$this->metadata['keyframes']['filepositions'][$key]-4);
break;
}
}
}
while ($tag = $this->getTag($skipTagTypes)) {
if ( $tag->type == FLV_TAG_TYPE_VIDEO ) {
if ($tag->timestamp >= $offset && $tag->frametype == 1 ) {
rewind($this->_fh);
fseek($this->_fh, $tag->start );
$dataOut = fread($this->_fh, ( ( $tag->end + 4 ) - $tag->start ) );
$this->replaceTimestamp($dataOut,0);
break;
}
}
//Does it actually help with memory allocation?
unset($tag);
}
if(!$dataOut) {
$offset = 0;
$this->start();
while ($tag = $this->getTag($skipTagTypes)) {
if ( $tag->type == FLV_TAG_TYPE_VIDEO ) {
if ($tag->timestamp >= $offset && $tag->frametype == 1 ) {
rewind($this->_fh);
fseek($this->_fh, $tag->start);
$dataOut = fread($this->_fh, ( ( $tag->end + 4 ) - $tag->start ) );
$this->replaceTimestamp($dataOut,0);
break;
}
}
//Does it actually help with memory allocation?
unset($tag);
}
}
$newMetaData = $this->defaultMetaData(false);
unset($newMetaData['keyframes']['times']);
$newMetaData['keyframes']['times'][] = 0;
//
unset($newMetaData['keyframes']['filepositions']);
$newMetaData['keyframes']['filepositions'][] = 0;
//
$newMetaData['duration'] = $newMetaData['datasize'] = $newMetaData['audiosize'] = $newMetaData['videosize'] = $newMetaData['filesize'] = $newMetaData['audiodatarate'] = $newMetaData['audiocodecid'] = $newMetaData['lastkeyframetimestamp'] = $newMetaData['lasttimestamp'] = $newMetaData['framerate'] = 0;
$metadata = $this->createMetaData($newMetaData,true);
$sizeMetaData = strlen($metadata);
$newMetaData = array();
$newMetaData = $this->defaultMetaData(false);
unset($newMetaData['keyframes']['times']);
$newMetaData['keyframes']['times'][] = 0;
//
unset($newMetaData['keyframes']['filepositions']);
$newMetaData['keyframes']['filepositions'][] = 0;
//
$newMetaData['lastkeyframetimestamp'] = $newMetaData['lasttimestamp'] = $newMetaData['framerate'] = $newMetaData['duration'] = $newMetaData['audiosize'] = $newMetaData['audiodatarate'] = $newMetaData['audiocodecid'] = 0;
$newMetaData['datasize'] = $sizeMetaData;
$newMetaData['videosize'] = strlen($dataOut);
$newMetaData['filesize'] = $sizeMetaData + strlen($dataOut) + FLV_HEADER_SIZE;
$metadata = $this->createMetaData($newMetaData,true);
$this->setHeader(strlen($metadata) + strlen($dataOut) + FLV_HEADER_SIZE);
header("Content-Disposition: filename=".basename($this->filename));
$this->close();
return "FLV".pack('C', 1 ).pack('C', 1 ).pack('N', 9 ).$metadata.$dataOut;
}
/**
* Get Flv Preview output's a Preview clip from offset point, locate a key frame and from there output's duration
* if no key frame is found it use the first key frame.
*
* @param int $offset Offset in ms
* @param int $duration Duration in ms
* @param bool $usemetadata Use metadata to attempt to find first keyframe
* @param int $speedModifyer Playback Speed modifier
*
* @return string Flv File preview
*/
function getFlvPreview($offset=2000,$duration=2000,$usemetadata=true,$speedModifyer=100) {
session_write_close();
$speedModifier = (int) $speedModifier;
if ($speedModifier < 1) $speedModifier = 1;
$this->dataArray = array();
$this->start();
$skipTagTypes = array();
$skipTagTypes[FLV_TAG_TYPE_AUDIO] = FLV_TAG_TYPE_AUDIO;
if ( !is_array($offset) || !is_array($duration) ) {
$currentOffset[0] = $offset;
$currentDuration[0] = $duration;
} else {
$currentOffset = $offset;
$currentDuration = $duration;
}
$totalDuration = $lastKeyframe = 0;
if($usemetadata && $currentOffset[0] && $this->metadata['keyframes']['times']) {
foreach($this->metadata['keyframes']['times'] as $metakey => $metavalue){
if($metavalue >= ($currentOffset[0]/1000)) {
$offset = $metavalue*1000;
fseek($this->_fh,$this->metadata['keyframes']['filepositions'][$metakey]-4);
break;
}
}
}
foreach($currentOffset as $offsetKey => $offset) {
if ( !$currentDuration[$offsetKey] ) $currentDuration[$offsetKey] = $currentDuration[0];
$endFouned = false;
$index = $startTimestamp = 0;
$endTimestamp = $totalDuration;
while($tag = $this->getTag($skipTagTypes)) {
if($tag->type == FLV_TAG_TYPE_VIDEO) {
if(!$this->dataArray[$offsetKey] && $tag->timestamp >= $offset && $tag->frametype == 1 ) {
$startTimestamp = $tag->timestamp;
rewind($this->_fh);
fseek($this->_fh, $tag->start);
$this->dataArray[$offsetKey][$index++] = fread($this->_fh, ($tag->end - $tag->start));
if ( $totalDuration ) {
$this->replaceTimestamp($this->dataArray[$offsetKey][$index-1],$totalDuration+10);
} else {
$this->replaceTimestamp($this->dataArray[$offsetKey][$index-1],0);
}
rewind($this->_fh);
fseek($this->_fh, $tag->end);
} elseif($this->dataArray[$offsetKey]) {
$endTimestamp = $totalDuration + $this->modifyTimestamp(($tag->timestamp-$startTimestamp),$speedModifyer);
if($tag->frametype == 1) $lastKeyframe = $endTimestamp;
rewind($this->_fh);
fseek($this->_fh, $tag->start);
$this->dataArray[$offsetKey][$index++] = fread($this->_fh, ($tag->end - $tag->start));
$this->replaceTimestamp($this->dataArray[$offsetKey][$index-1], $endTimestamp);
rewind($this->_fh);
fseek($this->_fh, $tag->end);
if($tag->timestamp >= ($currentDuration[$offsetKey]+$startTimestamp)) {
$endFouned = true;
break;
}
}
}
//Does it actually help with memory allocation?
unset($tag);
}
if(!$endFouned && !$this->dataArray[1]) {
unset($this->dataArray[$offsetKey]);
$index = $offset = $lastKeyframe = $startTimestamp = $endTimestamp = 0;
$this->start();
while($tag = $this->getTag($skipTagTypes)) {
if($tag->type == FLV_TAG_TYPE_VIDEO) {
if(!$this->dataArray[$offsetKey] && $tag->timestamp >= $offset && $tag->frametype == 1 ) {
$startTimestamp = $tag->timestamp;
rewind($this->_fh);
fseek($this->_fh, $tag->start);
$this->dataArray[$offsetKey][$index++] = fread($this->_fh, ($tag->end - $tag->start));
$this->replaceTimestamp($this->dataArray[$offsetKey][$index-1],0);
rewind( $this->_fh );
fseek( $this->_fh, $tag->end );
} elseif($this->dataArray[$offsetKey]) {
$endTimestamp = $this->modifyTimestamp(($tag->timestamp-$startTimestamp),$speedModifyer);
if($tag->frametype == 1) $lastKeyframe = $endTimestamp;
rewind($this->_fh);
fseek($this->_fh,$tag->start);
$this->dataArray[$offsetKey][$index++] = fread($this->_fh, ($tag->end - $tag->start));
$this->replaceTimestamp($this->dataArray[$offsetKey][$index-1],$endTimestamp);
rewind($this->_fh);
fseek($this->_fh, $tag->end);
}
}
if ($tag->timestamp >= ($currentDuration[$offsetKey]+$startTimestamp)) break;
//Does it actually help with memory allocation?
unset($tag);
}
}
$totalDuration = $endTimestamp;
if(!$endFouned) break;
}
$dataOut = '';
$lastSize = 0;
foreach($this->dataArray as $key => $value) {
foreach($this->dataArray[$key] as $key2 => $value2) {
if( $key || $key2 ) $dataOut = $dataOut.pack('N', $lastSize ).$value2;
else $dataOut = $value2;
$lastSize = strlen($value2);
}
}
$newMetaData = array();
$newMetaData = $this->defaultMetaData(true);
unset($newMetaData['keyframes']['times']);
$newMetaData['keyframes']['times'][] = 0;
//
unset($newMetaData['keyframes']['filepositions']);
$newMetaData['keyframes']['filepositions'][] = 0;
$newMetaData['duration'] = ( $totalDuration / 1000 );
$newMetaData['datasize'] = $newMetaData['audiosize'] = $newMetaData['videosize'] = $newMetaData['filesize'] = $newMetaData['audiodatarate'] = $newMetaData['audiocodecid'] = 0;
$newMetaData['hasmetadata'] = true;
$newMetaData['haskeyframes'] = true;
$newMetaData['lastkeyframetimestamp'] = $lastKeyframe;
$newMetaData['lasttimestamp'] = $totalDuration;
$metadata = $this->createMetaData($newMetaData,true);
$sizeMetaData = strlen($metadata);
$newMetaData = array();
$newMetaData = $this->defaultMetaData(true);
unset($newMetaData['keyframes']['times']);
$newMetaData['keyframes']['times'][] = 0;
//
unset($newMetaData['keyframes']['filepositions']);
$newMetaData['keyframes']['filepositions'][] = $sizeMetaData + FLV_HEADER_SIZE;
//
$newMetaData['duration'] = ( $totalDuration / 1000 );
$newMetaData['datasize'] = $sizeMetaData;
$newMetaData['audiosize'] = $newMetaData['audiodatarate'] = $newMetaData['audiocodecid'] = 0;
$newMetaData['videosize'] = strlen($dataOut);
$newMetaData['filesize'] = $sizeMetaData + strlen($dataOut) + FLV_HEADER_SIZE;
$newMetaData['hasmetadata'] = true;
$newMetaData['haskeyframes'] = true;
$newMetaData['lastkeyframetimestamp'] = $lastKeyframe;
$newMetaData['lasttimestamp'] = $totalDuration;
$metadata = $this->createMetaData($newMetaData,true);
$this->setHeader(strlen($metadata) + strlen($dataOut) + FLV_HEADER_SIZE);
header("Content-Disposition: filename=".basename($this->filename));
$this->close();
return "FLV".pack('C', 1).pack('C', 1).pack('N', 9).$metadata.$dataOut;
}
/**
* Download Flv
*
* @param int $limitSpeed Limit speed off downloading, calculated off videorate + audiorate + $limitSpeed
* @param array $newMetaData Array off new metadata
* @param bool $merge Merge original array with new one
*/
function downloadFlv($limitSpeed = 0,$newMetaData = false,$merge = true)
{
session_write_close();
$this->setHeader(filesize($this->filename));
header("Content-Disposition: attachment; filename=".basename($this->filename));
print("FLV");
print(pack('C', 1 ));
print(pack('C', 5 ));
print(pack('N', 9 ));
if(!is_array($newMetaData)) $newMetaData = $this->defaultMetaData();
print($this->createMetaData($newMetaData,$merge));
rewindcs($this->_fh); // Rewind the movie
fseek($this->_fh, $this->metadataend+4); // Skip the Original metadata
if($limitSpeed) {
if ($this->FileInfo['bitrate']) $limitSpeed = ceil(($this->FileInfo['bitrate']/100)/8)+$limitSpeed-1;
// if ($this->metadata["videodatarate"] || $this->metadata["audiodatarate"]) $limitSpeed = ceil(($this->metadata["videodatarate"]+$this->metadata["audiodatarate"])/8)+$limitSpeed-1;
else $limitSpeed = false;
}
set_time_limit(0);
while(!feof($this->_fh)) {
if($limitSpeed) {
print(fread($this->_fh, round($limitSpeed*(1024/32))));
flush();
usleep(31250);
} else {
print(fread($this->_fh, 1024));
}
}
$this->close();
}
/*
* Flv php header
*
* @param int $size Size of file.
*/
function setHeader($size=0)
{
header("Content-Type: video/x-flv");
// header("Content-Type: text/plain");
header("Content-Length: " .(string)$size);
if($this->_nocashe) {
// Date in the past
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// always modified
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
// HTTP/1.1
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
} else {
// calc an offset of 24 hours
$offset = 3600 * 24;
// calc the string in GMT not localtime and add the offset
$expire = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
//output the HTTP header
header($expire);
}
}
/**
* Open a lock used when playing with playFlvLock.
*
* @param string $key Key Name
* @param int $validtime Defines how long time a key is valid
* @param bool $usedb Use Database key storage?
*
* @return true/false if sucess/failed.
*/
function openLock($key=false,$validtime=30,$usedb=false)
{
if(!$key) return false;
if(!session_id()) session_start();
if($usedb) {
$this->loadConfig();
$sid = session_id();
$expire = time()+$validtime;
$ip = $_SERVER['REMOTE_ADDR'];
$this->dbConnect();
$result = mysql_list_tables ( $this->config['db_name'] ,$this->_db_link_id);
$tableKey = $this->config['db_table_prefix']."key";
$tableBlock = $this->config['db_table_prefix']."block";
$maketableKey = true;
$maketableBlock = true;
while($row = mysql_fetch_row($result)) {
if($row[0] == $tableKey) $maketableKey = false;
elseif($row[0] == $tableBlock) $maketableBlock = false;
}
if($maketableKey) {
$query="CREATE TABLE `".$tableKey."` ( `uid` SMALLINT( 5 ) AUTO_INCREMENT , `sid` VARCHAR( 35 ) NOT NULL , `key` VARCHAR( 50 ) NOT NULL , `timeout` INT( 20 ) NOT NULL , `ip` VARCHAR( 15 ) NOT NULL , PRIMARY KEY ( `uid` ) ) TYPE = MYISAM";
if (!mysql_query($query)) $this->_error_die(mysql_error());
}
if($maketableBlock) {
$query="CREATE TABLE `".$tableBlock."` (`uid` SMALLINT( 5 ) AUTO_INCREMENT ,`ip` VARCHAR( 15 ) NOT NULL ,`count` SMALLINT( 5 ) DEFAULT '0',PRIMARY KEY ( `uid` ) ) TYPE = MYISAM";
if (!mysql_query($query)) $this->_error_die(mysql_error());
}
$query = "SELECT uid FROM ".$tableKey." WHERE `sid` LIKE '$sid' AND `key` LIKE '$key' LIMIT 1";
$result = mysql_query($query);
$rowKey = mysql_fetch_assoc($result);
if($rowKey['uid']) $query = "UPDATE ".$tableKey." SET timeout = $expire , ip = '$ip' WHERE uid = ".$rowKey['uid'];
else $query = "INSERT INTO ".$tableKey." VALUES ('','$sid','$key','$expire','$ip')";
@mysql_query($query);
mysql_close($this->_db_link_id);
} else {
$_SESSION[FLV_SECRET_KEY][$key] = time()+$validtime;
}
return true;
}
/**
* Close a Lock used when playing with playFlvLock.
*
* @param int $lock_id uid in Database
*/
function closeLock($lock_id = 0)
{
if($lock_id) {
$this->loadConfig();
$this->dbConnect();
$sid = session_id();
$timeout = time();
$tableKey = $this->config['db_table_prefix']."key";
$tableBlock = $this->config['db_table_prefix']."block";
$query = "DELETE FROM `".$tableKey."` WHERE `uid` = '$lock_id' AND `sid` LIKE '$sid' AND `key` LIKE '$this->lock_key'";
if (!mysql_query($query)) $this->_error_die(mysql_error());
mysql_close($this->_db_link_id);
}
unset($_SESSION[FLV_SECRET_KEY][$this->lock_key]);
}
/**
* Play the flv with lock
*
* @param bool $usedb Check in database
*
* @return true/false if sucess/failed.
*/
function validLock($usedb=false)
{
if(!session_id()) session_start();
$return = false;
if($usedb) {
$this->loadConfig();
$this->dbConnect();
$ip = $_SERVER['REMOTE_ADDR'];
$tableKey = $this->config['db_table_prefix']."key";
$tableBlock = $this->config['db_table_prefix']."block";
$query = "SELECT count FROM ".$tableBlock." WHERE `ip` LIKE '$ip' LIMIT 1";
$result = mysql_query($query);
$rowBlock = mysql_fetch_assoc($result);
$sid = session_id();
$timeout = time();
$query = "SELECT uid FROM ".$tableKey." WHERE `sid` LIKE '$sid' AND `key` LIKE '$this->lock_key' AND `timeout` >= $timeout LIMIT 1";
$result = mysql_query($query);
$rowKey = mysql_fetch_assoc($result);
if($rowKey['uid'] && ($this->config['block_counter'] > $rowBlock['count'] || !$rowBlock['count'])) $return = true;
elseif($this->config['block_counter']) {
$query = "SELECT uid FROM ".$tableBlock." WHERE `ip` LIKE '$ip' LIMIT 1";
$result = mysql_query($query);
$rowBlock = mysql_fetch_assoc($result);
if($rowBlock['uid']) $query = "UPDATE ".$tableBlock." SET count = count+1 WHERE uid = ".$rowBlock['uid'];
else $query = "INSERT INTO ".$tableBlock." VALUES ('','$ip','1')";
@mysql_query($query);
$this->error[] = FLV_ERROR_BLOCKED;
}
mysql_close($this->_db_link_id);
} elseif($_SESSION[FLV_SECRET_KEY][$this->lock_key] >= time()) {
$return = true;
}
$this->closeLock($rowKey['uid']);
return $return;
}
/**
* Play the flv with lock
*
* @param string $key Set Key
*/
function setKey($key)
{
$this->lock_key = $key;
}
/**
* Returns the next tag from the open file
*
* @param array $skipTagTypes The tag types contained in this array won't be examined
*
* @return object FLV_Tag_Generic or one of its descendants
*/
function getTag( $skipTagTypes = false )
{
if ($this->eof) return NULL;
$hdr = fread( $this->_fh, $this->TAG_HEADER_SIZE );
if (strlen($hdr) < $this->TAG_HEADER_SIZE) {
$this->eof = true;
return NULL;
}
// check against corrupted files
$prevTagSize = unpack( 'Nprev', $hdr );
// if ($prevTagSize['prev'] != $this->_lastTagSize) die("<br>Previous tag size check failed. Actual size is ".$this->_lastTagSize." but defined size is ".$prevTagSize['prev']);
// Get the tag object by skiping the first 4 bytes which tell the previous tag size
$tag = FLV_Tag::getTag( substr( $hdr, 4 ) );
// Read at most MAX_TAG_BODY_SIZE bytes of the body
$bytesToRead = min( $this->MAX_TAG_BODY_SIZE, $tag->size );
$tag->setBody( fread( $this->_fh, $bytesToRead ) );
// Check if the tag body has to be processed
if ((is_array($skipTagTypes) && !in_array($tag->type, $skipTagTypes)) || !$skipTagTypes) $tag->analyze();
// If the tag was skipped or the body size was larger than MAX_TAG_BODY_SIZE
if ($tag->size > $bytesToRead) fseek($this->_fh, $tag->size-$bytesToRead, SEEK_CUR);
$this->_lastTagSize = $tag->size + $this->TAG_HEADER_SIZE - 4;
$tag->start = $this->getTagOffset();
$tag->end = ftell($this->_fh);
return $tag;
}
/**
* Returns the offset from the start of the file of the last processed tag
*
* @return int get offset
*/
function getTagOffset()
{
return ftell($this->_fh) - $this->_lastTagSize;
}
/**
* Connect to Database
*/
function dbConnect()
{
$this->loadConfig();
// connect to the mysql database server.
$this->_db_link_id = mysql_connect ($this->config['db_host'], $this->config['db_username'], $this->config['db_password']);
// sellect db
if (!mysql_select_db($this->config['db_name'])) $this->_error_die(mysql_error());
}
/**
* Load Config
*/
function loadConfig()
{
if( empty($this->config) ) {
$config = array();
require(FLV_INCLUDE_PATH.'config.php');
$this->config = $config;
}
}
/**
* defaultMetaData
*
* @return array default Metadata
*/
function defaultMetaData($supressGetId3=false)
{
$buffMetaData = array();
if(!$supressGetId3) {
// $buffMetaData = $this->FileInfo;
$buffMetaData = $this->FileInfo['meta']['onMetaData'];
$buffMetaData['flv'] = $this->FileInfo['flv'];
$buffMetaData['video'] = $this->FileInfo['video'];
$buffMetaData['audio'] = $this->FileInfo['audio'];
$buffMetaData['bitrate'] = $this->FileInfo['bitrate'];
}
$buffMetaData['width'] = $this->FileInfo['video']['resolution_x'];
$buffMetaData['height'] = $this->FileInfo['video']['resolution_y'];
$buffMetaData['metadatacreator'] = 'FLV Editor for PHP '.FLV_VERSION.' (Project: Flv4php)';
$buffMetaData['creator'] = 'FLV Editor for PHP '.FLV_VERSION." (Project: Flv4php)";
$buffMetaData['metadatadate'] = gmdate('Y-m-d\TH:i:s') . '.000Z';
return (array) $buffMetaData;
}
/**
* defaultMetaData replace timestamp in frame with new one
*/
function replaceTimestamp(&$frame,$newTimestamp)
{
$frame[4] = chr($newTimestamp >> 16);
$frame[5] = chr($newTimestamp >> 8);
$frame[6] = chr($newTimestamp);
$frame[7] = chr($newTimestamp >> 24);
}
/**
* defaultMetaData replace timestamp in frame with new one
*
* @return int Modifyed timestamp
*/
function modifyTimestamp($timestamp,$modifyer=100)
{
if ($modifyer < 1) $modifyer = 1;
return (int) ceil((100*$timestamp)/$modifyer);
}
}
?>