二次优化版<?php
// 频道映射表 - 将友好名称映射到抖音直播间ID
$channelMap = [
// CCTV频道
'cctv1' => '456815963645', // 央视一套CCTV-1
'cctv6' => '208823316033', // 央影传媒CCTV-6
'cctv13' => '870887192950', // 央视网CCTV-13 (主)
'cctv13-2' => '127453393722', // 央视网快看CCTV-13
'cctv13-3' => '50828500437', // 央视频CCTV-13
'cctv13-4' => '547977714661', // 小央视频CCTV-13
// 地方台
'hnjs' => '301788940262', // 湖南经视
'sdzy' => '385925606236', // 山东电视综艺频道
];
// 频道中文名称映射
$channelNames = [
'cctv1' => '央视一套CCTV-1',
'cctv6' => '央影传媒CCTV-6',
'cctv13' => '央视网CCTV-13 (主)',
'cctv13-2' => '央视网快看CCTV-13',
'cctv13-3' => '央视频CCTV-13',
'cctv13-4' => '小央视频CCTV-13',
'hnjs' => '湖南经视',
'sdzy' => '山东电视综艺频道',
];
// 获取频道ID参数
$channelId = isset($_GET['id']) ? $_GET['id'] : '';
// 检查是否为空
if (empty($channelId)) {
http_response_code(400);
echo "错误: 缺少频道ID参数\n\n";
echo "支持的频道:\n";
foreach ($channelMap as $name => $id) {
echo "- {$name}: http://localhost/Public/webplayer/php/douyintv/douyinlive.php?id={$name}\n";
}
exit;
}
// 如果是友好名称,转换为数字ID;如果已经是数字ID,直接使用
if (isset($channelMap[$channelId])) {
$roomId = $channelMap[$channelId];
$channelName = $channelId;
} elseif (is_numeric($channelId)) {
$roomId = $channelId;
$channelName = array_search($channelId, $channelMap) ?: 'unknown';
} else {
http_response_code(404);
echo "错误: 不支持的频道 '{$channelId}'\n\n";
echo "支持的频道:\n";
foreach ($channelMap as $name => $id) {
echo "- {$name}: http://localhost/Public/webplayer/php/douyintv/douyinlive.php?id={$name}\n";
}
exit;
}
$apiUrl = 'https://live.douyin.com/webcast/room/web/enter/?aid=6383&device_platform=web&browser_language=zh-CN&browser_platform=iPad&browser_name=Safari&browser_version=17.6&web_rid=' . $roomId;
// 使用cURL替代file_get_contents,更稳定
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (iPad; CPU OS 17_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Mobile/15E148 Safari/604.1');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Cookie: ttwid=1%7CYqdH7G5MetcLz-SYn5w09SR81BSavm6lW81orliZUbA%7C1719753328%7Ccb83acfa23ce88b920c26fef1746820e6a701528adfe7c48847cfb5925eb1a0f',
'Accept: application/json, text/plain, */*',
'Accept-Language: zh-CN,zh;q=0.9',
'Referer: https://live.douyin.com/'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
// 错误处理
if ($response === false || !empty($error)) {
http_response_code(500);
echo "🔌 网络连接错误\n\n";
echo "无法连接到抖音直播服务器\n";
echo "错误详情: " . $error . "\n\n";
echo "请检查:\n";
echo "1. 网络连接是否正常\n";
echo "2. 防火墙设置\n";
echo "3. 稍后重试";
exit;
}
if ($httpCode !== 200) {
http_response_code($httpCode);
echo "🚫 服务器响应错误\n\n";
echo "HTTP状态码: " . $httpCode . "\n";
if ($httpCode == 403) {
echo "可能原因: 访问被拒绝,请稍后重试";
} elseif ($httpCode == 404) {
echo "可能原因: 直播间不存在";
} elseif ($httpCode >= 500) {
echo "可能原因: 抖音服务器暂时不可用";
} else {
echo "请稍后重试或检查网络连接";
}
exit;
}
$json = json_decode($response, true);
// 检查JSON解析是否成功
if ($json === null) {
http_response_code(500);
echo "📄 数据解析错误\n\n";
echo "服务器返回的数据格式不正确\n";
echo "这可能是临时问题,请稍后重试";
exit;
}
// 检查响应数据结构
if (!isset($json['data']['data'][0]['stream_url']['live_core_sdk_data']['pull_data']['stream_data'])) {
// 检查是否是直播间不存在或离线
if (!isset($json['data']['data'][0])) {
http_response_code(404);
echo "❌ 直播间不存在或已关闭\n\n";
echo "频道: " . ($channelName !== 'unknown' ? $channelNames[$channelName] : $channelName) . "\n";
echo "房间号: " . $roomId . "\n\n";
echo "请检查:\n";
echo "1. 直播间是否正在直播\n";
echo "2. 房间号是否正确\n";
echo "3. 访问 https://live.douyin.com/" . $roomId . " 确认直播状态";
} else {
http_response_code(503);
echo "⏸️ 当前暂未播放\n\n";
echo "频道: " . ($channelName !== 'unknown' ? $channelNames[$channelName] : $channelName) . "\n";
echo "房间号: " . $roomId . "\n\n";
echo "该直播间存在但当前没有直播内容,请稍后再试。\n";
echo "或访问 https://live.douyin.com/" . $roomId . " 查看直播状态。";
}
exit;
}
$stream_data_json = $json['data']['data'][0]['stream_url']['live_core_sdk_data']['pull_data']['stream_data'];
$stream_data = json_decode($stream_data_json, true);
// 检查stream_data解析是否成功
if ($stream_data === null) {
http_response_code(500);
echo "📊 流数据解析失败\n\n";
echo "频道: " . (isset($channelNames[$channelName]) ? $channelNames[$channelName] : $channelName) . "\n";
echo "无法解析直播流信息,请稍后重试";
exit;
}
// 检查HLS URL是否存在
if (!isset($stream_data['data']['origin']['main']['hls'])) {
http_response_code(404);
echo "📺 直播流地址不可用\n\n";
echo "频道: " . (isset($channelNames[$channelName]) ? $channelNames[$channelName] : $channelName) . "\n";
echo "房间号: " . $roomId . "\n\n";
echo "可能原因:\n";
echo "1. 直播刚结束或即将开始\n";
echo "2. 直播间设置了权限限制\n";
echo "3. 网络问题导致流信息获取失败\n\n";
echo "建议访问 https://live.douyin.com/" . $roomId . " 确认直播状态";
exit;
}
$hls_url = $stream_data['data']['origin']['main']['hls'];
//$flv_url = $stream_data['data']['origin']['main']['flv'];
// 验证URL格式
if (empty($hls_url) || !filter_var($hls_url, FILTER_VALIDATE_URL)) {
http_response_code(500);
echo "🔗 直播流地址格式错误\n\n";
echo "频道: " . (isset($channelNames[$channelName]) ? $channelNames[$channelName] : $channelName) . "\n";
echo "获取到的流地址格式不正确,这可能是临时问题\n";
echo "请稍后重试或联系管理员";
exit;
}
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
header('Location: ' . $hls_url);
XX.php?id=cctv1 |