folder = $folder; } public function Lines(ReadDbFile $obj) #set which files to stream { $this->files = $obj->Lines(); } public function PreviousLength($length) #set an int indicating the length of the previous meta frame { $this->previous['full_length'] = $length; } public function StreamChapter(ReadDbFile $obj) #stream a complete chapter; no need to mess with metadata { $chapter = $obj->CompleteChapter(); $file = $this->folder . '/' . $this->chapter_folder . "/$chapter.flv"; if (@file_exists($file) && @readfile($file)) return true; return false; } public function Stream() #stream all the files { if (empty($this->files)) return false; #no files to stream foreach ($this->files as $file) { $this->get_file_contents($file); $this->do_stream(); } } protected function do_stream() #do the actual streaming { $this->handle_first_frame(); $content = $this->content; $this->content = ''; $content_length = strlen($content); $fhl = self::FRAME_HEADER_LENGTH; $this_ms = $this->ms; while ($content_length >= $fhl) { list(, $length) = unpack('N', "\0" . substr($content, 5, 3)); $length += $fhl; $frame = substr($content, 0, $length); $content = substr($content, $length); $content_length -= $length; if ($this_ms) { list(, $ms) = unpack('N', "\0" . substr($frame, 8, 3)); $frame = substr_replace($frame, #get 3 bytes of the 4 as required by the format substr(pack('N', $ms + $this_ms), 1), 8, 3); } echo $frame; flush(); } if (!$this_ms) list(, $ms) = unpack('N', "\0" . substr($frame, 8, 3)); $this->ms = $this_ms + $ms; $this->previous_length = $length - self::FRAME_HEADER_META_DIFF; } protected function handle_first_frame() #correct the frame length of the previous frame, which is unpredictable { $this->content = substr_replace($this->content, pack('N', $this->previous_length), 0, 4); } protected function get_file_contents($file) { $file = $this->folder . "/$file"; if (@file_exists($file)) $this->content = file_get_contents($file); else new FatalError(__METHOD__ . ":'$file' doesn't exist"); } } ?>