初始化版本

This commit is contained in:
LL
2025-11-18 14:18:28 +08:00
commit 3c348195b7
23 changed files with 2837 additions and 0 deletions

133
api/videos.php Normal file
View File

@@ -0,0 +1,133 @@
<?php
// 代理获取视频地址的接口:从多个来源“随机/顺序”获取 1~N 条视频地址,并返回统一格式
header('Content-Type: application/json; charset=utf-8');
// 指定来源功能已取消:统一按优先级尝试全部来源;如需随机请使用 ?random=1
// 支持的远程来源(按优先级尝试,默认启用全部并按优先级依次尝试)
$endpoints = [
'https://api.kuleu.com/api/MP4_xiaojiejie?type=json', // 新增来源纯视频URL或JSON
'https://v2.xxapi.cn/api/meinv', // 新来源JSON: {code,data}
'https://api.iyuns.com/api/meinv', // 旧来源JSON: {code,data}
'https://api.kuleu.com/api/xjj?type=json', // 新增来源JSON: {code,data}
'https://api.dwo.cc/api/ksvideo?type=json', // 新增来源JSON: {code,data}
'https://v2.api-m.com/api/meinv?type=json', // 新增来源JSON: {code,data}
'https://api.mhimg.cn/api/Sj_girls_video?type=json', // 新增来源JSON: {code,data}
];
// 随机获取:默认开启;如需关闭可用 ?random=0
$randomParam = $_GET['random'] ?? null;
$random = !isset($randomParam) ? true : (intval($randomParam) === 1);
$count = intval($_GET['count'] ?? 1);
if ($count < 1) $count = 1; if ($count > 5) $count = 5; // 限制最多5条
// 是否包含本地视频的开关
$includeLocal = intval($_GET['include_local'] ?? 0) === 1;
// 本地视频条数上限(当开启包含本地时生效,默认与远程条数相同)
$localCount = intval($_GET['local_count'] ?? $count);
if ($localCount < 0) $localCount = 0; if ($localCount > 10) $localCount = 10; // 限制一次最多10条本地视频
function fetch_remote_url($endpoint) {
// 使用 curl 更稳妥地请求第三方接口
$ch = curl_init($endpoint);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 8,
CURLOPT_TIMEOUT => 12,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_USERAGENT => 'VideoFetcher/1.0',
]);
$body = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($err) { return null; }
$json = json_decode($body, true);
$candidate = '';
if (is_array($json)) {
// 某些接口包含 code 字段,若存在则需为 200
if (array_key_exists('code', $json) && intval($json['code']) !== 200) {
return null;
}
// 兼容不同字段名mp4_video、data、url、mp4、video
foreach (['mp4_video','data','url','mp4','video','pic'] as $key) {
if (!empty($json[$key]) && is_string($json[$key])) { $candidate = $json[$key]; break; }
}
} else {
// 非JSON可能直接返回URL
$candidate = trim((string)$body);
}
// 清理反引号和空白
$candidate = preg_replace('/[`\s]/', '', (string)$candidate);
// 简单校验:必须是 http/https且 URL 中包含常见视频扩展(允许出现在路径或查询字符串中)
if (!$candidate || !preg_match('/^https?:\/\//i', $candidate)) { return null; }
if (!preg_match('/\.(mp4|webm|mov)(?![A-Za-z])/i', $candidate)) { return null; }
return $candidate;
}
// 远程接口视频列表
$remote = [];
for ($i = 0; $i < $count; $i++) {
$u = null;
// 依次尝试多个来源,取第一个成功的(随机模式下,每次尝试顺序打乱)
$epOrder = $endpoints;
if ($random && count($epOrder) > 1) { shuffle($epOrder); }
foreach ($epOrder as $ep) {
$u = fetch_remote_url($ep);
if ($u) { break; }
}
if ($u) {
$remote[] = [
'url' => $u,
'title' => '接口视频 ' . ($i + 1),
];
}
}
// 随机模式下,对远程列表打乱顺序
if ($random && count($remote) > 1) { shuffle($remote); }
// 同时把本地已保存的视频加入列表(可选)
$videosRoot = __DIR__ . '/../videos';
$local = [];
// 构建本地视频列表,用于开关合并或远程失败时的回退
if (is_dir($videosRoot)) {
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($videosRoot));
foreach ($rii as $file) {
if ($file->isFile()) {
$ext = strtolower(pathinfo($file->getFilename(), PATHINFO_EXTENSION));
if (in_array($ext, ['mp4','webm','mov'])) {
// 构造相对URL供前端播放
$rel = str_replace('\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $file->getPathname()));
$local[] = [
'url' => $rel,
'title' => '本地:' . $file->getFilename()
];
}
}
}
// 本地视频顺序随机并裁剪到指定数量
if (count($local) > 1) { shuffle($local); }
if ($localCount > 0 && count($local) > $localCount) {
$local = array_slice($local, 0, $localCount);
}
}
// 合并/回退策略:
// 1) 远程成功:
// - 如果开启本地,则远程+本地合并并整体随机
// - 如果未开启本地,则仅远程
// 2) 远程失败:
// - 若本地有内容,则仅返回本地随机列表(忽略开关)
$list = [];
if (!empty($remote)) {
$list = $includeLocal ? array_merge($remote, $local) : $remote;
if (count($list) > 1 && ($includeLocal || $random)) { shuffle($list); }
} else if (!empty($local)) {
$list = $local; // 远程不可用时,回退到全部本地随机
}
// 如果仍为空,提供一个后备示例
if (empty($list)) {
$list[] = [
'url' => 'https://sample-videos.com/video321/mp4/720/big_buck_bunny_720p_1mb.mp4',
'title' => '示例视频'
];
}
echo json_encode(['list' => $list], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);