На нашем сайте пользователи могут загружать аудиофайлы в формате mp3 и mp4. Они также могут установить частный / публичный флаг, чтобы запретить доступ другим пользователям, кроме них.
Мы хотим транслировать эти медиа-файлы и отображать их с помощью некоторых проигрывателей Javascript, но, поскольку нам нужно выполнить некоторую логику PHP, мы не можем позволить веб-серверу передавать их.
Каков эффективный способ для потоковой передачи этих средств и возможности выполнения некоторой логики PHP раньше (для предоставления или запрета доступа)?
Я написал и протестировал этот скрипт для загрузок. Должно также хорошо работать с потоковой передачей.
$file_name = $_GET['file'];
/* define UPLOADS_DIR */
$file_path = UPLOADS_DIR . $file_name;
if (!is_file($file_path)) {
header('HTTP/1.0 404 Not Found');
exit;
}
/* define has_access */
if (!has_access($file_name)) {
header('HTTP/1.0 403 Forbidden');
exit;
}
$file = fopen($file_path, 'rb');
if (!$file) {
header('HTTP/1.0 500 Internal Server Error');
exit;
}
$file_size = filesize($file_path);
$start = 0;
$end = $file_size - 1;
$length = $file_size;
if (isset($_SERVER['HTTP_RANGE'])) {
if (!preg_match('/^bytes=(\d*)-(\d*)/', $_SERVER['HTTP_RANGE'], $matches) || ($matches[1] === '' && $matches[2] === '')) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
fclose($file);
exit;
}
$start = (int)$matches[1];
$end = $matches[2] === '' ? $file_size - 1 : (int)$matches[2];
if ($start >= $end || $end >= $file_size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
fclose($file);
exit;
}
$length = $end - $start + 1;
}
if ($length != $file_size) {
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $file_size);
}
else {
header('HTTP/1.1 200 OK');
}
header('Pragma: public');
header('Expires: -1');
header('Cache-Control: public, must-revalidate, post-check=0, pre-check=0');
header('Accept-Ranges: bytes');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file_name . '"');
header('Content-Length: ' . $length);
set_time_limit(0);
/* you can modify the chunk size */
$chunk_size = 1024 * 8;
fseek($file, $start);
$left = $length;
while ($left > 0) {
$size = $chunk_size > $left ? $left : $chunk_size;
echo fread($file, $size);
ob_flush();
flush();
if (connection_status()) {
fclose($file);
exit;
}
$left -= $size;
}
fclose($file);
Других решений пока нет …