title: Video streaming - dealing with header 206 (php to HTML5)
body: <p>As usual, it never works for me...</p>
  
  <p>I try to stream video and I'm doing very well with the code below:</p>
  
  <pre><code>function send_back_video($video_path)
  {
      ob_clean();
      $mime = "application/octet-stream"; // The MIME type of the file, this should be replaced with your own.
      $size = filesize($video_path); // The size of the file
  
      // Send the content type header
      header('Content-type: ' . $mime);
  
      // Check if it's a HTTP range request
      if(isset($_SERVER['HTTP_RANGE']))
      {       
          // Parse the range header to get the byte offset
          $ranges = array_map(
              'intval', // Parse the parts into integer
              explode(
                  '-', // The range separator
                  substr($_SERVER['HTTP_RANGE'], 6) // Skip the `bytes=` part of the header
              )
          );
  
          // If the last range param is empty, it means the EOF (End of File)
          if(!$ranges[1]){
              $ranges[1] = $size - 1;
          }
  
          // Send the appropriate headers
          header('HTTP/1.1 206 Partial Content');
          header('Accept-Ranges: bytes');
          header('Content-Length: ' . ($ranges[1] - $ranges[0])); // The size of the range
  
          // Send the ranges we offered
          header(
              sprintf(
                  'Content-Range: bytes %d-%d/%d', // The header format
                  $ranges[0], // The start range
                  $ranges[1], // The end range
                  $size // Total size of the file
              )
          );
  
          // It's time to output the file
          $f = fopen($video_path, 'rb'); // Open the file in binary mode
          $chunkSize = 8192; // The size of each chunk to output
  
          // Seek to the requested start range
          fseek($f, $ranges[0]);
  
          // Start outputting the data
          while(true)
          {
  
              // Check if we have outputted all the data requested
              if(ftell($f) &gt;= $ranges[1])
              {
                  break;
              }
  
              // Output the data
              echo fread($f, $chunkSize);
  
              // Flush the buffer immediately
              @ob_flush();
              flush();
          }
      }
      else {
          // It's not a range request, output the file anyway
          header('Content-Length: ' . $size);
  
          // Read the file
          @readfile($file);
  
          // and flush the buffer
          @ob_flush();
          flush();
      }
  }
  </code></pre>
  
  <p>"So if it works, what do you want?" - you might ask..</p>
  
  <p>As I stated before, the code does a very good job, BUT there is 1 issue.</p>
  
  <p>If I start to play video, php sends <code>header('HTTP/1.1 206 Partial Content')</code> and this (video) request stays open till EOF, what means, I am FORCED to download entire video even if don't want to (let's say I'm clicking on the next video).</p>
  
  <p>My JS removes video tag (this should ABORT request) and creates new video tag with new link. ABORT part is not happening.</p>
  
  <p>Here you can see GET the example:
  <a href="https://i.stack.imgur.com/TOGdQ.png" rel="noreferrer"><img src="https://i.stack.imgur.com/TOGdQ.png" alt="enter image description here"></a></p>
  
  <ol>
  <li>1st - initial video get</li>
  <li>2nd - play button pressed </li>
  <li>3rd - navigate away - new DOM item created and waiting to appear.</li>
  </ol>
  
  <p>So what I'm looking for, is some option to close the connection on navigate away.
  I saw youtube does many GETs. As I understand every GET brings new "chunk" when previous "chunk" close to end. It's very good option, but it cancels buffering and I want to be able to buffer video.</p>
  
  <p>P.S.</p>
  
  <p>For sure I'm doing something wrong, I just can't see what.</p>
  
  <p>P.P.S.</p>
  
  <p>I'm not the author of the code.</p>