【问题标题】:html5 / mp4 video won't play in mobile browsers when streaming from PHP从 PHP 流式传输时,html5 / mp4 视频不会在移动浏览器中播放
【发布时间】:2013-04-10 20:28:28
【问题描述】:

我正在尝试在使用 PHP 的移动浏览器上使用 html5 流式传输 mp4 视频。

我正在使用以下类:

http://labs.divx.com/node/17030

脚本工作正常,除了对 mime_types 数组的引用,我必须删除 $ 才能使其工作。

无论如何,我的问题是这样的。 当我使用 file.mp4 运行此脚本时,它在我的手机上运行良好。

但只要我输入代码以验证是否允许播放文件等。 (如果客户购买了视频,如果他们超过了允许的观看次数等)

文件根本不会加载。

不过,它确实会在桌面浏览器中加载。它仅在移动浏览器中不加载。

这是我用来播放文件的代码:

当我这样运行它时,它可以在桌面浏览器中运行,但不能在移动设备上运行:

<?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->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->mysqli->error);

if (!$result->num_rows) {
//throw new Exception(language('account/order', 'ERROR_DOWNLOAD_EXPIRED'));
exit;   
}       

$row = $result->fetch_assoc();  
$result->free();

if ($row['no_downloads'] > 0 && $row['current_no_downloads'] >= $row['no_downloads']) {
//throw new Exception(language('account/order', 'ERROR_NO_DOWNLOADS_REACHED'));
exit;   
}       

if ($row['no_days_expire'] > 0 && strtotime($row['date_expire']) <= 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->stream(dirname(__FILE__).'/../397d729225599bcda978ac4fd4aaeba2.mp4');

当我这样评论和运行它时,它可以在移动浏览器中运行,但是为什么呢?

<?php
apc_clear_cache();
session_start();
require(dirname(__FILE__) . "/../_includes/config.php");

require(dirname(__FILE__).'/../_includes/classes/stream.php');

$st = new VSTREAM();
$st->stream(dirname(__FILE__).'/../397d729225599bcda978ac4fd4aaeba2.mp4');

如果我添加validation_session.php 代码,它就不起作用。

<?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->stream(dirname(__FILE__).'/../397d729225599bcda978ac4fd4aaeba2.mp4');

validation_session.php 代码里面只有这个:

<?php
if(!$_SESSION['customer']['id']){
    header("Location: /account/login");
    exit;
}
?>

我什至通过在屏幕上使用无效的短代码输出会话来测试会话,我可以看到 $_SESSION['customer']['id'] 确实存在。

所以我不知道我在这里缺少什么。

如果有人知道为什么这不起作用,我非常感谢您对此的意见!

谢谢!

【问题讨论】:

  • 您是否检查了所需文件上可能存在的 BOM?可能这些需要的文件在?&gt;后面有一些空格,可能会导致headers丢失。
  • 你在什么手机上运行这个?它是否允许使用 cookie(或者它们是否被禁用)?您可能想尝试简化版本以查看 Session 是否有效。或尝试 error_reporting:php.net/manual/en/function.error-reporting.php
  • 是的,我检查了所有相关文件,它们都很好,没有空格。另外,我正在 Windows Phone 8 上对其进行测试,但我知道它也不适用于 iphone。会话很好,我已经完成了测试,还打印了 $_SESSION 数组,可以看到里面包含的值。我还在标题后的 validate_session 文件中放置了一个 echo 'test',并且可以看到它出现时没有标题已经输出错误。
  • 这是一个更新,我也回显了 SQL 查询并且值是正确的,甚至在 phpmyadmin 中运行它,它运行良好并返回一行。所以那里没有问题。 (在手机上做的)

标签: php mobile streaming mp4


【解决方案1】:

除非会话的 UID 在 URL 中传播,否则它会存储在 cookie 中。如果页面在桌面上正常工作并且仅在您不验证会话时在移动设备上工作,则该问题必须与某处的 cookie 相关联。很可能,您的移动浏览器没有保存 cookie,因此在尝试确认会话时会将您踢出。

或者,您可以在 URL 中传递会话 ID: http://php.net/manual/en/session.idpassing.php

如果您可以让它与查询字符串中的会话 ID 一起工作,那么您就知道这是一个 cookie 问题。

【讨论】:

  • 伙计,我真希望你能出现在那个人身上!我做了测试,结果不是那么不幸!这很奇怪!该死的。
  • 该死。本来很容易解决的。你在其他设备上测试过吗?每部手机都有问题吗??
  • Ynfortunately 我没有要测试的所有手机,但我知道在我的 windows phone 8 上它不起作用,但在 iphone 4 上似乎可以,在 iphone 3 上它没有(我认为它与 iphone 3 的 mp4 有关?)我还尝试查看我的脚本中的响应标头,看起来还可以,只是一些缓存标头。有趣的是,当我删除 validate_session 行时,如果我不删除下面的整个代码(mysqli 查询),它也不起作用,但查询本身有效,因为我在我的手机上做了一个 sql 的回显,还有一个打印 $row 返回的数组。
  • 嗯只是做了一些测试,现在似乎可以在 iphone 3gs、iphone 4 但不能在 windows phone 8 上运行,还没有在 android 上测试。这仍然与上面相同的测试,很奇怪!
  • 好吧,经过更多的测试,我得出的结论是,这是 iphone 部分的分辨率问题,因为 3gs 是 640x480,更高的分辨率将无法工作。所以很可能所有设备都是一样的。但是,windows phone 的问题仍然存在,它可以在没有 validate_session 和 mysqli 代码的情况下工作,但不能使用它。
【解决方案2】:

好的,结束这个问题,移动播放的主要原因是每台设备的最大分辨率。

对于 windows phone 8 设备问题,我仍然没有任何线索。 这似乎是断断续续的,我可以在另一台服务器上播放它,然后通过更改一些代码并稍后将其删除,但现在它似乎可以工作,我不知道为什么,所以我没有碰它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    相关资源
    最近更新 更多