1

I'm string to seek in a remotely hosted FLV file and have it stream locally. Streaming from start works, but when I try to 'seek', player stops.

I'm using this script to seek to remote file

  $fp = fsockopen($host, 80, $errno, $errstr, 30);
  $out  = "GET $path_to_flv HTTP/1.1\r\n";
  $out .= "Host: $host\r\n";
  $out .= "Range: bytes=$pos-$end\r\n";
  $out .= "Connection: Close\r\n\r\n";

  fwrite($fp, $out);

  $content = false;

  while (!feof($fp))
  {
    $data = fgets($fp, 1024);
    if($content) echo $data;
    if($data == "\r\n")
    {
      $content = true;
      header("Content-Type: video/x-flv");
      header("Content-Length: " . (urlfilesize($file) - $pos));
      if($pos > 0)
      {
        print("FLV");
        print(pack('C', 1));
        print(pack('C', 1));
        print(pack('N', 9));
        print(pack('N', 9));
      }
    }
  }
  fclose($fp);

Any ideas ?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Disco
  • 4,226
  • 11
  • 58
  • 76

1 Answers1

-1

UPDATE

so apparently, even though the server signals it accepts range requests (with the Accept-Ranges: bytes), it does not actually do so. to see if there is another way to make the flv seekable, let's have a look at the communication between flash player and server (i use wireshark for this):

  1. the request when starting the player is:

    GET /files/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/ HTTP/1.1
    Host: xxxxxx.megavideo.com
    <some more headers>
    <no range header>
    
  2. this is answered with a response like that:

    HTTP/1.0 200 OK
    Server: Apache/1.3.37 (Debian GNU/Linux) PHP/4.4.7
    Content-Type: video/flv
    ETag: "<video-id>"
    Content-Length: <length of complete video>
    <some more headers>
    
    <the flv content>
    
  3. now when i seek in the flash player, another request is sent. it is almost the same as the initial one, with the following difference:

    GET /files/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/8800968 HTTP/1.1
    <same headers as first request>
    
  4. which gets answered with a response almost the same as the initial one, with a difference only in the Content-Length header.

which lets me assume that the 8800968 at the end of the request url is the "seek range" (the byte offset in the file after seeking) we are looking for, and the second response Content-Length is the initial Content-Length (the length of the whole file) minus this range. which is the case indeed.

with this information, it should be possible to get what you want. good luck!

UPDATE END

this will only work if the server supports HTTP RANGE requests. if it does, it will return a 206 Partial Content response code with a Content-Range header and your requested range of bytes. check for these in the response to your request.

Community
  • 1
  • 1
ax.
  • 58,560
  • 8
  • 81
  • 72
  • HTTP/1.0 200 OK Server: Apache/1.3.37 (Debian GNU/Linux) PHP/4.4.7 Content-Type: video/flv ETag: "Y70ZTH90" Content-Length: 86618084 Content-Disposition: attachment Cache-Control: private Content-Transfer-Encoding: binary Accept-Ranges: bytes – Disco Nov 22 '09 at 15:43
  • returns 200, so it doesn't support partial seeking ... mmh no other ideas no other alternative ? – Disco Nov 22 '09 at 15:45
  • `Accept-Ranges: bytes` suggests that it *does* support range requests. what are the values of `$pos` and `$end`? mind to share `$host/$path_to_flv`? – ax. Nov 22 '09 at 16:09
  • Yes, came to same conclusion after little search. Now i have a problem with the FLV player ... not displaying the video when starting from a different range. But i think this is out of scope of the question, unless you know a little flash ? Thx anyway – Disco Nov 22 '09 at 23:11
  • thanks for this research Disco. the only issue is to decode the range. This file [1] has a function _decode which shows how the first obfuscated part of the url is constructed, maybe the range part is similar. might have to look at the actionscript of the player to find out. [1] http://github.com/monsieurvideo/get-flash-videos/blob/master/FlashVideo/Site/Megavideo.pm – Eric Drechsel Jun 20 '10 at 19:04
  • Actually the second URL component is just a byte offset. – Eric Drechsel Jun 20 '10 at 20:10