title: Chrome issue - video stream & session conflict
body: <p>I have a problem with the implementation of videos in javascript and PHP.</p>
  <p>index.php</p>
  <pre><code>session_start()
  
  // do other stuff
  include ‘video.php’
  </code></pre>
  <p>video.php</p>
  <pre><code>&lt;?php
  If(!$_REQUEST[‘play’]){
      // displaying video.html
  }
  else
  {
      // play video
  $fp = @fopen($file, 'rb');
  
  $size   = filesize($file); // File size
  $length = $size;           // Content length
  $start  = 0;               // Start byte
  $end    = $size - 1;       // End byte
  
  // Now that we've gotten so far without errors we send the accept range header
  
  /* At the moment we only support single ranges.
   * Multiple ranges requires some more work to ensure it works correctly
   * and comply with the specifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
   *
   * Multirange support announces itself with:
   * header('Accept-Ranges: bytes');
   *
   * Multirange content must be sent with multipart/byteranges media type,
   * (mediatype = mimetype)
   * as well as a boundary header to indicate the various chunks of data.
   */
   
  header('Content-type: video/mp4');
  header('Accept-Ranges: bytes');
  // multipart/byteranges
  // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
  if (isset($_SERVER['HTTP_RANGE'])){
      $c_start = $start;
      $c_end   = $end;
      // Extract the range string
      list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
      // Make sure the client hasn't sent us a multibyte range
      if (strpos($range, ',') !== false){
          // (?) Shoud this be issued here, or should the first
          // range be used? Or should the header be ignored and
          // we output the whole content?
          header('HTTP/1.1 416 Requested Range Not Satisfiable');
          header(&quot;Content-Range: bytes $start-$end/$size&quot;);
          // (?) Echo some info to the client?
          exit;
      } // fim do if
  
      // If the range starts with an '-' we start from the beginning
      // If not, we forward the file pointer
      // And make sure to get the end byte if spesified
      if ($range{0} == '-'){
          // The n-number of the last bytes is requested
          $c_start = $size - substr($range, 1);
      } else {
          $range  = explode('-', $range);
          $c_start = $range[0];
          $c_end   = (isset($range[1]) &amp;&amp; is_numeric($range[1])) ? $range[1] : $size;
      } // fim do if
      /* Check the range and make sure it's treated according to the specs.
       * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
       */
      // End bytes can not be larger than $end.
      $c_end = ($c_end &gt; $end) ? $end : $c_end;
      // Validate the requested range and return an error if it's not correct.
      if ($c_start &gt; $c_end || $c_start &gt; $size - 1 || $c_end &gt;= $size){
          header('HTTP/1.1 416 Requested Range Not Satisfiable');
          header(&quot;Content-Range: bytes $start-$end/$size&quot;);
          // (?) Echo some info to the client?
          exit;
      } // fim do if
  
      $start  = $c_start;
      $end    = $c_end;
      $length = $end - $start + 1; // Calculate new content length
      fseek($fp, $start);
      header('HTTP/1.1 206 Partial Content');
  } // fim do if
  
  // Notify the client the byte range we'll be outputting
  header(&quot;Content-Range: bytes $start-$end/$size&quot;);
  header(&quot;Content-Length: $length&quot;);
  // Start buffered download
  $buffer = 1024 * 8;
  while(!feof($fp) &amp;&amp; ($p = ftell($fp)) &lt;= $end){
      if ($p + $buffer &gt; $end){
          // In case we're only outputtin a chunk, make sure we don't
          // read past the length
          $buffer = $end - $p + 1;
      } // fim do if
      set_time_limit(0); // Reset time limit for big files
      echo fread($fp, $buffer);
      flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
   } // fim do while
   fclose($fp);
   exit();
  }
  </code></pre>
  <p>video.html</p>
  <pre><code>&lt;!doctype html&gt;
  &lt;html lang=&quot;fr-FR&quot;&gt;
      &lt;head&gt;
          &lt;meta charset=&quot;utf-8&quot;&gt;
          &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge,chrome=1&quot;&gt;
          &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;video controls&gt;
              &lt;source src=&quot;index.php?format=mp4&amp;play=1&amp;id=someid type=&quot;video/mp4&quot; /&gt;
          &lt;/video&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p>Everything works fine but for some reason I don't know, when I start playing a video and then click on a link on my page or use the browser's back button, the browser freezes and waits a while ( variable ) before following the link.</p>
  <p>The profiler indicates that the requested page change is in pending status.</p>
  <p>If I position the video cursor further away, the browser unlocks instantly and follows the link I clicked.</p>
  <p>And finally, if I reload that page, the issue doesn't appear anymore. Seems that chrome waits for something but it's not cached since my cache is disabled.</p>
  <p>This occurs only with chrome desktop, all other browsers do the job correctly.</p>
  <p>** EDIT **</p>
  <p>I found the problem's origin.</p>
  <p>To play my video I go through my main file <code>index.php</code> which serves as my router in which I initialize the session with <code>session_start()</code>.</p>
  <p>When the video is playing and I click on a link or the back button of my browser, I go back to <code>index.php</code>. This is when chrome gets stuck during the session_start()</p>
  <p>It looks like there's a conflict with the sessions as long as the video is playing.</p>