Banner1 Banner2 Banner3 Banner4
查看: 29|回复: 0

[代码] mg2.php

[复制链接]
发表于 2026-4-18 00:52:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
版本2,上一个主题的ID是一样的。
  1. <?php

  2. $CACHE_DIR = __DIR__ . '/cache';

  3. if (!is_dir($CACHE_DIR)) {
  4.     mkdir($CACHE_DIR, 0777, true);
  5. }

  6. function md5_str($str) {
  7.     return md5($str);
  8. }

  9. function randomInt($min, $max) {
  10.     return random_int($min, $max);
  11. }

  12. function getCachePath($key) {
  13.     global $CACHE_DIR;
  14.     $filename = 'migu_cache_' . md5_str($key) . '.json';
  15.     return $CACHE_DIR . DIRECTORY_SEPARATOR . $filename;
  16. }

  17. function getMiguCache($key) {
  18.     $p = getCachePath($key);
  19.     if (!file_exists($p)) {
  20.         return ['url' => null, 'hit' => false];
  21.     }

  22.     try {
  23.         $content = file_get_contents($p);
  24.         $d = json_decode($content, true);

  25.         if (!$d) {
  26.             return ['url' => null, 'hit' => false];
  27.         }

  28.         $nowSeconds = time();
  29.         if ($nowSeconds - intval($d['time']) > intval($d['ttl'])) {
  30.             @unlink($p);
  31.             return ['url' => null, 'hit' => false];
  32.         }

  33.         return ['url' => $d['url'], 'hit' => true];
  34.     } catch (Throwable $e) {
  35.         return ['url' => null, 'hit' => false];
  36.     }
  37. }

  38. function setMiguCache($key, $url, $ttlSeconds) {
  39.     $p = getCachePath($key);
  40.     $data = [
  41.         'url' => $url,
  42.         'time' => time(),
  43.         'ttl' => $ttlSeconds
  44.     ];

  45.     try {
  46.         file_put_contents($p, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
  47.     } catch (Throwable $e) {
  48.         error_log("Cache write error: " . $e->getMessage());
  49.     }
  50. }

  51. function getSignConfig($contId) {
  52.     $appVersion = '2600033500';
  53.     $saltValue = '16d4328df21a4138859388418bd252c2';
  54.     $timestampMs = (string) round(microtime(true) * 1000);
  55.     $ver8 = substr($appVersion, 0, 8);

  56.     $md5string = md5_str($timestampMs . $contId . $ver8);
  57.     $prefix = randomInt(0, 999999);
  58.     $salt = str_pad((string)$prefix, 6, '0', STR_PAD_LEFT) . '80';

  59.     $text = $md5string . $saltValue . 'migu' . substr($salt, 0, 4);
  60.     $sign = md5_str($text);

  61.     return ['timestampMs' => $timestampMs, 'salt' => $salt, 'sign' => $sign];
  62. }

  63. function miguEncryptedUrl($rawUrl) {
  64.     $factorOfEncryption = [8, 3, 7, 6, 6];

  65.     $parsed = parse_url($rawUrl);
  66.     if ($parsed === false || !isset($parsed['query'])) {
  67.         return $rawUrl;
  68.     }

  69.     parse_str($parsed['query'], $params);

  70.     $puData = isset($params['puData']) ? (string)$params['puData'] : '';
  71.     if ($puData === '') {
  72.         return $rawUrl;
  73.     }

  74.     $ddCalcuExists = array_key_exists('ddCalcu', $params) && $params['ddCalcu'] !== '';
  75.     if (!$ddCalcuExists) {
  76.         $userid = isset($params['userid']) ? (string)$params['userid'] : 'eeeeeeeee';
  77.         $timestamp = isset($params['timestamp']) ? (string)$params['timestamp'] : 'tttttttttttttt';
  78.         $programId = isset($params['ProgramID']) ? (string)$params['ProgramID'] : 'ccccccccc';
  79.         $channelId = isset($params['Channel_ID']) ? (string)$params['Channel_ID'] : 'nnnnnnnnnnnnnnnn';

  80.         $useridChars = preg_split('//u', $userid, -1, PREG_SPLIT_NO_EMPTY);
  81.         $timestampChars = preg_split('//u', $timestamp, -1, PREG_SPLIT_NO_EMPTY);
  82.         $programIdChars = preg_split('//u', $programId, -1, PREG_SPLIT_NO_EMPTY);
  83.         $channelIdChars = preg_split('//u', $channelId, -1, PREG_SPLIT_NO_EMPTY);

  84.         $ddCalcu = '';
  85.         $puLen = strlen($puData);
  86.         $halfLen = intdiv($puLen, 2);

  87.         for ($i = 0; $i < $halfLen; $i++) {
  88.             $ddCalcu .= $puData[$puLen - 1 - $i];
  89.             $ddCalcu .= $puData[$i];

  90.             $charToEncrypt = '';
  91.             if ($i === 1) {
  92.                 $idx = $factorOfEncryption[0] - 1;
  93.                 $charToEncrypt = isset($useridChars[$idx]) ? $useridChars[$idx] : 'e';
  94.             } elseif ($i === 2) {
  95.                 $idx = $factorOfEncryption[1] - 1;
  96.                 $charToEncrypt = isset($timestampChars[$idx]) ? $timestampChars[$idx] : 't';
  97.             } elseif ($i === 3) {
  98.                 $idx = $factorOfEncryption[2] - 1;
  99.                 $charToEncrypt = isset($programIdChars[$idx]) ? $programIdChars[$idx] : 'c';
  100.             } elseif ($i === 4) {
  101.                 $idx = $factorOfEncryption[3] - 1;
  102.                 $charToEncrypt = isset($channelIdChars[$idx]) ? $channelIdChars[$idx] : 'n';
  103.             }

  104.             if ($charToEncrypt !== '') {
  105.                 $codePoint = function_exists('mb_ord') ? mb_ord($charToEncrypt, 'UTF-8') : ord($charToEncrypt);
  106.                 $encryptedVal = $codePoint ^ $factorOfEncryption[4];
  107.                 $encryptedVal %= 26;
  108.                 $encryptedVal += 97;
  109.                 $ddCalcu .= chr($encryptedVal);
  110.             }
  111.         }

  112.         if ($puLen % 2 === 1) {
  113.             $ddCalcu .= $puData[$halfLen];
  114.         }

  115.         $params['ddCalcu'] = $ddCalcu;
  116.     }

  117.     if (!isset($params['sv'])) {
  118.         $params['sv'] = '10004';
  119.     }
  120.     if (!isset($params['ct'])) {
  121.         $params['ct'] = 'android';
  122.     }

  123.     $parsed['query'] = http_build_query($params, '', '&', PHP_QUERY_RFC3986);

  124.     $url = '';
  125.     if (isset($parsed['scheme'])) $url .= $parsed['scheme'] . '://';
  126.     if (isset($parsed['user'])) {
  127.         $url .= $parsed['user'];
  128.         if (isset($parsed['pass'])) $url .= ':' . $parsed['pass'];
  129.         $url .= '@';
  130.     }
  131.     if (isset($parsed['host'])) $url .= $parsed['host'];
  132.     if (isset($parsed['port'])) $url .= ':' . $parsed['port'];
  133.     if (isset($parsed['path'])) $url .= $parsed['path'];
  134.     if (isset($parsed['query']) && $parsed['query'] !== '') $url .= '?' . $parsed['query'];
  135.     if (isset($parsed['fragment'])) $url .= '#' . $parsed['fragment'];

  136.     return $url;
  137. }

  138. function handleMiguMainRequest($id) {
  139.     $cached = getMiguCache($id);
  140.     if ($cached['hit']) {
  141.         return $cached['url'];
  142.     }

  143.     $signConfig = getSignConfig($id);
  144.     $timestampMs = $signConfig['timestampMs'];
  145.     $salt = $signConfig['salt'];
  146.     $sign = $signConfig['sign'];

  147.     $apiUrl = 'https://play.miguvideo.com/playurl/v1/play/playurl?contId=' . rawurlencode($id)
  148.         . '&dolby=true&isMultiView=true&xh265=true&os=13&ott=false&rateType=3&salt=' . rawurlencode($salt)
  149.         . '&sign=' . rawurlencode($sign)
  150.         . '&timestamp=' . rawurlencode($timestampMs)
  151.         . '&ua=oneplus-12&vr=true';

  152.     $headers = [
  153.         'Host: play.miguvideo.com',
  154.         'appId: miguvideo',
  155.         'terminalId: android',
  156.         'User-Agent: Dalvik/2.1.0+(Linux;+U;+Android+13;+oneplus-13+Build/TP1A.220624.014)',
  157.         'MG-BH: true',
  158.         'appVersionName: 6.3.35',
  159.         'appVersion: 2600033500',
  160.         'Phone-Info: oneplus-13|13',
  161.         'X-UP-CLIENT-CHANNEL-ID: 2600033500-99000-201600010010028',
  162.         'APP-VERSION-CODE: 260335005',
  163.         'Accept: */*',
  164.         'Connection: keep-alive',
  165.     ];

  166.     $ch = curl_init();
  167.     curl_setopt($ch, CURLOPT_URL, $apiUrl);
  168.     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  169.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  170.     curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  171.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  172.     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

  173.     $response = curl_exec($ch);
  174.     if ($response === false) {
  175.         error_log('API Request Error: ' . curl_error($ch));
  176.         curl_close($ch);
  177.         return null;
  178.     }
  179.     curl_close($ch);

  180.     $json = json_decode($response, true);
  181.     $rawUrl = '';
  182.     if (isset($json['body']['urlInfo']['url'])) {
  183.         $rawUrl = $json['body']['urlInfo']['url'];
  184.     }

  185.     if (!$rawUrl) {
  186.         return null;
  187.     }

  188.     $ottUrl = miguEncryptedUrl($rawUrl);
  189.     if (!$ottUrl || trim($ottUrl) === '') {
  190.         return null;
  191.     }

  192.     setMiguCache($id, $ottUrl, 1800);
  193.     return $ottUrl;
  194. }

  195. $id = isset($_GET['id']) ? $_GET['id'] : '608807420';
  196. $finalUrl = handleMiguMainRequest($id);

  197. if ($finalUrl) {
  198.     header('Location: ' . $finalUrl, true, 302);
  199.     exit;
  200. }

  201. http_response_code(500);
  202. echo 'Failed to retrieve or encrypt URL.';
复制代码




您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

论坛 Banner

相关侵权、举报、投诉及建议等,请发 E-mail:[email protected]

返回顶部