Files
MoYuBan/api/videos.php
2025-11-18 14:18:28 +08:00

134 lines
5.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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);