Files
pilates-platform/stream_video.php
Francesco Picone 59c9b1f5be fix ffmpeg
2025-12-09 16:58:11 +01:00

151 lines
3.6 KiB
PHP

<?php
/**
* Stream Video Protetto
*
* Serve i video in modo protetto, verificando i permessi dell'utente
* e impedendo il download diretto
*/
require_once 'includes/config.php';
require_once 'includes/functions.php';
session_start();
// Ottieni parametri
$lesson_id = isset($_GET['lesson_id']) && is_numeric($_GET['lesson_id']) ? (int)$_GET['lesson_id'] : 0;
if (!$lesson_id) {
http_response_code(404);
exit('Video non trovato');
}
// Ottieni lezione
$lesson = get_lesson_by_id($lesson_id);
if (!$lesson || !$lesson['is_active']) {
http_response_code(404);
exit('Video non trovato');
}
// Verifica permessi
$can_view = false;
// Se è demo, tutti possono vedere
if ($lesson['is_demo']) {
$can_view = true;
} elseif (is_logged_in()) {
// Verifica se l'utente possiede la lezione
$can_view = user_owns_lesson($_SESSION['user_id'], $lesson_id);
}
if (!$can_view) {
http_response_code(403);
exit('Non hai i permessi per visualizzare questo video');
}
// Verifica che sia un video locale
if (empty($lesson['video_url']) || $lesson['video_platform'] !== 'local') {
http_response_code(404);
exit('Video non disponibile');
}
// Costruisci il percorso del file
$video_path = ltrim($lesson['video_url'], '/');
$file = __DIR__ . '/' . $video_path;
if (!file_exists($file)) {
http_response_code(404);
exit('File video non trovato');
}
// Ottieni informazioni sul file
$file_size = filesize($file);
$file_name = basename($file);
$extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
// Determina il tipo MIME
$mime_types = [
'mp4' => 'video/mp4',
'webm' => 'video/webm',
'ogg' => 'video/ogg',
'mov' => 'video/quicktime'
];
$mime_type = $mime_types[$extension] ?? 'video/mp4';
// Gestisci Range Request per supportare seek nel video
$start = 0;
$end = $file_size - 1;
$length = $file_size;
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
if (preg_match('/bytes=(\d+)-(\d*)/', $range, $matches)) {
$start = intval($matches[1]);
if (!empty($matches[2])) {
$end = intval($matches[2]);
}
$length = $end - $start + 1;
http_response_code(206); // Partial Content
header("Content-Range: bytes $start-$end/$file_size");
} else {
http_response_code(200);
}
} else {
http_response_code(200);
}
// Pulisci output buffer per evitare corruzione
if (ob_get_level()) {
ob_end_clean();
}
// Invia header
header("Content-Type: $mime_type");
header("Accept-Ranges: bytes");
header("Content-Length: $length");
// Header per impedire il download
header("Content-Disposition: inline; filename=\"video.{$extension}\"");
header("X-Content-Type-Options: nosniff");
// Header di cache per migliorare le performance
header("Cache-Control: public, max-age=3600");
header("Pragma: public");
// Disabilita compressione per lo streaming
header("Content-Encoding: none");
// Apri e leggi il file
$fp = fopen($file, 'rb');
if ($fp === false) {
http_response_code(500);
exit('Impossibile aprire il file video');
}
fseek($fp, $start);
// Buffer più grande per migliore performance
$buffer = 1024 * 256; // 256KB buffer
$bytes_sent = 0;
while (!feof($fp) && ($bytes_sent < $length) && connection_status() == 0) {
$bytes_to_read = min($buffer, $length - $bytes_sent);
$data = fread($fp, $bytes_to_read);
if ($data === false) {
break;
}
echo $data;
$bytes_sent += strlen($data);
// Forza l'invio dei dati al browser
if (ob_get_level() > 0) {
ob_flush();
}
flush();
}
fclose($fp);
exit;