烟花 发表于 前天 11:21

虎牙不断流

转贴




四维 发表于 昨天 18:50

<?php
/**5合1
* 调用方式:http://yourdomain.com/script.php?hy=11342412
* 支持平台参数:hy(虎牙)、yy(YY)、dyu(斗鱼)、dy(抖音)、bl(B站)
虎牙周星驰,http://域名/liveplus.php?hy=11342412
抖cctv6,http://域名/liveplus.php?dy=208823316033
b站,http://域名/liveplus.php?bl=30792542
yy济公,http://域名/liveplus.php?yy=1355265814
斗鱼庆余年,http://域名/liveplus.php?dyu=7812810
*/

error_reporting(0);

function http_request($url, $method = 'GET', $headers = [], $data = null) {
    $ch = curl_init();
    curl_setopt_array($ch, [
      CURLOPT_URL => $url,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_SSL_VERIFYPEER => false,
      CURLOPT_SSL_VERIFYHOST => false,
      CURLOPT_ENCODING => '',
    ]);
    if ($method === 'POST') {
      curl_setopt($ch, CURLOPT_POST, true);
      if ($data !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    if (!empty($headers)) {
      $headerArr = [];
      foreach ($headers as $key => $value) $headerArr[] = "$key: $value";
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArr);
    }
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ['code' => $httpCode, 'body' => $response];
}

function get_headers_only($url, $headers = []) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HEADER => true,
      CURLOPT_NOBODY => true,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_TIMEOUT => 10,
      CURLOPT_SSL_VERIFYPEER => false,
      CURLOPT_SSL_VERIFYHOST => false,
    ]);
    if (!empty($headers)) {
      $headerArr = [];
      foreach ($headers as $k => $v) $headerArr[] = "$k: $v";
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArr);
    }
    $response = curl_exec($ch);
    $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    $headersStr = substr($response, 0, $headerSize);
    curl_close($ch);
    $headersArr = [];
    $lines = explode("\r\n", $headersStr);
    foreach ($lines as $line) {
      if (strpos($line, ':') !== false) {
            list($key, $value) = explode(':', $line, 2);
            $key = strtolower(trim($key));
            $value = trim($value);
            if (isset($headersArr[$key])) {
                if (!is_array($headersArr[$key])) $headersArr[$key] = [$headersArr[$key]];
                $headersArr[$key][] = $value;
            } else {
                $headersArr[$key] = $value;
            }
      }
    }
    return $headersArr;
}

function cache_get($key) {
    $file = sys_get_temp_dir() . '/' . md5($key) . '.cache';
    if (file_exists($file) && (time() - filemtime($file) < 7 * 24 * 3600)) return file_get_contents($file);
    return null;
}

function cache_set($key, $value) {
    $file = sys_get_temp_dir() . '/' . md5($key) . '.cache';
    file_put_contents($file, $value);
}

const YY_CACHE_DIR = __DIR__ . '/yycache';
const YY_CACHE_TIME = 1800;
const YY_DEFAULT_ID = '34229877';
const YY_QUALITY_LEVEL = 4500;

function yy_getRealUrl($rid, $quality) {
    $cacheFile = YY_CACHE_DIR . "/room_{$rid}_{$quality}.json";
    if (file_exists($cacheFile)) {
      $data = json_decode(file_get_contents($cacheFile), true);
      if (isset($data['time'], $data['url']) && time() - $data['time'] < YY_CACHE_TIME) {
            return $data['url'];
      }
    }

    $apiUrl = "https://interface.yy.com/hls/new/get/{$rid}/{$rid}/{$quality}?source=wapyy&callback=jsonp3";
    $headers = [
      "Referer: https://wap.yy.com/",
      "User-Agent: Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.181 Mobile Safari/537.36",
    ];
    $ch = curl_init();
    curl_setopt_array($ch, [
      CURLOPT_URL => $apiUrl,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => $headers,
      CURLOPT_SSL_VERIFYPEER => false,
      CURLOPT_SSL_VERIFYHOST => false,
    ]);
    $res = curl_exec($ch);
    curl_close($ch);

    if ($res && preg_match('/jsonp3\((.*)\)/', $res, $matches)) {
      $json = json_decode($matches, true);
      if (isset($json['hls']) && !empty($json['hls'])) {
            $realUrl = $json['hls'];
            if (!is_dir(YY_CACHE_DIR)) mkdir(YY_CACHE_DIR, 0755, true);
            file_put_contents($cacheFile, json_encode(['time' => time(), 'url' => $realUrl]));
            return $realUrl;
      }
    }
    return null;
}

function yy_serveM3u8Direct($url) {
    $ch = curl_init();
    curl_setopt_array($ch, [
      CURLOPT_URL => $url,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_SSL_VERIFYPEER => false,
      CURLOPT_SSL_VERIFYHOST => false,
      CURLOPT_HTTPHEADER => [
            "Referer: https://wap.yy.com/",
            "User-Agent: Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36"
      ]
    ]);
    $m3u8Content = curl_exec($ch);
    curl_close($ch);

    if (!$m3u8Content) exit;
    $baseUrl = dirname($url) . '/';
    $lines = explode("\n", $m3u8Content);
    header("Content-Type: application/vnd.apple.mpegurl");
    header("Access-Control-Allow-Origin: *");
    header("Cache-Control: no-cache");
    header("Content-Disposition: inline");
    foreach ($lines as $line) {
      $line = trim($line);
      if (empty($line)) continue;
      if ($line === '#') {
            echo $line . "\n";
      } else {
            if (strpos($line, 'http') !== 0) {
                echo $baseUrl . $line . "\n";
            } else {
                echo $line . "\n";
            }
      }
    }
}

$handlers = [
    'hy' => function($roomId) {
      $roomId = $roomId ?: '11342412';
      $res = http_request("https://mp.huya.com/cache.php?m=Live&do=profileRoom&roomid={$roomId}", 'GET');
      if ($res['code'] !== 200) return [];
      $data = json_decode($res['body'], true);
      if (!$data || $data['data']['realLiveStatus'] === 'OFF') return [];

      $uid = $data['data']['profileInfo']['uid'];
      $streamName = $data['data']['stream']['baseSteamInfoList']['sStreamName'];
      $multiLine = $data['data']['stream']['flv']['multiLine'];
      $baseUrl = explode('?', $multiLine['url']);

      $seq = (int)$uid + (int)(microtime(true) * 1000);
      $wsTime = dechex(time() + 21600);
      $wsSecret = md5("DWq8BcJ3h6DJt6TY_{$uid}_{$streamName}_" . md5("{$seq}|tars_wap|") . "_{$wsTime}");

      return ['url' => "{$baseUrl}?wsSecret={$wsSecret}&wsTime={$wsTime}&ctype=tars_wap&seqid={$seq}&uid={$uid}&fs=bgct&ver=1"];
    },
    'dyu' => function($roomId) {
      $roomId = $roomId ?: '7812810';
      $did = md5(mt_rand() . microtime(true));
      $k = http_request("https://www.douyu.com/wgapi/livenc/liveweb/websec/getEncryption?did={$did}", 'GET', ['User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Referer' => 'https://www.douyu.com/']);
      if ($k['code'] !== 200) return [];
      $encData = json_decode($k['body'], true)['data'] ?? null;
      if (!$encData) return [];

      $randStr = $encData['rand_str'];
      for ($i = 0; $i < $encData['enc_time']; $i++) $randStr = md5($randStr . $encData['key']);
      $ts = time();
      $auth = md5($randStr . $encData['key'] . $roomId . $ts);
      $postData = "enc_data={$encData['enc_data']}&tt={$ts}&did={$did}&auth={$auth}";

      $res = http_request("https://www.douyu.com/lapi/live/getH5PlayV1/{$roomId}", 'POST', ['Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Referer' => "https://www.douyu.com/{$roomId}"], $postData);
      if ($res['code'] !== 200) return [];
      $playData = json_decode($res['body'], true)['data'] ?? null;
      if (!$playData) return [];
      $playUrl = isset($playData['hls_url']) ? $playData['hls_url'] : ($playData['rtmp_url'] . '/' . $playData['rtmp_live']);
      return ['url' => $playUrl];
    },
    'dy' => function($roomId) {
      $rid = trim($roomId) ?: '37917621268';
      $url = "https://live.douyin.com/{$rid}";
      $ttwid = cache_get('douyin_ttwid');
      if (!$ttwid) {
            $responseHeaders = get_headers_only($url, ['User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36']);
            if (isset($responseHeaders['set-cookie'])) {
                $setCookie = $responseHeaders['set-cookie'];
                if (is_array($setCookie)) $setCookie = implode('; ', $setCookie);
                if (preg_match('/ttwid=([^;]+)/', $setCookie, $matches)) {
                  $ttwid = 'ttwid=' . $matches;
                  cache_set('douyin_ttwid', $ttwid);
                } else return [];
            } else return [];
      }

      $headers = ['Cookie' => $ttwid, 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Referer' => 'https://live.douyin.com/'];
      $res = http_request($url, 'GET', $headers);
      if ($res['code'] !== 200) return [];
      $body = $res['body'];

      $flvUrl = null;
      if (preg_match('/\\\"origin\\\":\\{\\\"main\\\":\\{\\\"flv\\\":(.*)tsl/', $body, $flvMatches)) $flvUrl = $flvMatches ?? null;
      if (!$flvUrl && preg_match('/(https?[^"\\\\]*?\.flv[^"\\\\]*)/', $body, $matches)) $flvUrl = $matches;

      if ($flvUrl) {
            $segments = explode(',\"hls', $flvUrl);
            $firstSegment = $segments;
            $cleanedUrl = trim($firstSegment, '\"');
            $finalUrl = str_replace(['\u0026', '\\/'], ['&', '/'], $cleanedUrl);
            return ['url' => $finalUrl];
      }
      return [];
    },
    'bl' => function($roomId) {
      $roomId = $roomId ?: '4053897';
      $res = http_request("https://api.live.bilibili.com/room/v1/Room/playUrl?quality=4&cid={$roomId}", 'GET');
      if ($res['code'] !== 200) return [];
      $data = json_decode($res['body'], true);
      if (isset($data['data']['durl']['url'])) return ['url' => $data['data']['durl']['url']];
      return [];
    }
];

$supported = ['hy', 'yy', 'dyu', 'dy', 'bl'];
foreach ($supported as $param) {
    if (isset($_GET[$param]) && !empty($_GET[$param])) {
      if ($param === 'yy') {
            $rid = preg_replace('/[^0-9]/', '', $_GET['yy']);
            if (empty($rid)) $rid = YY_DEFAULT_ID;
            $quality = isset($_GET['quality']) ? (int)$_GET['quality'] : YY_QUALITY_LEVEL;
            $quality = in_array($quality, ) ? $quality : YY_QUALITY_LEVEL;
            $playUrl = yy_getRealUrl($rid, $quality);
            if (!$playUrl) exit;
            yy_serveM3u8Direct($playUrl);
            exit;
      } else {
            $result = $handlers[$param]($_GET[$param]);
            if (!empty($result) && isset($result['url'])) {
                header('Location: ' . $result['url']);
                exit;
            }
            exit;
      }
    }
}

四维 发表于 昨天 14:54

好象只支持国内布置。

jitazhishen 发表于 4 小时前

四维 发表于 2026-4-1 18:50


不错,感谢分享
页: [1]
查看完整版本: 虎牙不断流