Example #1
0
 public function write()
 {
     $amfSerializer = new FLV_Util_AMFSerialize();
     $metadata_data = array();
     // theses will be used as placeholders for dynamic data
     $metadata_data["canSeekToEnd"] = true;
     $metadata_data["duration"] = (int) ($this->duration / 1000);
     $metadata_data["timeOffset"] = 0;
     $metadata_data["bytesOffset"] = 0;
     // because of akamai seek limitation we want to limit metadata size to 16kb
     // 15K / 2 (times & positions arrays ) / 8 (bytes each) ~ 850
     // we will skip keyframes in order to use at most 850 of them
     $kf_cnt = count($this->keyframeTimes);
     // if there are more than 1 keyframe per second and file size < 100MB its probably and edit flavor and we should maintain all KF
     // we serve the file from our server and not the cdn anyway because the cdn cant clip the file
     $lastKF = $lastKFPos = 0;
     if ($kf_cnt) {
         $lastKF = $this->keyframeTimes[$kf_cnt - 1] / 1000;
         $lastKFPos = $this->keyframeBytes[$kf_cnt - 1] / (1000 * 1000);
     }
     if ($kf_cnt > $lastKF && ($lastKFPos < 100 && !$this instanceof FlvMetadataAudio)) {
         $new_kf_step = 1;
     } else {
         $new_kf_step = max(1, $kf_cnt / 850);
     }
     $new_kf = array();
     $new_fp = array();
     $i = 0;
     $new_kf_pos = 0;
     while ($i < $kf_cnt) {
         $new_kf[] = $this->keyframeTimes[$i];
         $new_fp[] = $this->keyframeBytes[$i];
         $new_kf_pos += $new_kf_step;
         $i = floor($new_kf_pos);
     }
     $metadata_data["times"] = $new_kf;
     $metadata_data["filepositions"] = $new_fp;
     $data = $amfSerializer->serialize('onMetaData') . $amfSerializer->serialize($metadata_data);
     $data_len = strlen($data);
     $metatagSize = myFlvHandler::TAG_WRAPPER_SIZE + $data_len;
     for ($i = 0; $i < count($new_kf); ++$i) {
         $metadata_data["filepositions"][$i] += $metatagSize;
     }
     $res = $amfSerializer->serialize('onMetaData') . $amfSerializer->serialize($metadata_data);
     $meta_tag = myFlvHandler::createMetadataTag($data);
     kFile::safeFilePutContents($this->info_file_name, $meta_tag);
     // sync - OK
     $meta_tag = null;
     $amfSerializer = null;
 }
Example #2
0
 private static function createMetadataForStreamFlv($filePath, $assets, $streamInfo, $addPadding, $duration = null)
 {
     $metadata_content = self::getMetadataFromCache($filePath, $streamInfo, $addPadding);
     if ($metadata_content) {
         return $metadata_content;
     }
     list($sizeList, $timeList, $filePositionsList) = self::iterateAssets($assets, $streamInfo, $addPadding, false);
     $amfSerializer = new FLV_Util_AMFSerialize();
     $metadata = array();
     $metadata_data = array();
     if ($duration) {
         $metadata_data["duration"] = (int) ($duration / 1000);
     }
     $metadata_data["bufferSizes"] = $sizeList;
     $metadata_data["times"] = $timeList;
     $metadata_data["filepositions"] = $filePositionsList;
     $res = $amfSerializer->serialize('onMetaData') . $amfSerializer->serialize($metadata_data);
     $data_len = strlen($res);
     // first create a metadata tag with it's real size - this will be the offset of all the rest of the tags
     // create a metadata tag
     $metadata_size = myFlvHandler::TAG_WRAPPER_SIZE + $data_len;
     $metatagEndOffset = myFlvHandler::getHeaderSize() + $metadata_size;
     // second - create the real metadata tag with the values of all the following tags with correct offsets
     for ($i = 0; $i < count($sizeList); ++$i) {
         $sizeList[$i] += $metatagEndOffset;
     }
     for ($i = 0; $i < count($filePositionsList); ++$i) {
         $filePositionsList[$i] += $metatagEndOffset;
     }
     $metadata_data["bufferSizes"] = $sizeList;
     $metadata_data["filepositions"] = $filePositionsList;
     $res = $amfSerializer->serialize('onMetaData') . $amfSerializer->serialize($metadata_data);
     $metadata_content = myFlvHandler::createMetadataTag($res);
     self::setMetadataInCache($filePath, $streamInfo, $addPadding, $metadata_content);
     return $metadata_content;
 }
 /**
  * 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', "", 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;
 }
Example #4
0
 function play($from = 0, $play_to = null)
 {
     fseek($this->fp, 0);
     // get original file header just in case it has any special flag
     echo fread($this->fp, $this->bodyOfs + 4);
     // output the metadata if available
     $meta = $this->getSegmentMetaData();
     //$meta = $this->getMetaData();
     if (!empty($meta)) {
         //serialize the metadata as an AMF stream
         include_once 'FLV/Util/AMFSerialize.php';
         $amf = new FLV_Util_AMFSerialize();
         $serMeta = $amf->serialize('onMetaData');
         $serMeta .= $amf->serialize($meta);
         //Data tag mark
         $out = pack('C', FLV_Tag::TYPE_DATA);
         //Size of the data tag (BUG: limited to 64Kb)
         $out .= pack('Cn', 0, strlen($serMeta));
         //Timestamp
         $out .= pack('N', 0);
         //StreamID
         $out .= pack('Cn', 0, 0);
         echo $out;
         echo $serMeta;
         // PrevTagSize for the metadata
         echo pack('N', strlen($serMeta) + strlen($out));
     }
     $chunkSize = 4096;
     $skippedOrigMeta = empty($this->origMetaSize);
     //seek to offset point:
     fseek($this->fp, $from);
     while (!feof($this->fp)) {
         // if the original metadata is present and not yet skipped...
         if (!$skippedOrigMeta) {
             $pos = ftell($this->fp);
             // check if we are going to output it in this loop step
             if ($pos <= $this->origMetaOfs && $pos + $chunkSize > $this->origMetaOfs) {
                 // output the bytes just before the original metadata tag
                 if ($this->origMetaOfs - $pos > 0) {
                     echo fread($this->fp, $this->origMetaOfs - $pos);
                 }
                 // position the file pointer just after the metadata tag
                 fseek($this->fp, $this->origMetaOfs + $this->origMetaSize);
                 $skippedOrigMeta = true;
                 continue;
             }
         }
         if ($play_to != null) {
             if (ftell($this->fp) + $chunkSize > $play_to) {
                 $read_amount = ftell($this->fp) + $chunkSize - $play_to;
                 echo fread($this->fp, $read_amount);
                 break;
             }
         }
         echo fread($this->fp, $chunkSize);
     }
 }
 public function close()
 {
     if (!$this->creating) {
         return;
     }
     // save to disk
     $amfSerializer = new FLV_Util_AMFSerialize();
     $metadata = array();
     $metadata_data = array();
     // theses will be used as placeholders for dynamic data
     $metadata_data["duration"] = (int) ($this->duration / 1000);
     $metadata_data["timeOffset"] = 0;
     $metadata_data["bytesOffset"] = 0;
     // TODO - remove !!
     //$metadata_data["bufferSizes"] = $this->sizeList;
     $metadata_data["times"] = $this->keyframeTimes;
     $metadata_data["filepositions"] = $this->keyframeBytes;
     $res = $amfSerializer->serialize('onMetaData') . $amfSerializer->serialize($metadata_data);
     // first create a metadata tag with it's real size - this will be the offset of all the rest of the tags
     // create a metadata tag
     $metatag = new FlvTag();
     $metatag->setPrevTagSize(0);
     $metatag->setTagType(0x12);
     $metatag->setTimestamp(0);
     $metatag->setData($res);
     $metatagSize = $metatag->getSize();
     /*
     		 // TODO - remove
     		 // second - create the real metadata tag with the values of all the following tags with correct offsets
     		 for ($i = 0 ; $i < count ( $this->sizeList ) ; ++$i )
     		 {
     $this->sizeList[$i] += $metatagSize;
     }
     $metadata_data["bufferSizes"] = $this->sizeList;
     */
     // fix the bytes' offsets
     for ($i = 0; $i < count($this->keyframeBytes); ++$i) {
         $metadata_data["filepositions"][$i] += $metatagSize;
     }
     $res = $amfSerializer->serialize('onMetaData') . $amfSerializer->serialize($metadata_data);
     $metatag->setData($res);
     $str = $metatag->dump(true);
     $amfSerializer = null;
     $metatag = null;
     file_put_contents($this->file_name, $str);
 }