├── README.md ├── cctv_ysp.php └── mpvtest.py /README.md: -------------------------------------------------------------------------------- 1 | # yspLive 2 | 3 | 播放需要添加请求头 4 | "user-agent":"cctv_app_tv" 5 | "UID":"*****" 6 | 给了一个py调用mpv例子,其余自行解决 7 | 8 | ## 不再更新 9 | 建议使用 10 | https://github.com/wxhwz/ysptp 11 | -------------------------------------------------------------------------------- /cctv_ysp.php: -------------------------------------------------------------------------------- 1 | "Live1717729995180256", 5 | "cctv2_10m" => "Live1718261577870260", 6 | "cctv3_10m" => "Live1718261955077261", 7 | "cctv4_10m" => "Live1718276148119264", 8 | "cctv5_10m" => "Live1719474204987287", 9 | "cctv5p_10m" => "Live1719473996025286", 10 | "cctv7_10m" => "Live1718276412224269", 11 | "cctv8_10m" => "Live1718276458899270", 12 | "cctv9_10m" => "Live1718276503187272", 13 | "cctv10_10m" => "Live1718276550002273", 14 | "cctv11_10m" => "Live1718276603690275", 15 | "cctv12_10m" => "Live1718276623932276", 16 | "cctv13_10m" => "Live1718276575708274", 17 | "cctv14_10m" => "Live1718276498748271", 18 | "cctv15_10m" => "Live1718276319614267", 19 | "cctv16_10m" => "Live1718276256572265", 20 | "cctv164k_36m" => "Live1704966749996185", 21 | "cctv164k_10m" => "Live1704966749996185", 22 | "cctv17_10m" => "Live1718276138318263", 23 | "cctv4k_36m" => "Live1704872878572161", 24 | "cctv4k_10m" => "Live1704872878572161", 25 | "cctv8k_36m" => "Live1688400593818102", 26 | "cgtn_10m" => "Live1719392219423280", 27 | "cgtnfr_10m" => "Live1719392670442283", 28 | "cgtnru_10m" => "Live1719392779653284", 29 | "cgtnar_10m" => "Live1719392885692285", 30 | "cgtnsp_10m" => "Live1719392560433282", 31 | "cgtnen_10m" => "Live1719392360336281" 32 | ); 33 | $channel = $_GET['channel'] or $channel = "cctv1_10m"; 34 | $uid = $_GET['uid'] or $uid = "1234123122"; 35 | if (!array_key_exists($channel, $cctv_list)) { 36 | echo "Channel not found!"; 37 | } 38 | $datas = explode(",", $cctv_list[$channel]); 39 | $data = get_url($channel, $datas[0], $uid, $cache); 40 | header("content-type=application/x-mpegURL;filename=" . $channel . ".m3u8"); 41 | echo $data; 42 | function get_url($id, $hid, $uid,$cache) 43 | { 44 | //global $cache, $uid; 45 | $playUrl = $cache->get($id . $uid); 46 | if (!$playUrl) { 47 | $url = "https://ytpaddr.cctv.cn/gsnw/live"; 48 | $dd = '{ 49 | "rate": "", 50 | "systemType": "android", 51 | "id": "", 52 | "userId": "", 53 | "clientSign": "cctvVideo", 54 | "deviceId": { 55 | "serial": "", 56 | "imei": "", 57 | "android_id": "42e4f5c90dc7f060" 58 | } 59 | }'; 60 | $requestData = json_decode($dd, true); 61 | $requestData['id'] = $hid; 62 | $jsonData = json_encode($requestData); 63 | $ch = curl_init(); 64 | curl_setopt($ch, CURLOPT_URL, $url); 65 | curl_setopt($ch, CURLOPT_POST, true); 66 | curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData); 67 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 68 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 69 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 70 | curl_setopt($ch, CURLOPT_HTTPHEADER, [ 71 | 'Content-Type: application/json' 72 | ]); 73 | $response = curl_exec($ch); 74 | if (curl_errno($ch)) { 75 | echo 'cURL 错误: ' . curl_error($ch); 76 | } 77 | curl_close($ch); 78 | $retData = json_decode($response, true); 79 | $retData = json_decode($response, true); 80 | $videoList=$retData && isset($retData['data']['videoList']); 81 | $url = $videoList ? $retData['data']['videoList'][0]['url'] : ''; 82 | $url = $videoList ? $retData['data']['videoList'][1]['url'] : ''; 83 | $bstrURL = "https://ytpvdn.cctv.cn/cctvmobileinf/rest/cctv/videoliveUrl/getstream"; 84 | $postData = 'appcommon={"ap":"cctv_app_tv","an":"央视投屏助手","adid":" ' . $uid . '","av":"1.1.7"}&url=' . $url; 85 | $ch = curl_init(); 86 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 87 | curl_setopt($ch, CURLOPT_URL, $bstrURL); 88 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 89 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 90 | curl_setopt($ch, CURLOPT_POST, TRUE); 91 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 92 | $APPRANDOMSTR = uniqid(); 93 | $secretKey = "5f39826474a524f95d5f436eacfacfb67457c4a7"; 94 | $rawSign = "5f39826474a524f95d5f436eacfacfb67457c4a7c4068ea020ce4683a197bb88a47a39dc" . $APPRANDOMSTR; 95 | $APPSIGN = md5($rawSign); 96 | $headers = [ 97 | "User-Agent: cctv_app_tv", 98 | "Referer: api.cctv.cn", 99 | "UID: $uid", 100 | "APPID: $secretKey", 101 | "APPSIGN: $APPSIGN", 102 | "APPRANDOMSTR: $APPRANDOMSTR" 103 | ]; 104 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 105 | $data = curl_exec($ch); 106 | curl_close($ch); 107 | $obj = json_decode($data); 108 | $playUrl = $obj->url; 109 | $cache->put($id . $uid, $playUrl); 110 | } 111 | $ch = curl_init(); 112 | $path = substr($playUrl, 0, strrpos($playUrl, '/') + 1); 113 | while (1) { 114 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 115 | curl_setopt($ch, CURLOPT_URL, $playUrl); 116 | curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: cctv_app_tv", "Referer: api.cctv.cn", "UID: " . $uid)); 117 | $data = curl_exec($ch); 118 | preg_match('/(.*\.m3u8\?.*)/', $data, $matches); 119 | if (!empty($matches)) { 120 | $m3u8_url = $matches[0]; 121 | $playUrl = $path . $m3u8_url; 122 | } else { 123 | break; 124 | } 125 | } 126 | $data = preg_replace('/(.*?.ts)/i', $path . '$1', $data); 127 | curl_close($ch); 128 | return $data; 129 | } 130 | 131 | // 以下缓存类来自互联网,请确保cache目录存在以及读写权限 // 132 | class Cache 133 | { 134 | 135 | private $cache_path; 136 | private $cache_expire; 137 | 138 | public function __construct($exp_time = 3600, $path = "cache/") 139 | { 140 | $this->cache_expire = $exp_time; 141 | $this->cache_path = $path; 142 | } 143 | 144 | private function fileName($key) 145 | { 146 | return $this->cache_path . md5($key); 147 | } 148 | 149 | public function put($key, $data) 150 | { 151 | 152 | $values = serialize($data); 153 | $filename = $this->fileName($key); 154 | $file = fopen($filename, 'w'); 155 | if ($file) { 156 | 157 | fwrite($file, $values); 158 | fclose($file); 159 | } else return false; 160 | } 161 | 162 | public function get($key) 163 | { 164 | 165 | $filename = $this->fileName($key); 166 | 167 | if (!file_exists($filename) || !is_readable($filename)) { 168 | return false; 169 | } 170 | 171 | if (time() < (filemtime($filename) + $this->cache_expire)) { 172 | 173 | $file = fopen($filename, "r"); 174 | 175 | if ($file) { 176 | 177 | $data = fread($file, filesize($filename)); 178 | fclose($file); 179 | return unserialize($data); 180 | } else return false; 181 | 182 | } else return false; 183 | } 184 | } 185 | 186 | ?> 187 | -------------------------------------------------------------------------------- /mpvtest.py: -------------------------------------------------------------------------------- 1 | import time 2 | import mpv 3 | from loguru import logger 4 | logger.add("mpv.log", format="{time} {level} {message}", level="INFO", rotation="10 MB", retention="10 days", compression="zip") 5 | 6 | def my_log(loglevel, component, message): 7 | if loglevel == "error": 8 | logger.error(f"{title} {message} {component}") 9 | 10 | 11 | def play(title): 12 | player["stream-record"] = "./record/" + title + ".ts" 13 | player["user-agent"] = "cctv_app_tv" 14 | player["input-default-bindings"] = "yes" 15 | player["input-vo-keyboard"] = "yes" 16 | player["http-header-fields"] = "UID:42e4f5c90dc7f06a" 17 | url = f"http://localhost:800/cctv_ysp.php?channel={title}&uid=42e4f5c90dc7f06a" 18 | player.title = title 19 | player.play(url) 20 | time.sleep(20) 21 | if __name__ == '__main__': 22 | player = mpv.MPV(ytdl=True, log_handler=my_log) 23 | datas = ["cctv1_10m", "cctv2_10m", "cctv3_10m", "cctv4_10m", "cctv5_10m", "cctv5p_10m", "cctv7_10m", "cctv8_10m", 24 | "cctv9_10m", "cctv10_10m", "cctv11_10m", "cctv12_10m", "cctv13_10m", "cctv14_10m", "cctv15_10m", 25 | "cctv16_10m", "cctv17_10m", "cgtnar_10m", "cgtndoc_10m", "cgtnen_10m", "cgtnfr_10m", "cgtnru_10m", 26 | "cgtnsp_10m", "cctv16_25m", "cctv4k_10m", "cctv4k10m", "cctv4k1610m", "cctv4k16_36m", "cctv4k_25m", 27 | "cctv4k_36m", "cctv8k_36m"] 28 | for title in datas: 29 | play(title) 30 | --------------------------------------------------------------------------------