$ok, 'message' => $message, 'path' => $path], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } // 递归删除目录及其内容(用于清理旧视频) function rrmdir($dir) { if (!is_dir($dir)) return; $items = @scandir($dir); if ($items === false) return; foreach ($items as $item) { if ($item === '.' || $item === '..') continue; $full = $dir . DIRECTORY_SEPARATOR . $item; if (is_dir($full)) { rrmdir($full); } else { @unlink($full); } } @rmdir($dir); } // 读取JSON输入 $raw = file_get_contents('php://input'); $data = json_decode($raw, true); $url = $data['url'] ?? ''; $title = $data['title'] ?? ''; if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) { respond(false, 'URL无效'); } // 只允许 http/https $scheme = parse_url($url, PHP_URL_SCHEME); if (!in_array(strtolower($scheme), ['http','https'])) { respond(false, '仅支持http/https视频地址'); } $videosRoot = __DIR__ . '/../videos'; if (!is_dir($videosRoot)) { @mkdir($videosRoot, 0777, true); } $today = (new DateTime('now'))->format('Y-m-d'); $targetDir = $videosRoot . '/' . $today; if (!is_dir($targetDir)) { @mkdir($targetDir, 0777, true); } // 生成文件名 $basename = basename(parse_url($url, PHP_URL_PATH) ?: 'video_' . time() . '.mp4'); if (strpos($basename, '.') === false) { $basename .= '.mp4'; } $safeName = preg_replace('/[^\w\.-]+/u', '_', $basename); $targetPath = $targetDir . '/' . $safeName; // 如果文件已存在则跳过下载 $skipDownload = file_exists($targetPath); $msg = '保存成功'; if ($skipDownload) { $msg = '文件已存在,跳过下载'; } else { // 下载保存 try { $read = @fopen($url, 'rb'); if (!$read) { respond(false, '无法读取远程视频'); } $write = @fopen($targetPath, 'wb'); if (!$write) { respond(false, '无法写入文件'); } stream_copy_to_stream($read, $write); fclose($read); fclose($write); } catch (Throwable $e) { respond(false, '保存失败: ' . $e->getMessage()); } } $bytes = @filesize($targetPath) ?: 0; try { $statsRoot = __DIR__ . '/../stats'; if (!is_dir($statsRoot)) { @mkdir($statsRoot, 0777, true); } $dailyPath = $statsRoot . '/daily.json'; $today = (new DateTime('now'))->format('Y-m-d'); $daily = []; if (file_exists($dailyPath)) { $rawDaily = @file_get_contents($dailyPath); $decoded = json_decode($rawDaily, true); if (is_array($decoded)) { $daily = $decoded; } } if (!isset($daily[$today]) || !is_array($daily[$today])) { $daily[$today] = ['visits' => 0, 'video_plays' => 0, 'picture_shows' => 0, 'uv' => 0, 'bandwidth_in' => 0, 'bandwidth_out' => 0]; } $daily[$today]['bandwidth_out'] += (int)$bytes; @file_put_contents($dailyPath, json_encode($daily, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); } catch (Throwable $e) {} // 恢复清理逻辑:仅保留最近两天的视频目录,删除更早的目录 try { $dirs = @scandir($videosRoot); if (is_array($dirs)) { // 仅筛选形如 YYYY-MM-DD 的目录 $dateDirs = []; foreach ($dirs as $d) { if ($d === '.' || $d === '..') continue; $path = $videosRoot . DIRECTORY_SEPARATOR . $d; if (is_dir($path) && preg_match('/^\d{4}-\d{2}-\d{2}$/', $d)) { $dateDirs[] = $d; } } // 按日期升序排序 sort($dateDirs); // 保留最近两天(末尾两项),其它全部删除 if (count($dateDirs) > 2) { $toDelete = array_slice($dateDirs, 0, count($dateDirs) - 2); foreach ($toDelete as $del) { rrmdir($videosRoot . DIRECTORY_SEPARATOR . $del); } } } } catch (Throwable $e) { // 清理失败不影响主流程 } respond(true, $msg, str_replace($_SERVER['DOCUMENT_ROOT'], '', $targetPath));