tags:

views:

453

answers:

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 ?

A: 

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.

ax
HTTP/1.0 200 OKServer: Apache/1.3.37 (Debian GNU/Linux) PHP/4.4.7Content-Type: video/flvETag: "Y70ZTH90"Content-Length: 86618084Content-Disposition: attachmentCache-Control: privateContent-Transfer-Encoding: binaryAccept-Ranges: bytes
Disco
returns 200, so it doesn't support partial seeking ... mmh no other ideas no other alternative ?
Disco
`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
Mmmh so why does it not work :(, flv is hosted at megavideo.
Disco
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
yes, different question.
ax
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
Actually the second URL component is just a byte offset.
Eric Drechsel