PHP脚本适用于Firefox,但不适用于Chrome

时间:2017-03-03 02:40:58

标签: php html google-chrome firefox

我一直试图解决这个问题几天,我找不到修复方法。

所以我有一个非常基本的PHP脚本,它运行一个文本转语音命令行工具并输出一个mp3文件。我想为它创建一个前端,这里是:

<!DOCTYPE HTML>
<html lang = "en">
<head>
<title>TTS App</title>
<meta charset = "UTF-8" />
</head>
<body>
<center>
<form action="ttsapp.php" method="post">
    <TEXTAREA name="text" rows="20" cols="80"></TEXTAREA><br>
    <select name="voice">
        <option value="4">English</option>
        <option value="3">French</option>
    </select>
    <input type="submit" value="Submit" />
</form>
</center>
</body>
</html>

这是PHP代码

<?php
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
  define('ESPEAK', 'sapitts\tts.exe');
  define('LAME', 'eSpeak\command_line\lame\lame.exe');
} else {
  define('ESPEAK', '/usr/bin/espeak');
  define('LAME', '/usr/bin/lame');
}

if (!empty($_POST['voice'])) {
    $voice = $_POST['voice'];
} else {
  $voice = '4';
}
  $text = $_POST['text'];
  $filename = md5($text) . '.wav';

 $filepath =  'voicesmp3/v' . $voice . 's' . $filename;
 $filepath1 = 'voicesmp3/v' . $voice . 's' . md5($text) . '0' . '.mp3';
 $filepath2 = 'voicesmp3/v' . $voice . 's' . md5($text) . '0' . '.wav';
  $text = escapeshellarg($text);
if (!file_exists($filepath1)) {
  $cmd = ESPEAK." -v $voice -o $filepath $text && ".LAME." -q0 -b128 --vbr-new $filepath2";
    exec($cmd);
}
  header('Content-Type: audio/mpeg');
  header('Content-Length: ' . filesize($filepath1));
  readfile($filepath1);
?>

以下是问题: 就像我在标题中所说的,这个脚本适用于Firefox,但不适用于Chrome。我决定和Fiddler一起调查,我发现Firefox只会发送一个POST并播放正确的文件,但是Chrome会发送一个POST(用正确的文件回复),然后 Chrome会发送另一个GET请求即可。该脚本将再次响应,但由于没有POST变量,它们都是空的,我得到一个没有声音的文件。我想要发生的是正确的变量被发布,并且php脚本读取正确的文件,而不是它运行两次并播放一个空文件,就像它当前使用Chrome一样。我还要提一下,Chrome完成的第二个GET请求只是请求php文件,它与POST文件的URL相同。

我在Wampserver上托管文件。

我真的不知道如何解决这个问题。我的代码中没有看到任何可能导致问题的错误,所以如果这里的任何人都可以提供一些关于为什么的见解,它可以在一个浏览器中工作,而不是在另一个浏览器中工作,以及如何修复它,非常感谢。

2 个答案:

答案 0 :(得分:0)

刚做了一个实验,我可以复制你的场景。

似乎与$ filepath和$ filepath1是否正确有关:

例如,如果我键入&#34;测试&#34;在textarea并选择英语

$ filepath1将是: voicemp3 / v4s0cbc6611f5540bd0809a388dc95a615b0.mp3

$ filepath将是: voicemp3 / v4sd41d8cd98f00b204e9800998ecf8427e.wav

如果$ filepath1中的文件不存在,代码将转到

if (!file_exists($filepath1)) {
    $cmd = ESPEAK." -v $voice -o $filepath $text && ".LAME." -q0 -b128 --vbr-new $filepath2";
    exec($cmd);
}

我无法想象它的作用。可能按$ filepath1创建文件。但它取决于$ filepath。如果$ filepath中的文件也丢失了,您将始终在Fiddler中找到一个GET请求,其中包含206个部分内容响应。

所以我怀疑它可能是由于没有wav / mp3文件引起的。它与浏览器行为无关。

----------------------------------------------- - 更新于2017-03-03 ------------------------------------------ ---------

确认这是与Chrome相关的已发布。

chrome触发空GET请求的原因是重定向后生成的html:

铬:

<video controls="" autoplay="" name="media"><source src="http://127.0.0.1/test/ttsapp.php" type="audio/mpeg"></video>

火狐:

<video style="height: 28px; width: 66%;" controls="" autoplay=""></video>

src属性的cos,chrome会再次调用URL。

答案 1 :(得分:0)

再次,我。在这一点上,我只能四处走动。

之后

if (!file_exists($filepath1)) {
  $cmd = ESPEAK." -v $voice -o $filepath $text && ".LAME." -q0 -b128 --vbr-new $filepath2";
  exec($cmd);   
}

//This is to encode your mp3 file as base64     
$fileContent = 'data:video/mp3;base64,' . base64_encode(file_get_contents($filepath1));

//close the PHP tag here
?> 

<!-- From here it is pure html, point the SRC to the base64 -->
<video controls="" autoplay="" name="media"><source src="<?php echo $fileContent?>" type="audio/mpeg"></video>