title: html5 / mp4 video won't play in mobile browsers when streaming from PHP
body: <p>I am trying to stream mp4 videos using html5 on mobile browsers with PHP.</p>
  
  <p>I am using the following class: </p>
  
  <p><a href="http://labs.divx.com/node/17030" rel="nofollow">http://labs.divx.com/node/17030</a></p>
  
  <p>The script works fine except for the reference to the mime_types array which I had to remove the $ to make it work.</p>
  
  <p>Anyhow, my problem is this.
  When I run this script with a file.mp4 it runs fine on my phone.</p>
  
  <p>But as soon as I put code in to validate if the file is allowed to be played, etc.
  (if the customer has purchased the video, if they have exceeded the number of views allowed, etc)</p>
  
  <p>The file won't load at all.</p>
  
  <p>It does load in desktop browsers though. It is only in mobile browsers that it doesn't load.</p>
  
  <p>Here is the code I use to play the file:</p>
  
  <p>When I run it like this, it works in desktop browsers, but not mobile:</p>
  
  <pre><code>&lt;?php
  apc_clear_cache();
  session_start();
  require(dirname(__FILE__) . "/../_includes/config.php");
  require(dirname(__FILE__) . "/../_includes/validate_session.php");
  
  $id = (int)$_GET['id'];
  
  if (!$result = $mysqli-&gt;query('SELECT
  orders_item_product_downloadable_videos.id,
  orders_item_product_downloadable_videos.current_no_downloads,
  DATE_ADD(IF(orders.id IS NOT NULL,orders.date_order,o.date_order),INTERVAL orders_item_product_downloadable_videos.no_days_expire DAY) AS date_expire,
  product_downloadable_videos.embed_code,
  orders_item_product_downloadable_videos.no_days_expire,
  orders_item_product_downloadable_videos.no_downloads,
  product_downloadable_videos.filename,
  product_downloadable_videos.stream,
  product_downloadable_videos.source
  
  FROM 
  orders_item_product_downloadable_videos 
  LEFT JOIN
  (orders_item_product CROSS JOIN orders_item CROSS JOIN orders)
  ON
  (orders_item_product_downloadable_videos.id_orders_item_product = orders_item_product.id AND orders_item_product.id_orders_item = orders_item.id AND orders_item.id_orders = orders.id)
  
  LEFT JOIN
  (orders_item_product AS oip CROSS JOIN orders_item_product AS oip_parent CROSS JOIN orders_item AS oi CROSS JOIN orders AS o)
  ON
  (orders_item_product_downloadable_videos.id_orders_item_product = oip.id AND oip.id_orders_item_product = oip_parent.id AND oip_parent.id_orders_item = oi.id AND oi.id_orders = o.id)
  
  INNER JOIN 
  product_downloadable_videos
  ON
  (orders_item_product_downloadable_videos.id_product_downloadable_videos = product_downloadable_videos.id)
  WHERE
  orders_item_product_downloadable_videos.id = "'.$id.'"
  AND
  (
  (orders.id IS NOT NULL AND orders.status IN (1,7) AND orders.id_customer = "'.(int)$_SESSION['customer']['id'].'")
  OR
  (o.id IS NOT NULL AND o.status IN (1,7) AND o.id_customer = "'.(int)$_SESSION['customer']['id'].'")
  )       
  LIMIT 1')) throw new Exception('An error occured while trying to get video info.'."\r\n\r\n".$mysqli-&gt;mysqli-&gt;error);
  
  if (!$result-&gt;num_rows) {
  //throw new Exception(language('account/order', 'ERROR_DOWNLOAD_EXPIRED'));
  exit;   
  }       
  
  $row = $result-&gt;fetch_assoc();  
  $result-&gt;free();
  
  if ($row['no_downloads'] &gt; 0 &amp;&amp; $row['current_no_downloads'] &gt;= $row['no_downloads']) {
  //throw new Exception(language('account/order', 'ERROR_NO_DOWNLOADS_REACHED'));
  exit;   
  }       
  
  if ($row['no_days_expire'] &gt; 0 &amp;&amp; strtotime($row['date_expire']) &lt;= time()) {
  //throw new Exception(language('account/order', 'ERROR_DOWNLOAD_EXPIRED'));
  exit;               
  }
  
  $file = dirname(__FILE__).'/../admin/protected/streaming_videos/'.$row['source'];
  
  require(dirname(__FILE__).'/../_includes/classes/stream.php');
  
  $st = new VSTREAM();
  $st-&gt;stream(dirname(__FILE__).'/../397d729225599bcda978ac4fd4aaeba2.mp4');
  </code></pre>
  
  <p>When I comment and run it like this, it works in mobile browsers, but why?</p>
  
  <pre><code>&lt;?php
  apc_clear_cache();
  session_start();
  require(dirname(__FILE__) . "/../_includes/config.php");
  
  require(dirname(__FILE__).'/../_includes/classes/stream.php');
  
  $st = new VSTREAM();
  $st-&gt;stream(dirname(__FILE__).'/../397d729225599bcda978ac4fd4aaeba2.mp4');
  </code></pre>
  
  <p>If I add the validation_session.php code, it doesn't work. </p>
  
  <pre><code>&lt;?php
  apc_clear_cache();
  session_start();
  require(dirname(__FILE__) . "/../_includes/config.php");
  require(dirname(__FILE__) . "/../_includes/validate_session.php");
  
  require(dirname(__FILE__).'/../_includes/classes/stream.php');
  
  $st = new VSTREAM();
  $st-&gt;stream(dirname(__FILE__).'/../397d729225599bcda978ac4fd4aaeba2.mp4');
  </code></pre>
  
  <p>The validation_session.php code only has this inside:</p>
  
  <pre><code>&lt;?php
  if(!$_SESSION['customer']['id']){
      header("Location: /account/login");
      exit;
  }
  ?&gt;
  </code></pre>
  
  <p>I even tested the session by outputting it on the screen with the non working short code and i could see the $_SESSION['customer']['id'] did exist.</p>
  
  <p>So I do not know what I am missing here.</p>
  
  <p>If anybody has any idea why this is not working, I would really appreciate your input on this!</p>
  
  <p>Thanks!</p>