【问题标题】:Sending mp3 file through PHP to be used with the audio tag of HTML5 fails in the middle of the mp3通过 PHP 发送 mp3 文件以与 HTML5 的音频标签一起使用在 mp3 中间失败
【发布时间】:2012-03-26 12:39:26
【问题描述】:

我正在尝试通过 PHP 脚本发送我的 mp3 文件,以便在 HTML 中隐藏文件的路径。一切正常,除了进入 mp3 chrome 的一半给我一个 GET [URL] 错误。 mp3 的其余部分只是空白。音频标签认为它仍在读取文件,但没有声音。

这就是我从 php 发送 mp3 文件的方式:

if (file_exists($filename)) {
  header("Content-Transfer-Encoding: binary"); 
  header("Content-Type: audio/mpeg");
  header('Content-length: ' . filesize($filename));
  header('Content-Disposition: inline; filename="' . $filename . '"');
  header('X-Pad: avoid browser bug');
  header('Cache-Control: no-cache');


  readfile($filename);
  exit;
}
else {
  header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found', true, 404);
  echo "no file";
}

编辑:我添加了 Etag 标头。它似乎让事情变得更好。问题仍然存在,但不那么频繁。 :-/

Edit2:我注意到发送到我的 PHP 文件的请求标头与直接发送到 mp3 文件的标头不同。实际上有一个 HTTP_RANGE 请求发送到 mp3 文件,但是当我尝试从 PHP 获取内容时,这个范围请求丢失了。 (这是在 Chrome 中)。知道为什么会这样吗?

【问题讨论】:

  • 您的脚本不支持范围,chrome 中的 HTML 5 标签可能会请求范围。使您的脚本支持范围或尝试使用较小的文件。另请参阅:Parsing HTTP_RANGE header in PHP.
  • 我的文件不是很大。平均大小小于 10MB。最大的可能是 30MB。默认内容范围是多少?我可以将其设置为 50 MB 之类的吗?
  • @hakre,这应该是一个答案。
  • @hakre,经过一番挖掘后,我认为 Range 问题不是问题,因为当我收到来自 html5 音频的请求时未设置 isset($_SERVER['HTTP_RANGE'])标签。还有其他想法吗?
  • 知道如何浏览浏览器检查器的人仍然可以使用该路径。不是说它毫无意义,但你并没有真正“隐藏”这样的事情。

标签: php mp3 html5-audio


【解决方案1】:

我知道这是一篇旧帖子,但我能够使用两个文件以及 index.php 和 example.php 来解决这个问题。

这是 example.php,它正在检查数据库中的哈希和 used 字段以了解该文件之前是否已使用过

<?php

  if(isset($_GET['hash'])){
    $mysqli = new mysqli('host_here','user_here','password_here','database_here');
    $result = $mysqli->query("select * from hashes where hash = '{$_GET['hash']}'  limit 1");

    $row = $result->fetch_array();
  }

  if(isset($row['used']) && $row['used'] == 0){
    $mysqli->query("update hashes set used=1 where hash = '{$_GET['hash']}'");
    $filename = "example.mp3";
    header("Content-Transfer-Encoding: binary");
    header("Content-Type: audio/mpeg");
    header('Content-length: ' . filesize($filename)); 
    //If this is a secret filename then don't include it.
    header('Content-Disposition: inline');
    //Otherwise you can add it like so, in order to give the download a filename
    //header('Content-Disposition: inline;filename='.$filename);
    header('Cache-Control: no-cache');


    readfile($filename);
    exit;
  }

  elseif(isset($row['used']) && $row['used'] == 1){
    die("you can't just download this dude");
  }

这里是带有音频标签的 index.php,它允许播放但不能下载 mp3。

<html>
<body>
<?php

  $mysqli = new mysqli('localhost','root','','test_mp3');
  $rand = mt_rand();
  $hash = md5($rand);
  $result = $mysqli->query("insert into hashes (hash,used) values('$hash',0)");

?>
  <audio controls>
    <source src="example.php?hash=<?=$hash?>" type="audio/mpeg">
  </audio>
</body>
</html>

有一个数据库表,其中只有一个散列和一个用于此示例的使用字段

【讨论】:

    猜你喜欢
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    相关资源
    最近更新 更多