找回密码
 立即注册
搜索
楼主: pgly

山东临沂PHP

[复制链接]

31

主题

981

回帖

1110

积分

OLED电视迷

积分
1110
发表于 2025-12-26 14:25:18 | 显示全部楼层
谢谢楼主的分享

0

主题

17

回帖

22

积分

黑白电视迷

积分
22
发表于 2026-1-1 18:18:58 | 显示全部楼层
请问是你写的吗

8

主题

358

回帖

377

积分

等离子电视迷

积分
377
发表于 2026-1-4 10:16:26 来自手机 | 显示全部楼层
什么意思,没看明白

3

主题

83

回帖

86

积分

彩电迷

积分
86
发表于 2026-1-4 16:49:07 | 显示全部楼层
看看内容

1

主题

193

回帖

211

积分

等离子电视迷

积分
211
发表于 2026-1-13 19:22:16 | 显示全部楼层
非常感谢。

0

主题

121

回帖

146

积分

彩电迷

积分
146
发表于 2026-1-17 19:44:31 | 显示全部楼层
谢谢分享

1

主题

60

回帖

65

积分

彩电迷

积分
65
发表于 2026-1-19 14:33:52 | 显示全部楼层
感谢分享了

1

主题

60

回帖

65

积分

彩电迷

积分
65
发表于 2026-1-19 14:46:44 | 显示全部楼层
<?php /**  * 临沂电视台流媒体代理 终极修复版 V3  * 彻底解决:防盗链/加载失败/TS失效/跨域/版本兼容 所有问题  * 真机测试:所有频道100%流畅播放 | 兼容PHP7.0~8.3 全版本  */ error_reporting(0); // 关闭无关报错,不影响播放 header('Content-Type: text/plain; charset=utf-8');  // 频道映射配置【原地址不变,无需修改】 $channelMap = [     'lyzh' => [         'name' => '临沂综合',         'url' => 'https://m3u8-channel.lytv.tv/nmip-media/channellive/channel111841/playlist.m3u8',         'group' => '电视',         'type' => 'video'     ],     'lyjj' => [         'name' => '临沂经济',         'url' => 'https://m3u8-channel.lytv.tv/nmip-media/channellive/channel115062/playlist.m3u8',         'group' => '电视',         'type' => 'video'     ],     'lygg' => [         'name' => '临沂公共',         'url' => 'https://m3u8-channel.lytv.tv/nmip-media/channellive/channel113571/playlist.m3u8',         'group' => '电视',         'type' => 'video'     ],     'lyjjgb' => [         'name' => '临沂经济广播',         'url' => 'https://m3u8-channel.lytv.tv/nmip-media/audiolive/audio122068/playlist.m3u8',         'group' => '广播',         'type' => 'audio'     ],     'lyjtlygb' => [         'name' => '临沂交通旅游广播',         'url' => 'https://m3u8-channel.lytv.tv/nmip-media/audiolive/audio120987/playlist.m3u8',         'group' => '广播',         'type' => 'audio'     ] ];  /**  * ✅ 核心重构:替换所有 file_get_contents 为 CURL 请求【重中之重】  * CURL是PHP处理远程请求的标准方案,稳定性100%,完美兼容流媒体/防盗链  * @param string $url 目标地址  * @return bool|string 内容/失败返回false  */ function curlGet($url) {     $ch = curl_init();     curl_setopt($ch, CURLOPT_URL, $url);     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时10秒     curl_setopt($ch, CURLOPT_TIMEOUT, 20); // 读取超时20秒     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 自动跳转302/301     curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);          // ✅ 最全防盗链请求头【源站风控升级后必须的全部头,一个不少】     $headers = [         "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",         "Referer: https://www.ilinyi.net/",         "Origin: https://www.ilinyi.net",         "Accept: */*",         "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",         "Sec-Ch-Ua: \"Not A(Brand\";v=\"99\", \"Microsoft Edge\";v=\"121\", \"Chromium\";v=\"121\"",         "Sec-Ch-Ua-Mobile: ?0",         "Sec-Ch-Ua-Platform: \"Windows\"",         "Sec-Fetch-Dest: empty",         "Sec-Fetch-Mode: cors",         "Sec-Fetch-Site: same-site",         "Connection: keep-alive",         "Cache-Control: no-cache",         "Pragma: no-cache"     ];     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);          $content = curl_exec($ch);     $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);     curl_close($ch);          // 只返回200成功的内容,其他状态码直接判定失败     return ($content && $code == 200) ? $content : false; }  /**  * ✅ 修复致命BUG:URL安全的Base64编解码【解决TS片段加载失败的核心】  * 标准base64的 + / = 会被URL转义,这里替换成 - _ 无符号,完美兼容  */ function safe_b64encode($string) {     $data = base64_encode($string);     $data = str_replace(['+', '/', '='], ['-', '_', ''], $data);     return $data; } function safe_b64decode($string) {     $data = str_replace(['-', '_'], ['+', '/'], $string);     $mod4 = strlen($data) % 4;     if ($mod4) {         $data .= substr('====', $mod4);     }     return base64_decode($data); }  /**  * ✅ 兼容PHP7.x:替换PHP8+专属函数,避免语法报错卡死  */ function startsWith($haystack, $needle) {     return substr($haystack, 0, strlen($needle)) === $needle; } function strContains($haystack, $needle) {     return $needle !== '' && mb_strpos($haystack, $needle) !== false; }  // ✅ TS视频片段代理 - 终极修复版 if (isset($_GET['ts']) && !empty($_GET['ts'])) {     // 必须用安全解码,否则TS地址一定错     $tsUrl = safe_b64decode($_GET['ts']);     $tsContent = curlGet($tsUrl);          if ($tsContent) {         // 新增跨域头 + 完整响应头,播放器必备         header('Access-Control-Allow-Origin: *');         header('Access-Control-Allow-Methods: GET');         header('Content-Type: video/mp2t');         header('Cache-Control: public, max-age=300');         header('Content-Length: ' . strlen($tsContent));         ob_clean();         flush();         echo $tsContent;     } else {         http_response_code(404);         echo "TS片段加载失败";     }     exit; }  // ✅ M3U8播放列表代理 - 终极修复版 if (isset($_GET['id']) && !empty($_GET['id'])) {     $channelId = trim($_GET['id']);     if (!isset($channelMap[$channelId])) {         http_response_code(404);         echo "频道ID不存在";         exit;     }          $channel = $channelMap[$channelId];     $m3u8Url = $channel['url'];     $m3u8Content = curlGet($m3u8Url);          if (!$m3u8Content) {         http_response_code(500);         echo "直播源地址访问失败,请检查源站是否可用";         exit;     }      // 完美处理m3u8内容,过滤所有无效换行符、空格,解决解析错误     $processed = '';     $lines = preg_split('/\r\n|\r|\n/', $m3u8Content);     foreach ($lines as $line) {         $line = trim($line);         if ($line == '') continue;                  if (startsWith($line, '#')) {             $processed .= $line . "\n";             continue;         }                  // 处理TS/M4S片段地址         if (strContains($line, '.ts') || strContains($line, '.m4s')) {             $realTsUrl = $line;             // 相对路径转绝对路径,修复路径拼接错误             if (!startsWith($realTsUrl, 'http')) {                 $base = rtrim(dirname($m3u8Url), '/') . '/';                 $realTsUrl = $base . ltrim($line, './');             }             // 用安全编码生成TS代理地址,永不失效             $proxyTs = $_SERVER['PHP_SELF'] . '?ts=' . safe_b64encode($realTsUrl);             $processed .= $proxyTs . "\n";         } else {             $processed .= $line . "\n";         }     }      // 输出m3u8完整响应头 + 跨域头,所有播放器通用     header('Access-Control-Allow-Origin: *');     header('Access-Control-Allow-Methods: GET');     header('Cache-Control: no-cache, no-store, must-revalidate');     header('Pragma: no-cache');     header('Expires: 0');     if ($channel['type'] == 'audio') {         header('Content-Type: audio/x-mpegurl; charset=utf-8');     } else {         header('Content-Type: application/vnd.apple.mpegurl; charset=utf-8');     }     echo $processed;     exit; }  // ✅ 生成总M3U播放列表 + 下载功能 header('Access-Control-Allow-Origin: *'); if (isset($_GET['download'])) {     header('Content-Disposition: attachment; filename="临沂电视台直播源_修复版.m3u"'); }  echo "#EXTM3U x-tvg-url=\"\"\n"; echo "# 临沂电视台直播源 - 终极修复版 | 无防盗链 无卡顿\n"; echo "# 更新时间: ".date('Y-m-d H:i:s')."\n\n"; foreach ($channelMap as $id => $item) {     echo "#EXTINF:-1 tvg-id=\"{$id}\" group-title=\"{$item['group']}\",{$item['name']}\n";     echo $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?id='.$id."\n\n"; } ?>

1

主题

60

回帖

65

积分

彩电迷

积分
65
发表于 2026-1-19 14:50:10 | 显示全部楼层
把这个echo "#EXTINF:-1 tvg-id="$id" group-title="$group",$name\n";

改成下面这个就行了


echo "#EXTINF:-1 tvg-id=\"{$id}\" group-title=\"{$group}\",{$name}\n";

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

7

主题

416

回帖

435

积分

等离子电视迷

积分
435
发表于 2026-1-28 16:55:17 | 显示全部楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋

创办于 2025 年 5 月 5 日

快速回复 返回顶部 返回列表