我一直试图解决这个问题几天,我找不到修复方法。
所以我有一个非常基本的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上托管文件。
我真的不知道如何解决这个问题。我的代码中没有看到任何可能导致问题的错误,所以如果这里的任何人都可以提供一些关于为什么的见解,它可以在一个浏览器中工作,而不是在另一个浏览器中工作,以及如何修复它,非常感谢。
答案 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>