<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

$videoId = isset($_GET['id']) ? trim($_GET['id']) : '';
if (empty($videoId)) {
    http_response_code(400);
    echo '缺少视频ID';
    exit;
}

require_once 'config.php';
global $pdo;

$stmt = $pdo->prepare("SELECT storage_path, file_name, file_size, format FROM video_assets WHERE video_id = ?");
$stmt->execute([$videoId]);
$asset = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$asset) {
    http_response_code(404);
    echo '视频不存在';
    exit;
}

// 防止路径遍历攻击
$storagePath = $asset['storage_path'];
$fileName = $asset['file_name'];
if (strpos($storagePath, '..') !== false || strpos($fileName, '..') !== false || strpos($fileName, '/') !== false || strpos($fileName, '\\') !== false) {
    http_response_code(403);
    echo '非法请求';
    exit;
}
$filePath = __DIR__ . '/' . $storagePath . $fileName;

if (!file_exists($filePath)) {
    http_response_code(404);
    echo '文件不存在';
    exit;
}

$fileSize = filesize($filePath);
$mime = 'video/mp4';
if ($asset['format'] === 'WEBM') {
    $mime = 'video/webm';
} elseif ($asset['format'] === 'MOV') {
    $mime = 'video/quicktime';
}

$offset = 0;
$length = $fileSize;

if (isset($_SERVER['HTTP_RANGE'])) {
    $range = $_SERVER['HTTP_RANGE'];
    preg_match('/bytes=(\d+)-(\d+)?/', $range, $matches);
    
    $offset = intval($matches[1]);
    if (isset($matches[2])) {
        $length = intval($matches[2]) - $offset + 1;
    } else {
        $length = $fileSize - $offset;
    }
    
    header('HTTP/1.1 206 Partial Content');
    header('Content-Range: bytes ' . $offset . '-' . ($offset + $length - 1) . '/' . $fileSize);
} else {
    header('HTTP/1.1 200 OK');
}

header('Content-Type: ' . $mime);
header('Content-Length: ' . $length);
header('Accept-Ranges: bytes');
header('Connection: keep-alive');
header('Cache-Control: public, max-age=31536000');

$handle = fopen($filePath, 'rb');
fseek($handle, $offset);

$chunkSize = 1024 * 1024;
while ($length > 0) {
    $read = min($chunkSize, $length);
    $buffer = fread($handle, $read);
    if ($buffer === false) break;
    echo $buffer;
    flush();
    $length -= $read;
}

fclose($handle);
?>
