Example #1
0
 public function dump($chunk_size, $from_byte, $to_byte, $only_audio = false, $dump_from_byte = 0, $range_from = 0, $range_to = 2147483647, $cuepoint_time = 0, $cuepoint_pos = 0)
 {
     $this->validateMetadata($only_audio);
     // find out if there are any audio tags when creating the header for a video dump
     // otherwise flash may act in a wierd way when playing the video.
     // for an audio dump assume there are audio tags (otherwise the dump is empty)
     if ($only_audio) {
         $has_vtags = false;
         $has_atags = true;
     } else {
         $vinfo = $this->validateHelper(false);
         $ainfo = $this->validateHelper(true);
         $has_vtags = $vinfo->hasTags();
         $has_atags = $ainfo->hasTags();
     }
     $ofs = 0;
     // we always dump the header even if the request is for a partial flv (for scrubbing)
     $header = self::createFlvHeader($has_vtags, $has_atags);
     if ($this->echo_range($header, $ofs, $range_from, $range_to)) {
         return;
     }
     $metadata = $this->getMetadata($only_audio);
     // we either dump the whole metadata or nothing at all - no need to dump partial metadata
     $dumped_offset = self::FLV_HEADER_SIZE + strlen($metadata);
     if ($dump_from_byte < $dumped_offset) {
         if ($this->echo_range($metadata, $ofs, $range_from, $range_to)) {
             return;
         }
     }
     if ($only_audio) {
         // dont support scrubbing for audio for now
         $this->seek($from_byte);
         while ($this->pos < $to_byte && ($data = $this->getNextTag(myFlvHandler::GET_NEXT_TAG_DATA))) {
             $type = unpack("C", $data);
             if ($type[1] == myFlvHandler::TAG_TYPE_AUDIO) {
                 if ($this->echo_range($data, $ofs, $range_from, $range_to)) {
                     return;
                 }
             }
         }
     } else {
         // start serving from the requested position (after substracting header and metadata size)
         $from_byte += max(0, $dump_from_byte - $dumped_offset);
         $file_seek_pos = $from_byte;
         $file_need_seek = true;
         $dump_ranges = array();
         // in case of a cuepoint dump three parts - before cuepoint, the cuepoint itself, after cuepoint
         if ($cuepoint_pos) {
             $dump_ranges[] = array("type" => "data", "from" => $from_byte, "to" => $cuepoint_pos);
             $dump_ranges[] = array("type" => "cuepoint");
             $dump_ranges[] = array("type" => "data", "from" => $cuepoint_pos, "to" => $to_byte);
         } else {
             $dump_ranges[] = array("type" => "data", "from" => $from_byte, "to" => $to_byte);
         }
         foreach ($dump_ranges as $range) {
             if ($range["type"] == "cuepoint") {
                 $amfSerializer = new FLV_Util_AMFSerialize();
                 $cuepoint = $amfSerializer->serialize('onCuePoint') . $amfSerializer->serialize(array());
                 $cuepoint_tag = myFlvHandler::createMetadataTag($cuepoint);
                 $cuepoint_tag = myFlvHandler::dumpTag($cuepoint_tag, $cuepoint_time);
                 if ($this->echo_range($cuepoint_tag, $ofs, $range_from, $range_to)) {
                     return;
                 }
             } else {
                 $dump_from = $range["from"];
                 $dump_to = $range["to"];
                 $dump_chunk_size = $chunk_size;
                 while ($dump_from < $dump_to) {
                     if ($dump_to - $dump_from < $dump_chunk_size) {
                         // this is for the very last chunk  - make it as big of the what's left
                         $dump_chunk_size = $dump_to - $dump_from;
                     }
                     // check if we need to dump anything otherwise dont read file
                     if ($this->check_range($dump_chunk_size, $ofs, $range_from, $range_to)) {
                         if ($file_need_seek) {
                             fseek($this->fh, $file_seek_pos);
                         }
                         $content = fread($this->fh, $dump_chunk_size);
                         $file_need_seek = false;
                     } else {
                         $content = "";
                         $file_need_seek = true;
                     }
                     $file_seek_pos += $dump_chunk_size;
                     if ($this->echo_range($content, $ofs, $range_from, $range_to, $dump_chunk_size)) {
                         return;
                     }
                     $dump_from += $dump_chunk_size;
                 }
             }
         }
     }
 }
Example #2
0
 private static function iterateAssets($assets, $streamInfo, $addPadding, $echo)
 {
     if ($assets == null) {
         return null;
     }
     $total_bytes = 0;
     list($filePath, $timeline, $streamNum, $fileTimestamp) = $streamInfo;
     $lastTimeStamp = 0;
     $sizeList = array();
     $timeList = array();
     $filePositionsList = array();
     $sizeListTime = 1000;
     $dump_type = $echo ? myFlvHandler::GET_NEXT_TAG_ALL : myFlvHandler::GET_NEXT_TAG_META;
     if ($addPadding) {
         $silence_tag_data = '080000d1000000000000002efffb50c40003c00001a400000020000034800000' . '044c414d45332e39382e32555555555555555555555555555555555555555555' . '5555555555555555555555555555555555555555554c414d45332e39382e3255' . '5555555555555555555555555555555555555555555555555555555555555555' . '5555555555555555555555555555555555555555555555555555555555555555' . '5555555555555555555555555555555555555555555555555555555555555555' . '55555555555555555555555555555555555555555555555555555555000000dc';
         $silence_tag = pack("H*", $silence_tag_data);
     }
     foreach ($assets as $asset) {
         // in the future this will always be true,for backward compatibility - make sure will work OK if
         // there is no edit flavor
         $use_multi_flavor = $asset['file_name_edit'] && $asset['file_name_data'] && $timeline == "video";
         $number_of_iterations = $use_multi_flavor ? 2 : 1;
         for ($i = 0; $i < $number_of_iterations; $i++) {
             if ($use_multi_flavor) {
                 if ($i == 0) {
                     $file_name = $asset['file_name_edit'];
                     // edit flavor with original attributes
                     $start_byte = $asset['start_byte'];
                     $end_byte = $asset['end_byte'];
                 } else {
                     $file_name = $asset['file_name_data'];
                     // original file name with '_play' attributes
                     $start_byte = $asset['start_byte_play'];
                     $end_byte = $asset['end_byte_play'];
                 }
                 KalturaLog::log("myFlvStreamer:: ({$i}) using {$file_name} ({$start_byte} - {$end_byte})");
             } else {
                 $file_name = $asset['file_name_data'];
                 // original file name with original attributes
                 $start_byte = $asset['start_byte'];
                 $end_byte = $asset['end_byte'];
             }
             if ($start_byte >= $end_byte) {
                 // edit flavor not used (play clip was used from keyframe)
                 continue;
             }
             $first_frame = true;
             KalturaLog::log("playing file [{$file_name}] from [{$start_byte}] to [{$end_byte}]");
             // if should echo - don't optimize (we need the actual data
             // if should not echo - use optimization
             $flv_wrapper = new myFlvHandler($file_name);
             $flv_wrapper->seek($start_byte);
             $flv_tag_prev = $flv_wrapper->getNextTag($dump_type);
             if ($flv_tag_prev == NULL) {
                 continue;
             }
             KalturaLog::log("file [{$file_name}]: flv_tag_prev is not null");
             $videoTimeline = $timeline == "video";
             while ($flv_tag_prev[myFlvHandler::TAG_FIELD_POS] < $end_byte) {
                 $flv_current_tag = $flv_wrapper->getNextTag($dump_type);
                 // dont write the last tag as we dont know its duration and we wont be able to give the next chunk
                 // a percise timestamp
                 if ($flv_current_tag == NULL) {
                     break;
                 }
                 $prev_tag_type = $flv_tag_prev[myFlvHandler::TAG_FIELD_TYPE];
                 if ($prev_tag_type != myFlvHandler::TAG_TYPE_METADATA) {
                     $prev_tag_timestamp = $flv_tag_prev[myFlvHandler::TAG_FIELD_TIMESTAMP];
                     if ($first_frame) {
                         $first_frame = false;
                         $lastTimeStamp -= $prev_tag_timestamp;
                     }
                     // if the timeline is video dump both audio and video data chunks
                     // otherwise (timeline is audio / voice) dump only audio data chunks
                     if ($videoTimeline || $prev_tag_type == myFlvHandler::TAG_TYPE_AUDIO) {
                         $currentTimeStamp = $prev_tag_timestamp + $lastTimeStamp;
                         if ($echo) {
                             echo myFlvHandler::dumpTag($flv_tag_prev[myFlvHandler::TAG_FIELD_DATA], $lastTimeStamp);
                         } else {
                             $total_bytes += $flv_tag_prev[myFlvHandler::TAG_FIELD_SIZE];
                             // we accumulate 3 types of metadata
                             // filepositions and times - VIDEOS - each keyframe. AUDIO - each second (used for scrubbing validation)
                             // bufferTimes - once per second (used for buffering calculations)
                             if ($videoTimeline) {
                                 if ($flv_tag_prev[myFlvHandler::TAG_FIELD_KEYFRAME]) {
                                     $filePositionsList[] = $total_bytes;
                                     $timeList[] = $currentTimeStamp;
                                 }
                             }
                             if ($sizeListTime < $currentTimeStamp) {
                                 $sizeList[] = $total_bytes;
                                 if (!$videoTimeline) {
                                     $filePositionsList[] = $total_bytes;
                                     $timeList[] = $sizeListTime;
                                 }
                                 $sizeListTime += 1000;
                             }
                         }
                     }
                 }
                 $flv_tag_prev = $flv_current_tag;
             }
             $lastTimeStamp += $flv_tag_prev[myFlvHandler::TAG_FIELD_TIMESTAMP];
         }
         // add silence padding between clips in order to give the flash player enough time to
         // execute some logic in between.
         if ($addPadding) {
             $paddingTags = self::PADDING_TAGS;
             while ($paddingTags--) {
                 if ($echo) {
                     echo myFlvHandler::dumpTag($silence_tag, $lastTimeStamp);
                 }
                 $lastTimeStamp += self::PADDING_TAG_TIME;
                 $total_bytes += self::PADDING_TAG_SIZE;
             }
         }
     }
     return array($sizeList, $timeList, $filePositionsList);
 }