Javascript firefox与chrome中的php流式wav
我在页面中有一个隐藏的音频元素,我正在动态地设置源。我将它设置为一个php页面,带有一个GET请求,该请求根据GET参数查找文件 然而,音频元素在Chrome中可以很好地处理wav文件,而在firefox中则不行。下面是查询和htmlJavascript firefox与chrome中的php流式wav,javascript,php,google-chrome,firefox,audio,Javascript,Php,Google Chrome,Firefox,Audio,我在页面中有一个隐藏的音频元素,我正在动态地设置源。我将它设置为一个php页面,带有一个GET请求,该请求根据GET参数查找文件 然而,音频元素在Chrome中可以很好地处理wav文件,而在firefox中则不行。下面是查询和html <html> <audio id = "play_wav" controls> <span id = "set_source">set source</span> <script> $('#se
<html>
<audio id = "play_wav" controls>
<span id = "set_source">set source</span>
<script>
$('#set_source').on('click', function(){
$('#play_wav').attr('src', 'get_wav.php?fname=playme.wav');
document.getElementById('play_wav').play();
});
</script>
</html>
所以这是在chrome上播放流媒体音频,而不是在firefox上。源代码仍在设置中,只是没有加载。有什么建议吗?首先,您不应该将音频文件存储在与php文件相同的目录中,因为使用隔离文件名的函数很容易防止有人加载您的php文件,否则您必须进一步检查它不是传递到
$的php或系统文件路径['fname']
参数,您还应该在媒体文件夹中放置一个.htaccess,其中包含deny from all
,这将停止直接访问,如果您希望能够使用seek-able功能进行流式传输,则需要处理HTTP\u范围头
<?php
if(!empty($_GET['fname'])){
$file_name = './wav_files/'.basename($_GET['fname']);
stream($file_name, 'audio/wav');
}
/**
* Streamable file handler
*
* @param String $file_location
* @param Header|String $content_type
* @return content
*/
function stream($file, $content_type = 'application/octet-stream') {
// Make sure the files exists
if (!file_exists($file)) {
header("HTTP/1.1 404 Not Found");
exit;
}
// Get file size
$filesize = sprintf("%u", filesize($file));
// Handle 'Range' header
if(isset($_SERVER['HTTP_RANGE'])){
$range = $_SERVER['HTTP_RANGE'];
}elseif($apache = apache_request_headers()){
$headers = array();
foreach ($apache as $header => $val){
$headers[strtolower($header)] = $val;
}
if(isset($headers['range'])){
$range = $headers['range'];
}
else $range = FALSE;
} else $range = FALSE;
//Is range
if($range){
$partial = true;
list($param, $range) = explode('=',$range);
// Bad request - range unit is not 'bytes'
if(strtolower(trim($param)) != 'bytes'){
header("HTTP/1.1 400 Invalid Request");
exit;
}
// Get range values
$range = explode(',',$range);
$range = explode('-',$range[0]);
// Deal with range values
if ($range[0] === ''){
$end = $filesize - 1;
$start = $end - intval($range[0]);
} else if ($range[1] === '') {
$start = intval($range[0]);
$end = $filesize - 1;
}else{
// Both numbers present, return specific range
$start = intval($range[0]);
$end = intval($range[1]);
if ($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1)))) $partial = false;
}
$length = $end - $start + 1;
}
// No range requested
else {
$partial = false;
$length = $filesize;
}
// Send standard headers
header("Content-Type: $content_type");
header("Content-Length: $length");
header('Accept-Ranges: bytes');
// send extra headers for range handling...
if ($partial) {
header('HTTP/1.1 206 Partial Content');
header("Content-Range: bytes $start-$end/$filesize");
if (!$fp = fopen($file, 'rb')) { // Error out if we can't read the file
header("HTTP/1.1 500 Internal Server Error");
exit;
}
if ($start) fseek($fp,$start);
while($length){
set_time_limit(0);
$read = ($length > 8192) ? 8192 : $length;
$length -= $read;
print(fread($fp,$read));
}
fclose($fp);
}
//just send the whole file
else readfile($file);
exit;
}
?>
sidenote您的当前php代码可能会受到攻击,例如get_wav.php?fname=index.php
将回显index.php文件的源代码。另一个sidenote您在get_waw.php
附近的isset()中有语法错误
。我知道数据库中的paramater实际上是和别名。谢谢。这只是为了说明一个问题。我刚刚尝试了这个方法,但无法在firefox或chrome上使用。apache logI中没有错误,只是通过添加标题('Content-type:audio/wav)使其工作,firefox对此没有问题
<?php
if(!empty($_GET['fname'])){
$file_name = './wav_files/'.basename($_GET['fname']);
stream($file_name, 'audio/wav');
}
/**
* Streamable file handler
*
* @param String $file_location
* @param Header|String $content_type
* @return content
*/
function stream($file, $content_type = 'application/octet-stream') {
// Make sure the files exists
if (!file_exists($file)) {
header("HTTP/1.1 404 Not Found");
exit;
}
// Get file size
$filesize = sprintf("%u", filesize($file));
// Handle 'Range' header
if(isset($_SERVER['HTTP_RANGE'])){
$range = $_SERVER['HTTP_RANGE'];
}elseif($apache = apache_request_headers()){
$headers = array();
foreach ($apache as $header => $val){
$headers[strtolower($header)] = $val;
}
if(isset($headers['range'])){
$range = $headers['range'];
}
else $range = FALSE;
} else $range = FALSE;
//Is range
if($range){
$partial = true;
list($param, $range) = explode('=',$range);
// Bad request - range unit is not 'bytes'
if(strtolower(trim($param)) != 'bytes'){
header("HTTP/1.1 400 Invalid Request");
exit;
}
// Get range values
$range = explode(',',$range);
$range = explode('-',$range[0]);
// Deal with range values
if ($range[0] === ''){
$end = $filesize - 1;
$start = $end - intval($range[0]);
} else if ($range[1] === '') {
$start = intval($range[0]);
$end = $filesize - 1;
}else{
// Both numbers present, return specific range
$start = intval($range[0]);
$end = intval($range[1]);
if ($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1)))) $partial = false;
}
$length = $end - $start + 1;
}
// No range requested
else {
$partial = false;
$length = $filesize;
}
// Send standard headers
header("Content-Type: $content_type");
header("Content-Length: $length");
header('Accept-Ranges: bytes');
// send extra headers for range handling...
if ($partial) {
header('HTTP/1.1 206 Partial Content');
header("Content-Range: bytes $start-$end/$filesize");
if (!$fp = fopen($file, 'rb')) { // Error out if we can't read the file
header("HTTP/1.1 500 Internal Server Error");
exit;
}
if ($start) fseek($fp,$start);
while($length){
set_time_limit(0);
$read = ($length > 8192) ? 8192 : $length;
$length -= $read;
print(fread($fp,$read));
}
fclose($fp);
}
//just send the whole file
else readfile($file);
exit;
}
?>