|
|
|
@ -1,22 +1,47 @@ |
|
|
|
<?php |
|
|
|
<?php |
|
|
|
|
|
|
|
date_default_timezone_set("Asia/Shanghai"); |
|
|
|
|
|
|
|
$type = empty($_GET['type']) ? "nodisplay" : trim($_GET['type']); |
|
|
|
|
|
|
|
$id = empty($_GET['id']) ? "shangdi" : trim($_GET['id']); |
|
|
|
|
|
|
|
$cdn = empty($_GET['cdn']) ? "hwcdn" : trim($_GET['cdn']); |
|
|
|
|
|
|
|
$media = empty($_GET['media']) ? "flv" : trim($_GET['media']); |
|
|
|
|
|
|
|
$roomurl = "https://m.huya.com/" . $id; |
|
|
|
|
|
|
|
|
|
|
|
$rid = empty($_GET['id']) ? "shangdi" : trim($_GET['id']); |
|
|
|
function get_content($apiurl, $flag) |
|
|
|
$cdn = empty($_GET['cdn']) ? "HW" : trim($_GET['cdn']); |
|
|
|
|
|
|
|
$cdnType = empty($_GET['type']) ? "nodisplay" : trim($_GET['type']); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function parseAntiCode($antiCode, $streamName) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
parse_str($antiCode, $qr); |
|
|
|
if ($flag == "mobile") { |
|
|
|
$t = "0"; |
|
|
|
$headers = array( |
|
|
|
$f = strval(round(microtime(true) * 100)); |
|
|
|
'Content-Type: application/x-www-form-urlencoded', |
|
|
|
$wsTime = $qr['wsTime']; |
|
|
|
'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1' |
|
|
|
$fm = base64_decode($qr['fm']); |
|
|
|
); |
|
|
|
$fm = str_replace("$0", $t, $fm); |
|
|
|
} else { |
|
|
|
$fm = str_replace("$1", $streamName, $fm); |
|
|
|
$arr = [ |
|
|
|
$fm = str_replace("$2", $f, $fm); |
|
|
|
"appId" => 5002, |
|
|
|
$fm = str_replace("$3", $wsTime, $fm); |
|
|
|
"byPass" => 3, |
|
|
|
return sprintf("wsSecret=%s&wsTime=%s&u=%s&seqid=%s&txyp=%s&fs=%s&sphdcdn=%s&sphdDC=%s&sphd=%s&u=0&t=100&ratio=0", |
|
|
|
"context" => "", |
|
|
|
md5($fm), $wsTime, $t, $f, empty($qr['txyp']) ? "" : $qr['txyp'], empty($qr['fs']) ? "" : $qr['fs'], empty($qr['sphdcdn']) ? "" : $qr['sphdcdn'], empty($qr['sphdDC']) ? "" : $qr['sphdDC'], empty($qr['sphd']) ? "" : $qr['sphd']); |
|
|
|
"version" => "2.4", |
|
|
|
|
|
|
|
"data" => new stdClass(), |
|
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
$postData = json_encode($arr); |
|
|
|
|
|
|
|
$headers = array( |
|
|
|
|
|
|
|
'Content-Type: application/json', |
|
|
|
|
|
|
|
'Content-Length: ' . strlen($postData), |
|
|
|
|
|
|
|
'upgrade-insecure-requests: 1', |
|
|
|
|
|
|
|
'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$ch = curl_init(); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $apiurl); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); |
|
|
|
|
|
|
|
if ($flag == "uid") { |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_POST, 1); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$data = curl_exec($ch); |
|
|
|
|
|
|
|
curl_close($ch); |
|
|
|
|
|
|
|
return $data; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function aes_decrypt($ciphertext, $key, $iv) |
|
|
|
function aes_decrypt($ciphertext, $key, $iv) |
|
|
|
@ -28,64 +53,92 @@ $key = "abcdefghijklmnopqrstuvwxyz123456"; |
|
|
|
$iv = "1234567890123456"; |
|
|
|
$iv = "1234567890123456"; |
|
|
|
$mediaurl = aes_decrypt("fIuPMpBI1RpRnM2JhbYHzvwCvwhHBF7Q+8k14m9h3N5ZfubHcDCEk08TnLwHoMI/SG7bxpqT6Rh+gZunSpYHf1JM/RmEC/S1SjRYWw6rwc3gGo3Rrsl3sojPujI2aZsb", $key, $iv); |
|
|
|
$mediaurl = aes_decrypt("fIuPMpBI1RpRnM2JhbYHzvwCvwhHBF7Q+8k14m9h3N5ZfubHcDCEk08TnLwHoMI/SG7bxpqT6Rh+gZunSpYHf1JM/RmEC/S1SjRYWw6rwc3gGo3Rrsl3sojPujI2aZsb", $key, $iv); |
|
|
|
|
|
|
|
|
|
|
|
function getLiveUrl($rid, $cdn, $cdnType, $mediaurl) |
|
|
|
$uid = json_decode(get_content("https://udblgn.huya.com/web/anonymousLogin", "uid"), true)["data"]["uid"]; |
|
|
|
{ |
|
|
|
|
|
|
|
$liveurl = "https://m.huya.com/" . $rid; |
|
|
|
|
|
|
|
$ch = curl_init(); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $liveurl); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_ENCODING, "gzip"); |
|
|
|
|
|
|
|
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false); |
|
|
|
|
|
|
|
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, false); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array( |
|
|
|
|
|
|
|
"User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1", |
|
|
|
|
|
|
|
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" |
|
|
|
|
|
|
|
)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$result = curl_exec($ch); |
|
|
|
function get_uuid() |
|
|
|
curl_close($ch); |
|
|
|
{ |
|
|
|
|
|
|
|
$now = intval(microtime(true) * 1000); |
|
|
|
|
|
|
|
$rand = rand(0, 1000) | 0; |
|
|
|
|
|
|
|
return intval(($now % 10000000000 * 1000 + $rand) % 4294967295); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$matches = array(); |
|
|
|
function process_anticode($anticode, $uid, $streamname) |
|
|
|
preg_match('/<script> window.HNF_GLOBAL_INIT = (.*)<\/script>/', $result, $matches); |
|
|
|
{ |
|
|
|
if (count($matches) < 2) { |
|
|
|
parse_str($anticode, $q); |
|
|
|
return null; |
|
|
|
$q["t"] = '102'; |
|
|
|
|
|
|
|
$q["ctype"] = 'tars_mp'; |
|
|
|
|
|
|
|
$q["wsTime"] = dechex(time() + 21600); |
|
|
|
|
|
|
|
$q["ver"] = "1"; |
|
|
|
|
|
|
|
$q["sv"] = date('YmdH'); |
|
|
|
|
|
|
|
$q["seqid"] = strval(intval($uid) + intval(microtime(true) * 1000)); |
|
|
|
|
|
|
|
$q["uid"] = strval($uid); |
|
|
|
|
|
|
|
$q["uuid"] = strval(get_uuid()); |
|
|
|
|
|
|
|
$ss = md5("{$q["seqid"]}|{$q["ctype"]}|{$q["t"]}"); |
|
|
|
|
|
|
|
$q["fm"] = base64_decode($q["fm"]); |
|
|
|
|
|
|
|
$q["fm"] = str_replace(["$0", "$1", "$2", "$3"], [$q["uid"], $streamname, $ss, $q["wsTime"]], $q["fm"]); |
|
|
|
|
|
|
|
$q["wsSecret"] = md5($q["fm"]); |
|
|
|
|
|
|
|
unset($q["fm"]); |
|
|
|
|
|
|
|
if (array_key_exists("txyp", $q)) { |
|
|
|
|
|
|
|
unset($q["txyp"]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return http_build_query($q); |
|
|
|
return extractInfo($matches[1], $cdn, $cdnType, $mediaurl); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function extractInfo($content, $cdn, $cdnType, $mediaurl) |
|
|
|
function format($livearr, $uid) |
|
|
|
{ |
|
|
|
{ |
|
|
|
$parse = json_decode($content, true); |
|
|
|
$stream_info = ['flv' => [], 'hls' => []]; |
|
|
|
if (array_key_exists("exceptionType", $parse)) { |
|
|
|
$cdn_type = ['HY' => 'hycdn', 'AL' => 'alicdn', 'TX' => 'txcdn', 'HW' => 'hwcdn', 'HS' => 'hscdn', 'WS' => 'wscdn']; |
|
|
|
header('location:' . $mediaurl); |
|
|
|
foreach ($livearr["roomInfo"]["tLiveInfo"]["tLiveStreamInfo"]["vStreamInfo"]["value"] as $s) { |
|
|
|
exit(); |
|
|
|
if ($s["sFlvUrl"]) { |
|
|
|
|
|
|
|
$stream_info["flv"][$cdn_type[$s["sCdnType"]]] = $s["sFlvUrl"] . '/' . $s["sStreamName"] . '.' . $s["sFlvUrlSuffix"] . '?' . process_anticode($s["sFlvAntiCode"], $uid, $s["sStreamName"]); |
|
|
|
} |
|
|
|
} |
|
|
|
$streamInfo = $parse['roomInfo']['tLiveInfo']['tLiveStreamInfo']['vStreamInfo']['value']; |
|
|
|
if ($s["sHlsUrl"]) { |
|
|
|
|
|
|
|
$stream_info["hls"][$cdn_type[$s["sCdnType"]]] = $s["sHlsUrl"] . '/' . $s["sStreamName"] . '.' . $s["sHlsUrlSuffix"] . '?' . process_anticode($s["sHlsAntiCode"], $uid, $s["sStreamName"]); |
|
|
|
$cdnSlice = array(); |
|
|
|
|
|
|
|
$finalurl = null; |
|
|
|
|
|
|
|
foreach ($streamInfo as $value) { |
|
|
|
|
|
|
|
$cdnTypeValue = $value['sCdnType']; |
|
|
|
|
|
|
|
$cdnSlice[] = $cdnTypeValue; |
|
|
|
|
|
|
|
if ($cdnTypeValue == $cdn) { |
|
|
|
|
|
|
|
$urlStr = sprintf("%s/%s.%s?%s", |
|
|
|
|
|
|
|
$value['sFlvUrl'], |
|
|
|
|
|
|
|
$value['sStreamName'], |
|
|
|
|
|
|
|
$value['sFlvUrlSuffix'], |
|
|
|
|
|
|
|
parseAntiCode($value['sFlvAntiCode'], $value['sStreamName'])); |
|
|
|
|
|
|
|
$finalurl = str_replace("http://", "https://", $urlStr); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return $stream_info; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$res = get_content($roomurl, "mobile"); |
|
|
|
|
|
|
|
$reg = "/\<script\> window.HNF_GLOBAL_INIT = (.*) \<\/script\>/i"; |
|
|
|
|
|
|
|
preg_match($reg, $res, $realres); |
|
|
|
|
|
|
|
$realdata = json_decode($realres[1], true); |
|
|
|
|
|
|
|
|
|
|
|
if ($cdnType == "display") { |
|
|
|
if (array_key_exists("exceptionType", $realdata)) { |
|
|
|
var_dump($cdnSlice); |
|
|
|
header('location:' . $mediaurl); |
|
|
|
|
|
|
|
exit(); |
|
|
|
|
|
|
|
} elseif ($realdata["roomInfo"]["eLiveStatus"] == 2) { |
|
|
|
|
|
|
|
$realurl = format($realdata, $uid); |
|
|
|
|
|
|
|
if ($type == "display") { |
|
|
|
|
|
|
|
print_r($realurl); |
|
|
|
exit(); |
|
|
|
exit(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if ($media == "flv") { |
|
|
|
return $finalurl; |
|
|
|
switch ($cdn) { |
|
|
|
|
|
|
|
case $cdn: |
|
|
|
|
|
|
|
$mediaurl = str_replace("http://", "https://", $realurl["flv"][$cdn]); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
$mediaurl = str_replace("http://", "https://", $realurl["flv"]["hwcdn"]); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if ($media == "hls") { |
|
|
|
|
|
|
|
switch ($cdn) { |
|
|
|
|
|
|
|
case $cdn: |
|
|
|
|
|
|
|
$mediaurl = str_replace("http://", "https://", $realurl["hls"][$cdn]); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
$mediaurl = str_replace("http://", "https://", $realurl["hls"]["hwcdn"]); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
header('location:' . $mediaurl); |
|
|
|
|
|
|
|
exit(); |
|
|
|
|
|
|
|
} elseif ($realdata["roomInfo"]["eLiveStatus"] == 3) { |
|
|
|
|
|
|
|
header('location:' . "https:" . base64_decode($realdata["roomProfile"]["liveLineUrl"])); |
|
|
|
|
|
|
|
exit(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
header('location:' . $mediaurl); |
|
|
|
|
|
|
|
exit(); |
|
|
|
} |
|
|
|
} |
|
|
|
$liveurl = getLiveUrl($rid, $cdn, $cdnType, $mediaurl); |
|
|
|
|
|
|
|
$mediaurl = $liveurl == null ? $mediaurl : $liveurl; |
|
|
|
|
|
|
|
header('location:' . $mediaurl); |
|
|
|
|
|
|
|
exit(); |
|
|
|
|