title: PHP: iPad does not play MP4 videos delivered by PHP, but if accessed directly it does
body: <p>I am trying to find a solution for this problem for some days already, I tried all advices I could find here on stackoverflow and other platforms. And still, there is no solution.</p>
  
  <p>I am embedding a video via HTML5 video tag: </p>
  
  <pre><code> &lt;video poster="thumb.png" controls="controls" preload="none" width="640" height="480"&gt;
      &lt;source src="provider.php?secure=12345" type="video/mp4"&gt;
   &lt;/video&gt;
  </code></pre>
  
  <p>I try to deliver the MP4 video file by PHP instead of linking it directly. Linking the mp4 file directly works and plays the file!</p>
  
  <p>Testing: </p>
  
  <ol>
  <li>the video file: <a href="https://github.com/q2apro/videotest-ipad/raw/master/video.mp4" rel="noreferrer">https://github.com/q2apro/videotest-ipad/raw/master/video.mp4</a> (plays on iPad)</li>
  <li>the video file loaded by PHP with same headers: <a href="https://github.com/q2apro/videotest-ipad/blob/master/test-headers.php" rel="noreferrer">https://github.com/q2apro/videotest-ipad/blob/master/test-headers.php</a> (not playing on iPad) - <a href="https://github.com/q2apro/videotest-ipad/blob/master/test-headers.txt" rel="noreferrer">Sourcecode</a></li>
  <li>the video file loaded by PHP with Byte Ranges: <a href="https://github.com/q2apro/videotest-ipad/blob/master/test-byterange.php" rel="noreferrer">https://github.com/q2apro/videotest-ipad/blob/master/test-byterange.php</a> (not playing on iPad) - <a href="https://github.com/q2apro/videotest-ipad/blob/master/test-byterange.txt" rel="noreferrer">Sourcecode</a></li>
  <li>the video file loaded by PHP with Byte Ranges (another script): <a href="https://github.com/q2apro/videotest-ipad/blob/master/test-byterange-2.php" rel="noreferrer">https://github.com/q2apro/videotest-ipad/blob/master/test-byterange-2.php</a> (not playing on iPad, alert "The operation could not be completed") - <a href="https://github.com/q2apro/videotest-ipad/blob/master/test-byterange-2.txt" rel="noreferrer">Sourcecode</a></li>
  </ol>
  
  <p>Notes:</p>
  
  <ul>
  <li>all links above are directly accessing/playing the video file without embed tag</li>
  <li>video works on all browsers in Windows (but not in Safari/Chrome on iPad, probably not iPhone either)</li>
  </ul>
  
  <p>My Setup: </p>
  
  <ul>
  <li>testing device: iPad iOS 6 (I don't have a mac, <a href="https://stackoverflow.com/questions/12583275/ios6-removed-console-log-for-ipad-how-to-use-web-inspector-on-windows">cannot debug</a>)</li>
  <li>iPad with Safari and Chrome (tried both browsers)</li>
  <li>my server is shared-hosting from <a href="http://www.df.eu/" rel="noreferrer">domainfactory</a></li>
  <li>tool for debugging: Firefox 29 Web Developer Console / WIN7</li>
  </ul>
  
  <p>The <code>.htaccess</code> in the test folder sets the MIME type and Accept-Ranges: </p>
  
  <pre><code>AddType video/mp4 .mp4 
  
  &lt;IfModule mod_headers.c&gt;
     Header set Accept-Ranges "bytes"
  &lt;/IfModule&gt;
  </code></pre>
  
  <p><br />
  Even though I created the <strong>same header</strong> (compare test URLs <a href="https://github.com/q2apro/videotest-ipad/blob/master/video.mp4" rel="noreferrer">1.</a> and <a href="https://github.com/q2apro/videotest-ipad/blob/master/test-headers.php" rel="noreferrer">2.</a>), the iPad is not playing the file through the PHP request. </p>
  
  <p>Instead I always get this strikedthrough play button: </p>
  
  <p><img src="https://github.com/q2apro/videotest-ipad/blob/master/screenshot-play-button.jpg" alt="ipad strikedthrough play button"></p>
  
  <p>The headers of <a href="https://github.com/q2apro/videotest-ipad/blob/master/video.mp4" rel="noreferrer">1. (direct mp4 call)</a>: </p>
  
  <p><img src="https://raw.githubusercontent.com/q2apro/videotest-ipad/master/screenshot-video-mp4-direct-call.png" alt="mp4 direct call"></p>
  
  <p>The headers of <a href="https://github.com/q2apro/videotest-ipad/blob/master/test-headers.php" rel="noreferrer">2.</a> The same headers as above, but set up by PHP (mp4 delivered by PHP): </p>
  
  <p><img src="https://raw.githubusercontent.com/q2apro/videotest-ipad/master/screenshot-video-mp4-php-delivered.png" alt="enter image description here"></p>
  
  <p>--</p>
  
  <p>I have also tried reading the entire video file and sending it to the browser using PHP's <a href="http://www.php.net/manual/en/function.fread.php" rel="noreferrer">fread()</a>, <a href="http://www.php.net/manual/en/function.fpassthru.php" rel="noreferrer">fpassthru()</a> and <a href="http://www.php.net/manual/en/function.file-get-contents.php" rel="noreferrer">file_get_contents()</a> but the iPad is always showing the cannot-play-icon.</p>
  
  <p>--</p>
  
  <p>My hosted server does not supply Connection keep-alive, could this be a problem?
  Is the iPad interpreting .php different from .mp4?</p>
  
  <p>Can somebody help me out of pain? I am totally stuck.</p>
  
  <p><br />
  <br /></p>
  
  <p>PS: What I tried to consider: </p>
  
  <ul>
  <li>Byte range requests (206 partial content) <a href="https://groups.google.com/forum/#!msg/iphonewebdev/eUxLXLbVl2g/xuuTM9Ky9XoJ" rel="noreferrer">01</a> <a href="https://stackoverflow.com/questions/17966493/show-video-on-iphone-ipad-through-php">02</a> <a href="http://forums.phpfreaks.com/topic/106711-php-code-which-supports-byte-range-downloads-for-iphone/" rel="noreferrer">03</a></li>
  <li>correct video encoding <a href="https://stackoverflow.com/questions/4240915/h-264-encoded-mp4-presented-in-html5-plays-on-safari-but-not-ios-devices/13402284#13402284">04</a></li>
  <li>used other encoded videos while testing</li>
  <li>disabled zlib.output_compression in php scripts</li>
  </ul>
  
  <p><br />
  <br /></p>
  
  <h2>UPDATE: Debug Console</h2>
  
  <p>I finally got a MAC of a friend, connected the iPad, opened the Debug Console in Safari on the Mac, loaded the page on the iPad and checked the error messages appearing on the Mac (btw, how more complicated could apple force us to develop...). For all test scripts this error appears: </p>
  
  <pre><code>Failed to load resource: Plug-in handled load
  </code></pre>