Index: branches/MetavidWiki-exp/MetavidWiki/skins/mv_embed/flvServer/MvFlv.php |
— | — | @@ -1,240 +0,0 @@ |
2 | | -<?php |
3 | | -include_once 'FLV/FLV.php'; |
4 | | - |
5 | | -define('MAX_FLV_TS', 16777.216);//it appears tag times restart after 16777.216 seconds; |
6 | | -define('KEY_FRAME_DISTANCE', 2); //max keyframe distance |
7 | | - |
8 | | -define('META_DATA_EXT', '.meta'); //file extension for cached Time metadata |
9 | | - |
10 | | - class MvFLV extends FLV { |
11 | | - |
12 | | - /** |
13 | | - * On audio-only files the frame index will use this as minimum gap |
14 | | - */ |
15 | | - private $audioFrameGap = 3; |
16 | | - |
17 | | - private $origMetaOfs = 0; |
18 | | - private $origMetaSize = 0; |
19 | | - private $origMetaData; |
20 | | - private $compMetaData; |
21 | | - |
22 | | - private $wrapTimeCount = 0; |
23 | | - |
24 | | - |
25 | | - function playTimeReq($start_time_sec, $end_time_sec=null){ |
26 | | - |
27 | | - //@@todo cache byte offsets in memcache if avaliable |
28 | | - $this->getMetaData(); |
29 | | - $meta = & $this->compMetaData['keyframes']; |
30 | | - |
31 | | - $start_byte=$end_byte=null; |
32 | | - if($start_time_sec==0 && $end_time_sec==null)$this->play(); |
33 | | - for($i=0;$i<count($meta['times']);$i++){ |
34 | | - //set to the keyframe right before a keyframe of the requested start time |
35 | | - if($meta['times'][$i]>=$start_time_sec && $start_byte==null){ |
36 | | - $start_byte=(isset($meta['times'][$i-1]))?$meta['filepositions'][$i-1]:$meta['filepositions'][$i]; |
37 | | - if($end_time_sec==null)break; |
38 | | - } |
39 | | - //set to the keyframe right after the keyframe of the end time: |
40 | | - if($end_time_sec!=null){ |
41 | | - if($meta['times'][$i]>=$end_time_sec)$end_byte= $meta['filepositions'][$i]; |
42 | | - } |
43 | | - } |
44 | | - $this->play($start_byte, $end_byte); |
45 | | - } |
46 | | - function getMetaData() |
47 | | - { |
48 | | - if (! is_array($this->origMetaData)) |
49 | | - return $this->compMetaData; |
50 | | - else |
51 | | - return array_merge( $this->origMetaData, $this->compMetaData ); |
52 | | - } |
53 | | - /*function getMetaData() |
54 | | - { |
55 | | - if(is_file($this->fname . META_DATA_EXT)){ |
56 | | - $this->compMetaData = unserialize(file_get_contents ($this->fname . META_DATA_EXT)); |
57 | | - }else{ |
58 | | - $this->computeMetaData(); |
59 | | - if(!file_put_contents($this->fname . META_DATA_EXT, serialize($this->compMetaData))){ |
60 | | - throw( new FLV_FileException('Unable to write out cached keyframe output') ); |
61 | | - } |
62 | | - } |
63 | | - return $this->compMetaData; |
64 | | - }*/ |
65 | | - function computeMetaData() |
66 | | - { |
67 | | - ini_set("max_execution_time","0");//computeMetaData can take some time |
68 | | - $this->compMetaData = array(); |
69 | | - $this->compMetaData['metadatacreator'] = 'FLV Tools for PHP v0.1 by DrSlump'; |
70 | | - $this->compMetaData['metadatadate'] = gmdate('Y-m-d\TH:i:s') . '.000Z'; |
71 | | - $this->compMetaData['keyframes'] = array(); |
72 | | - $this->compMetaData['keyframes']['filepositions'] = array(); |
73 | | - $this->compMetaData['keyframes']['times'] = array(); |
74 | | - |
75 | | - $this->origMetaOfs = 0; |
76 | | - $this->origMetaSize = 0; |
77 | | - $this->origMetaData = null; |
78 | | - $skipTagTypes = array(); |
79 | | - while ($tag = $this->getTag( $skipTagTypes )) |
80 | | - { |
81 | | - // pre-calculate the timestamp as seconds |
82 | | - $ts = $tag->timestamp/1000; |
83 | | - if ($tag->timestamp > 0 && $tag->type==FLV_Tag::TYPE_VIDEO ){ |
84 | | - $ts = (MAX_FLV_TS*$this->wrapTimeCount) + $ts; |
85 | | - if($ts < $this->compMetaData['lasttimestamp']){ |
86 | | - $this->wrapTimeCount++; |
87 | | - $ts = MAX_FLV_TS + $ts; |
88 | | - } |
89 | | - //print "set end time to $ts \n"; |
90 | | - $this->compMetaData['lasttimestamp'] = $ts; |
91 | | - } |
92 | | - |
93 | | - switch ($tag->type) |
94 | | - { |
95 | | - case FLV_Tag::TYPE_VIDEO : |
96 | | - |
97 | | - //Optimization, extract the frametype without analyzing the tag body |
98 | | - if ((ord($tag->body[0]) >> 4) == FLV_Tag_Video::FRAME_KEYFRAME) |
99 | | - { |
100 | | - $this->compMetaData['keyframes']['filepositions'][] = $this->getTagOffset(); |
101 | | - $this->compMetaData['keyframes']['times'][] = $ts; |
102 | | - } |
103 | | - |
104 | | - if ( !in_array(FLV_TAG::TYPE_VIDEO, $skipTagTypes) ) |
105 | | - { |
106 | | - $this->compMetaData['width'] = $tag->width; |
107 | | - $this->compMetaData['height'] = $tag->height; |
108 | | - $this->compMetaData['videocodecid'] = $tag->codec; |
109 | | - //Processing one video tag is enough |
110 | | - array_push( $skipTagTypes, FLV_Tag::TYPE_VIDEO ); |
111 | | - } |
112 | | - |
113 | | - break; |
114 | | - |
115 | | - case FLV_Tag::TYPE_AUDIO : |
116 | | - |
117 | | - //Save audio frame positions when there is no video |
118 | | - if (!$flv->hasVideo && $ts - $oldTs > $this->audioFrameGap) |
119 | | - { |
120 | | - $this->compMetaData['keyframes']['filepositions'][] = $this->getTagOffset(); |
121 | | - $this->compMetaData['keyframes']['times'][] = $ts; |
122 | | - $oldTs = $ts; |
123 | | - } |
124 | | - |
125 | | - if ( !in_array( FLV_Tag::TYPE_AUDIO, $skipTagTypes) ) |
126 | | - { |
127 | | - $this->compMetaData['audiocodecid'] = $tag->codec; |
128 | | - $this->compMetaData['audiofreqid'] = $tag->frequency; |
129 | | - $this->compMetaData['audiodepthid'] = $tag->depth; |
130 | | - $this->compMetaData['audiomodeid'] = $tag->mode; |
131 | | - |
132 | | - //Processing one audio tag is enough |
133 | | - array_push( $skipTagTypes, FLV_Tag::TYPE_AUDIO ); |
134 | | - } |
135 | | - |
136 | | - break; |
137 | | - |
138 | | - case FLV_Tag::TYPE_DATA : |
139 | | - if ($tag->name == 'onMetaData') |
140 | | - { |
141 | | - $this->origMetaOfs = $this->getTagOffset(); |
142 | | - $this->origMetaSize = $tag->size + self::TAG_HEADER_SIZE; |
143 | | - $this->origMetaData = $tag->value; |
144 | | - } |
145 | | - break; |
146 | | - } |
147 | | - |
148 | | - //Does this actually help with memory allocation? |
149 | | - unset($tag); |
150 | | - } |
151 | | - |
152 | | - if (! empty($this->compMetaData['keyframes']['times'])) |
153 | | - $this->compMetaData['lastkeyframetimestamp'] = $this->compMetaData['keyframes']['times'][ count($this->compMetaData['keyframes']['times'])-1 ]; |
154 | | - |
155 | | - $this->compMetaData['duration'] = $this->compMetaData['lasttimestamp']; |
156 | | - |
157 | | - return $this->compMetaData; |
158 | | - } |
159 | | - |
160 | | - function setMetaData( $metadata, $origMetaOfs = 0, $origMetaSize = 0 ) |
161 | | - { |
162 | | - $this->compMetaData = $metadata; |
163 | | - $this->origMetaOfs = $origMetaOfs; |
164 | | - $this->origMetaSize = $origMetaSize; |
165 | | - } |
166 | | - |
167 | | - |
168 | | - function play( $from = 0, $play_to=null ) |
169 | | - { |
170 | | - print "play $from to $play_to "; |
171 | | - die; |
172 | | - fseek($this->fp, 0); |
173 | | - |
174 | | - // get original file header just in case it has any special flag |
175 | | - echo fread($this->fp, $this->bodyOfs + 4); |
176 | | - |
177 | | - // output the metadata if available |
178 | | - $meta = $this->getMetaData(); |
179 | | - if (! empty($meta)) |
180 | | - { |
181 | | - //serialize the metadata as an AMF stream |
182 | | - include_once 'FLV/Util/AMFSerialize.php'; |
183 | | - $amf = new FLV_Util_AMFSerialize(); |
184 | | - |
185 | | - $serMeta = $amf->serialize('onMetaData'); |
186 | | - $serMeta.= $amf->serialize($meta); |
187 | | - |
188 | | - //Data tag mark |
189 | | - $out = pack('C', FLV_Tag::TYPE_DATA); |
190 | | - //Size of the data tag (BUG: limited to 64Kb) |
191 | | - $out.= pack('Cn', 0, strlen($serMeta)); |
192 | | - //Timestamp |
193 | | - $out.= pack('N', 0); |
194 | | - //StreamID |
195 | | - $out.= pack('Cn', 0, 0); |
196 | | - |
197 | | - echo $out; |
198 | | - echo $serMeta; |
199 | | - |
200 | | - // PrevTagSize for the metadata |
201 | | - echo pack('N', strlen($serMeta) + strlen($out) ); |
202 | | - } |
203 | | - |
204 | | - $chunkSize = 4096; |
205 | | - $skippedOrigMeta = empty($this->origMetaSize); |
206 | | - //seek to offset point: |
207 | | - fseek($this->fp, $from); |
208 | | - while (! feof($this->fp)) |
209 | | - { |
210 | | - // if the original metadata is pressent and not yet skipped... |
211 | | - if (! $skippedOrigMeta) |
212 | | - { |
213 | | - $pos = ftell($this->fp); |
214 | | - |
215 | | - // check if we are going to output it in this loop step |
216 | | - if ( $pos <= $this->origMetaOfs && |
217 | | - $pos + $chunkSize > $this->origMetaOfs ) |
218 | | - { |
219 | | - // output the bytes just before the original metadata tag |
220 | | - if ($this->origMetaOfs - $pos > 0) |
221 | | - echo fread($this->fp, $this->origMetaOfs - $pos); |
222 | | - |
223 | | - // position the file pointer just after the metadata tag |
224 | | - fseek($this->fp, $this->origMetaOfs + $this->origMetaSize); |
225 | | - |
226 | | - $skippedOrigMeta = true; |
227 | | - continue; |
228 | | - } |
229 | | - } |
230 | | - if($play_to!=null){ |
231 | | - if(ftell($this->fp)+$chunkSize > $play_to){ |
232 | | - $read_amount = (ftell($this->fp)+$chunkSize)-$play_to; |
233 | | - echo fread($this->fp, $read_amount); |
234 | | - break; |
235 | | - } |
236 | | - } |
237 | | - echo fread($this->fp, $chunkSize); |
238 | | - } |
239 | | - } |
240 | | -} |
241 | | -?> |
Index: branches/MetavidWiki-exp/MetavidWiki/skins/mv_embed/flvServer/mvFlvServer.php |
— | — | @@ -50,16 +50,28 @@ |
51 | 51 | //print "DO: $start_sec $end_sec \n"; |
52 | 52 | require_once('MvFlv.php'); |
53 | 53 | //open up the metavid Flv object: |
54 | | - $flv = new MvFLV(); |
| 54 | + /*$flv = new MvFLV(); |
55 | 55 | try { |
56 | 56 | $flv->open( $file_loc ); |
57 | 57 | } catch (Exception $e) { |
58 | 58 | die("<pre>The following exception was detected while trying to open a FLV file:\n" . $e->getMessage() . "</pre>"); |
59 | 59 | } |
60 | | - //header('Content-type: '.FLASH_VIDEO_CONTENT_TYPE); |
| 60 | + header('Content-type: '.FLASH_VIDEO_CONTENT_TYPE); |
61 | 61 | $flv->playTimeReq($start_sec, $end_sec); |
62 | 62 | //print_r($flv->computeMetaData() ); |
63 | 63 | $flv->close(); |
| 64 | + */ |
| 65 | + $flv = new MyFLV(); |
| 66 | + try { |
| 67 | + $flv->open( $file_loc ); |
| 68 | + } catch (Exception $e) { |
| 69 | + die("<pre>The following exception was detected while trying to open a FLV file:\n" . $e->getMessage() . "</pre>"); |
| 70 | + } |
| 71 | + header('Content-type: '.FLASH_VIDEO_CONTENT_TYPE); |
| 72 | + //$flv->play(331630, 647659); |
| 73 | + $flv->playTimeReq($start_sec, $end_sec); |
| 74 | + $flv->close(); |
| 75 | + |
64 | 76 | } |
65 | 77 | |
66 | 78 | |
Index: branches/MetavidWiki-exp/MetavidWiki/skins/mv_embed/flvServer/README |
— | — | @@ -1,5 +1,3 @@ |
2 | | -==mv_embed helper scripts== |
| 2 | +==flvServer== |
3 | 3 | |
4 | | -These are the mv_embed helper scripts. |
5 | | - |
6 | | -@@todo document |
\ No newline at end of file |
| 4 | +enables the serving of flv video segments. |
\ No newline at end of file |
Index: branches/MetavidWiki-exp/MetavidWiki/skins/mv_embed/flvServer/MvFlv_old.php |
— | — | @@ -0,0 +1,251 @@ |
| 2 | +<?php |
| 3 | +include_once 'FLV/FLV.php'; |
| 4 | + |
| 5 | +define('MAX_FLV_TS', 16777.216);//it appears tag times restart after 16777.216 seconds; |
| 6 | +define('KEY_FRAME_DISTANCE', 2); //max keyframe distance |
| 7 | + |
| 8 | +define('META_DATA_EXT', '.KfMeta'); //file extension for cached Time metadata |
| 9 | + |
| 10 | + class MvFLV extends FLV { |
| 11 | + |
| 12 | + /** |
| 13 | + * On audio-only files the frame index will use this as minimum gap |
| 14 | + */ |
| 15 | + private $audioFrameGap = 3; |
| 16 | + |
| 17 | + private $origMetaOfs = 0; |
| 18 | + private $origMetaSize = 0; |
| 19 | + private $origMetaData; |
| 20 | + private $compMetaData; |
| 21 | + |
| 22 | + private $wrapTimeCount = 0; |
| 23 | + private $kfMeta=array(); |
| 24 | + |
| 25 | + private $metaDuration=0; |
| 26 | + |
| 27 | + function playTimeReq($start_time_sec, $end_time_sec=null){ |
| 28 | + //print "play $start_time_sec to $end_time_sec"; |
| 29 | + //@@todo cache byte offsets in memcache if avaliable |
| 30 | + if( $end_time_sec) |
| 31 | + $this->metaDuration = $end_time_sec - $start_time_sec; |
| 32 | + //print "SET metaDuration to: " . $this->metaDuration . "\n"; |
| 33 | + $meta = & $this->getKfMetaData(); |
| 34 | + $start_byte=$end_byte=null; |
| 35 | + if($start_time_sec==0 && $end_time_sec==null)$this->play(); |
| 36 | + $start_time_ms = $start_time_sec*1000; |
| 37 | + $end_time_ms = ($end_time_sec==null)?null:$end_time_sec*1000; |
| 38 | + |
| 39 | + for($i=0;$i<count($meta['times']);$i++){ |
| 40 | + //set to the keyframe right before a keyframe of the requested start time |
| 41 | + if($meta['times'][$i]>=$start_time_ms && $start_byte==null){ |
| 42 | + $start_byte=(isset($meta['times'][$i-1]))?$meta['filepositions'][$i-1]:$meta['filepositions'][$i]; |
| 43 | + if($end_time_ms==null)break; |
| 44 | + } |
| 45 | + //set to the keyframe right after the keyframe of the end time: |
| 46 | + if($end_time_ms!=null){ |
| 47 | + if($meta['times'][$i]>=$end_time_ms)$end_byte= $meta['filepositions'][$i]; |
| 48 | + } |
| 49 | + } |
| 50 | + //print " bytes: $start_byte $end_byte "; |
| 51 | + $this->play($start_byte, $end_byte); |
| 52 | + } |
| 53 | + function getMetaData() |
| 54 | + { |
| 55 | + if (! is_array($this->origMetaData)) |
| 56 | + return $this->compMetaData; |
| 57 | + else |
| 58 | + return array_merge( $this->origMetaData, $this->compMetaData ); |
| 59 | + } |
| 60 | + function getKfMetaData() |
| 61 | + { |
| 62 | + if(is_file($this->fname . META_DATA_EXT)){ |
| 63 | + $this->kfMeta = unserialize(file_get_contents ($this->fname . META_DATA_EXT)); |
| 64 | + }else{ |
| 65 | + $this->computeMetaData(); |
| 66 | + //store keframe data as int (takes less time to parse/open/search) |
| 67 | + foreach($this->compMetaData['keyframes']['times'] as $inx=>&$ts){ |
| 68 | + $ts = (int)($ts*1000); |
| 69 | + } |
| 70 | + if(!file_put_contents($this->fname . META_DATA_EXT, serialize($this->compMetaData['keyframes']))){ |
| 71 | + throw( new FLV_FileException('Unable to write out cached keyframe output') ); |
| 72 | + } |
| 73 | + } |
| 74 | + return $this->kfMeta; |
| 75 | + } |
| 76 | + function computeMetaData() |
| 77 | + { |
| 78 | + ini_set("max_execution_time","0");//computeMetaData can take some time |
| 79 | + $this->compMetaData = array(); |
| 80 | + $this->compMetaData['metadatacreator'] = 'FLV Tools'; |
| 81 | + $this->compMetaData['metadatadate'] = gmdate('Y-m-d\TH:i:s') . '.000Z'; |
| 82 | + $this->compMetaData['keyframes'] = array(); |
| 83 | + $this->compMetaData['keyframes']['filepositions'] = array(); |
| 84 | + $this->compMetaData['keyframes']['times'] = array(); |
| 85 | + |
| 86 | + $this->origMetaOfs = 0; |
| 87 | + $this->origMetaSize = 0; |
| 88 | + $this->origMetaData = null; |
| 89 | + $skipTagTypes = array(); |
| 90 | + while ($tag = $this->getTag( $skipTagTypes )) |
| 91 | + { |
| 92 | + // pre-calculate the timestamp as seconds |
| 93 | + $ts = $tag->timestamp/1000; |
| 94 | + if ($tag->timestamp > 0 && $tag->type==FLV_Tag::TYPE_VIDEO ){ |
| 95 | + $ts = (MAX_FLV_TS*$this->wrapTimeCount) + $ts; |
| 96 | + if($ts < $this->compMetaData['lasttimestamp']){ |
| 97 | + $this->wrapTimeCount++; |
| 98 | + $ts = MAX_FLV_TS + $ts; |
| 99 | + } |
| 100 | + //print "set end time to $ts \n"; |
| 101 | + $this->compMetaData['lasttimestamp'] = $ts; |
| 102 | + } |
| 103 | + switch ($tag->type) |
| 104 | + { |
| 105 | + case FLV_Tag::TYPE_VIDEO : |
| 106 | + |
| 107 | + //Optimization, extract the frametype without analyzing the tag body |
| 108 | + if ((ord($tag->body[0]) >> 4) == FLV_Tag_Video::FRAME_KEYFRAME) |
| 109 | + { |
| 110 | + $this->compMetaData['keyframes']['filepositions'][] = $this->getTagOffset(); |
| 111 | + $this->compMetaData['keyframes']['times'][] = $ts; |
| 112 | + } |
| 113 | + |
| 114 | + if ( !in_array(FLV_TAG::TYPE_VIDEO, $skipTagTypes) ) |
| 115 | + { |
| 116 | + $this->compMetaData['width'] = $tag->width; |
| 117 | + $this->compMetaData['height'] = $tag->height; |
| 118 | + $this->compMetaData['videocodecid'] = $tag->codec; |
| 119 | + //Processing one video tag is enough |
| 120 | + array_push( $skipTagTypes, FLV_Tag::TYPE_VIDEO ); |
| 121 | + } |
| 122 | + |
| 123 | + break; |
| 124 | + case FLV_Tag::TYPE_AUDIO : |
| 125 | + //Save audio frame positions when there is no video |
| 126 | + if (!$flv->hasVideo && $ts - $oldTs > $this->audioFrameGap) |
| 127 | + { |
| 128 | + $this->compMetaData['keyframes']['filepositions'][] = $this->getTagOffset(); |
| 129 | + $this->compMetaData['keyframes']['times'][] = $ts; |
| 130 | + $oldTs = $ts; |
| 131 | + } |
| 132 | + |
| 133 | + if ( !in_array( FLV_Tag::TYPE_AUDIO, $skipTagTypes) ) |
| 134 | + { |
| 135 | + $this->compMetaData['audiocodecid'] = $tag->codec; |
| 136 | + $this->compMetaData['audiofreqid'] = $tag->frequency; |
| 137 | + $this->compMetaData['audiodepthid'] = $tag->depth; |
| 138 | + $this->compMetaData['audiomodeid'] = $tag->mode; |
| 139 | + |
| 140 | + //Processing one audio tag is enough |
| 141 | + array_push( $skipTagTypes, FLV_Tag::TYPE_AUDIO ); |
| 142 | + } |
| 143 | + |
| 144 | + break; |
| 145 | + |
| 146 | + case FLV_Tag::TYPE_DATA : |
| 147 | + if ($tag->name == 'onMetaData') |
| 148 | + { |
| 149 | + $this->origMetaOfs = $this->getTagOffset(); |
| 150 | + $this->origMetaSize = $tag->size + self::TAG_HEADER_SIZE; |
| 151 | + $this->origMetaData = $tag->value; |
| 152 | + } |
| 153 | + break; |
| 154 | + } |
| 155 | + |
| 156 | + //Does this actually help with memory allocation? |
| 157 | + unset($tag); |
| 158 | + } |
| 159 | + if (! empty($this->compMetaData['keyframes']['times'])) |
| 160 | + $this->compMetaData['lastkeyframetimestamp'] = $this->compMetaData['keyframes']['times'][ count($this->compMetaData['keyframes']['times'])-1 ]; |
| 161 | + |
| 162 | + $this->compMetaData['duration'] = $this->compMetaData['lasttimestamp']; |
| 163 | + |
| 164 | + |
| 165 | + return $this->compMetaData; |
| 166 | + } |
| 167 | + |
| 168 | + function setMetaData( $metadata, $origMetaOfs = 0, $origMetaSize = 0 ) |
| 169 | + { |
| 170 | + $this->compMetaData = $metadata; |
| 171 | + $this->origMetaOfs = $origMetaOfs; |
| 172 | + $this->origMetaSize = $origMetaSize; |
| 173 | + } |
| 174 | + |
| 175 | + |
| 176 | + function play( $from = 0, $play_to=null ) |
| 177 | + { |
| 178 | + // output the metadata if available |
| 179 | + $this->computeMetaData(); |
| 180 | + $meta = $this->getMetaData(); |
| 181 | + //print "META:"; |
| 182 | + //print_r($meta); |
| 183 | + //die; |
| 184 | + |
| 185 | + fseek($this->fp, 0); |
| 186 | + // get original file header just in case it has any special flag |
| 187 | + echo fread($this->fp, $this->bodyOfs + 4); |
| 188 | + |
| 189 | + //ignore the "ture" metadata and make a simple metadata packet: |
| 190 | + if (! empty($meta)) |
| 191 | + { |
| 192 | + //serialize the metadata as an AMF stream |
| 193 | + include_once 'FLV/Util/AMFSerialize.php'; |
| 194 | + $amf = new FLV_Util_AMFSerialize(); |
| 195 | + |
| 196 | + $serMeta = $amf->serialize('onMetaData'); |
| 197 | + $serMeta.= $amf->serialize($meta); |
| 198 | + |
| 199 | + //Data tag mark |
| 200 | + $out = pack('C', FLV_Tag::TYPE_DATA); |
| 201 | + //Size of the data tag (BUG: limited to 64Kb) |
| 202 | + $out.= pack('Cn', 0, strlen($serMeta)); |
| 203 | + //Timestamp |
| 204 | + $out.= pack('N', 0); |
| 205 | + //StreamID |
| 206 | + $out.= pack('Cn', 0, 0); |
| 207 | + |
| 208 | + echo $out; |
| 209 | + echo $serMeta; |
| 210 | + |
| 211 | + // PrevTagSize for the metadata |
| 212 | + echo pack('N', strlen($serMeta) + strlen($out) ); |
| 213 | + } |
| 214 | + |
| 215 | + $chunkSize = 4096; |
| 216 | + $skippedOrigMeta = empty($this->origMetaSize); |
| 217 | + //seek to offset point: |
| 218 | + fseek($this->fp, $from); |
| 219 | + while (! feof($this->fp)) |
| 220 | + { |
| 221 | + // if the original metadata is pressent and not yet skipped... |
| 222 | + if (! $skippedOrigMeta) |
| 223 | + { |
| 224 | + $pos = ftell($this->fp); |
| 225 | + |
| 226 | + // check if we are going to output it in this loop step |
| 227 | + if ( $pos <= $this->origMetaOfs && |
| 228 | + $pos + $chunkSize > $this->origMetaOfs ) |
| 229 | + { |
| 230 | + // output the bytes just before the original metadata tag |
| 231 | + if ($this->origMetaOfs - $pos > 0) |
| 232 | + echo fread($this->fp, $this->origMetaOfs - $pos); |
| 233 | + |
| 234 | + // position the file pointer just after the metadata tag |
| 235 | + fseek($this->fp, $this->origMetaOfs + $this->origMetaSize); |
| 236 | + |
| 237 | + $skippedOrigMeta = true; |
| 238 | + continue; |
| 239 | + } |
| 240 | + } |
| 241 | + if($play_to!=null){ |
| 242 | + if(ftell($this->fp)+$chunkSize > $play_to){ |
| 243 | + $read_amount = (ftell($this->fp)+$chunkSize)-$play_to; |
| 244 | + echo fread($this->fp, $read_amount); |
| 245 | + break; |
| 246 | + } |
| 247 | + } |
| 248 | + echo fread($this->fp, $chunkSize); |
| 249 | + } |
| 250 | + } |
| 251 | +} |
| 252 | +?> |