Featured image of post 【PHP】超级干货(腾讯、爱奇艺、优酷)视频解析源码

【PHP】超级干货(腾讯、爱奇艺、优酷)视频解析源码

写这套程序的起因是快两个月前的事情了吧(好像),只是某次没有VIP看电影,用了网上那些所谓的VIP解析结果发现大部分都是盗版或者是非蓝光的,看了不少资料索性决定写一个。

经过实际测试,这部分代码到现在为止(2018年12月2号)都是能够正常使用,至于以后是否如遇官方更新导致失效于本人无关,若非亲友,不提供无偿服务,抱歉!

同时声明:源码仅供技术学习交流,如若用作其它用途导致的任何后果均与本人(小珏博客)无任何关系。

解析介绍:代码封装了三个类,在写的过程中都是以解析出最高画质(蓝光)为目的,所以解析出来的视频都是蓝光画质,部分视频如果官方也未提供蓝光画质,可能导致解析失败等问题,写三个类整整花了我差不多半个月的时间,一边学习一边写,能够写出来完全就是站在各位前辈的肩膀上,在此真诚感谢那些前辈。

Ps:下面的代码即便拿来之后也并不能直接使用,需要配置VIP账号的Cookies,不要问为什么,除此之外爱奇艺的加密算法特别恶心,本人没有能力单独提取出来并写成PHP,所以我是直接提取js函数部分,然后利用服务器部署nodejs提供的加密服务,所以爱奇艺里面的GetKey函数可能因为小珏博客不再提供加密API而导致无法使用。

爱奇艺加密算法API:http://182.254.150.166:558 ,如果不能正常返回数据,说明接口已失效或关闭,此算法不公开了,若有需求可单独详谈。

解析结果:腾讯视频和优酷最后解析出来的都是m3u8格式,这种格式会由于跨域问题,导致大部分PC浏览器无法直接播放,但部分H5(手机)浏览器可正常使用,至于爱奇艺解析出来之后的是整部视频的切割片段,在源码中本人的解决方法时直接解析出所有视频片段然后再组合成m3u8格式的,会在运行目录生成一个缓存文件(m3u8格式文件);经过实际测试发现还是有一点的弊端。

所以在不考虑成本的问题的情况下,利用解析出来的地址完成整部影片的下载再播放,才是最完美的。

最后:上面说这么多无非就是告诉大家,想要大范围使用务必先考量一下是否合适再做抉择(不然我这快半个月的时间都干嘛去了)

1.腾讯视频

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php

$qq = new tx();
print_r($qq->GetUrl('https://v.qq.com/x/cover/co6hernchr5uql1.html'));

class tx {
	static function GetUrl($url = 0) {//解析视频地址
		$url = tx::ToUrl(isset($url) ? $url : $_GET['url']);
		$tm = time();
		$day = date("w") == '0' ? '7' : date("w");
		$vid = tx::GetVid($url);
		$ckey = tx::GetCkey($url, $vid, $tm);
		$api = 'https://vd.l.qq.com/proxyhttp';
		$cookie = 'luin=o1538236552;lskey=000100002f5807ee11112ae5823936dfc93e8c29f02f1ef89f275c7a81f699071f307290eebb538ac41130f8';
		$post = json_encode(array(
			'buid' => 'vinfoad',
			'vinfoparam' => 'otype=ojson&platform=10201&ehost=' . $url . '&refer=v.qq.com&sphttps=1&tm=' . $tm . '&spwm=4&vid=' . $vid . '&defn=fhd&fhdswitch=0&show1080p=1&isHLS=1&dtype=3&sphls=2&spgzip=1&dlver=2&drm=32&spau=1&spaudio=15&defsrc=2&encryptVer=7.' . $day . '&cKey=' . $ckey . '&fp2p=1'
		));
		$ret = self::get_curl($api, $post, $cookie);
		$ret = json_decode($ret, true);
		if (is_array($ret) && $ret['errCode'] == '0') {
			$ret = json_decode($ret['vinfo'], true);
			$ret = array(
				'name' => $ret['vl']['vi']['0']['ti'],
				'url' => $ret['vl']['vi']['0']['ul']['ui']['3']['url']
			);
			return $ret;
		} else
			return false;
	}
	static function getinaurl($longurl) {
		$appkey = '31641035';
		$url = 'https://api.weibo.com/2/short_url/shorten.json?source=' . $appkey . '&url_long=' . urlencode($longurl);
		$result = self::curl_get($url);
		$arr = json_decode($result, true);
		return isset($arr['urls'][0]['url_short']) ? $arr['urls'][0]['url_short'] : false;
	}
	static function ToUrl($url = 0) {
		if (preg_match('/m.v.qq.com/', $url)) {
			preg_match('/w\/(\w+){1,20}\//', $url, $ret);
			$url = 'https://v.qq.com/x/cover/' . $ret[1] . '.html';
			return $url;
		} else
			return $url;
	}
	static function GetVid($url) {
		preg_match('/vid=(\w+){1,20}&/', self::get_curl($url), $ret);
		return $ret[1];
	}
	static function GetCkey($url = null, $vid = null, $tm = Null) {
		// ckey7=md5 ( key + vid + tm + "*#06#" + platform );
		$platform = '10201';
		$day = date("w") == '0' ? '7' : date("w");
		switch ($day) {
			case '1':
				$key = '06fc1464';
				break;
			case '2':
				$key = '4244ce1b';
				break;
			case '3':
				$key = '77de31c5';
				break;
			case '4':
				$key = 'e0149fa2';
				break;
			case '5':
				$key = '60394ced';
				break;
			case '6':
				$key = '2da639f0';
				break;
			case '7': // 星期天
				$key = 'c2f0cf9f';
				break;
		}
		$ckey = md5($key . $vid . $tm . "*#06#" . $platform);
		return $ckey;
	}
	static function get_curl($url, $post = 0, $cookie = 0, $header = 0, $referer = 0, $ua = 0, $nobaody = 0, $proxy = 0) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		$httpheader[] = "Accept:*/*";
		$httpheader[] = "Accept-Encoding:gzip,deflate,sdch";
		$httpheader[] = "Accept-Language:zh-CN,zh;q=0.8";
		$httpheader[] = "Connection:close";
		curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
		if ($post) {
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
		}
		if ($header) {
			curl_setopt($ch, CURLOPT_HEADER, true);
		}
		if ($cookie) {
			curl_setopt($ch, CURLOPT_COOKIE, $cookie);
		}
		if ($referer) {
			if ($referer == 1) {
				curl_setopt($ch, CURLOPT_REFERER, 'http://m.qzone.com/infocenter?g_f=');
			} else {
				curl_setopt($ch, CURLOPT_REFERER, $referer);
			}
		}
		if ($ua) {
			curl_setopt($ch, CURLOPT_USERAGENT, $ua);
		} else {
			curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
		}
		if ($nobaody) {
			curl_setopt($ch, CURLOPT_NOBODY, 1);
		}
		if ($proxy) {
			curl_setopt($ch, CURLOPT_PROXY, $proxy);
		}
		curl_setopt($ch, CURLOPT_ENCODING, "gzip");
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$ret = curl_exec($ch);
		curl_close($ch);
		return $ret;
	}
}

2.优酷视频

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
header("Content-type:text/json;charset=UTF-8");
$url = 'https://v.youku.com/v_show/id_XMzY1MjM5NTEyNA==.html?x&sharefrom=android&sharekey=3af5943a61865e8764242087de1741748';
print_r(youku::GetRealUrl($url));

class youku {
	private static $vid = Null; //视频ID
	private static $url = Null; //视频URL
	private static $api = Null; //请求API
	private static $data = Null; //URL参数
	private static $sign = Null; //URL签名
	private static $time = Null; //当前时间戳
	private static $token = Null; //加密Token
	private static $appKey = '24679788'; //appKey
	private static $cookie = 'P_pck_rm=wJlyhW1DcLiVNdTAjZCpGIHS7a3Dgj%2BKm9pOn2vAkj2FqZZVpZYK0DImRiXt1j6CczJHUibTtgO0h5qIbIE8DKup5LeAbtow3t143nchxK86pgilbYA5cVOWOcF%2B7eOPVTeoN%2FNIcFUBYW30S88%2FYA%3D%3D; _m_h5_tk=b4e69ab122973fdf474651b2e2523ee6_1539619698343; _m_h5_tk_enc=08c4689efff06e847615dcf034a235eb;'; //必须Cookie
	
	public static function GetRealUrl($video_url) {
		//================
		self::$url = $video_url;
		self::$time = time();
		self::getVid();
		self::getToken();
		self::getData();
		self::getSign();
		self::getApi();
		//===============
		//注释初始化操作,不能改变顺序
		$ret = self::get_curl(self::$api, null, self::$cookie, 0, 'https://v.youku.com/v_show/id_' . self::$vid . '.html');
		$ret = json_decode($ret, true);
		if ($ret['ret'][0] == 'SUCCESS::调用成功') {
			$name = $ret['data']['data']['show']['title']; //获取片名
			foreach ($ret['data']['data']['stream'] as $value)
				if ($value['stream_type'] == 'mp4hd3v2' || $value['stream_type'] == 'mp4hd3' || $value['stream_type'] == 'mp5hd3' || $value['stream_type'] == 'mp4hd2' || $value['stream_type'] == 'mp4hd2v2' || $value['stream_type'] == 'mp5hd2') { //优酷画质比较多,默认只获取1920x1080和1280x720两种
					$RealUrl = $value['m3u8_url'];
					return array(
						'name' => $name,
						'url' => $RealUrl
					);
					break;
				}
		} elseif ($ret['ret'][0] == 'FAIL_SYS_TOKEN_EXOIRED::令牌过期') { //过期重新获取Cookie
			$ret = self::get_curl(self::$api, null, self::$cookie, 1, 'https://v.youku.com/v_show/id_' . self::$vid . '.html');
			preg_match('/_m_h5_tk=(.*?);/', $ret, $_m_h5_tk);
			preg_match('/_m_h5_tk_enc=(.*?);/', $ret, $_m_h5_tk_enc);
			preg_match('/P_pck_rm=(.*?);/', self::$cookie, $P_pck_rm);
			$cookie = "P_pck_rm={$P_pck_rm[1]};_m_h5_tk={$_m_h5_tk[1]};_m_h5_tk_enc={$_m_h5_tk_enc[1]};";
			self::$cookie = $cookie;
			return self::GetRealUrl(self::$url); //递归重新获取
		} else
			return False;
	}
	
	private static function getVid() {
		preg_match('/id_(.*?).html/', self::$url, $ret);
		self::$vid = $ret[1];
		return self::$vid;
	}
	
	private static function getToken() {
		preg_match('/_m_h5_tk=(.*?)_/', self::$cookie, $token);
		self::$token = $token[1];
		return self::$token;
	}
	
	private static function getSign() {
		$signstr = self::$token . "&" . self::$time . "&" . self::$appKey . "&" . self::$data;
		$sign = md5($signstr);
		self::$sign = $sign;
		return self::$sign;
	}
	private static function getApi() {
		$api = "https://acs.youku.com/h5/mtop.youku.play.ups.appinfo.get/1.1/?&appKey=" . self::$appKey . "&t=" . self::$time . "&sign=" . self::$sign . "&data=" . urlencode(self::$data);
		self::$api = $api;
		return self::$api;
	}
	
	private static function getData() {
		$data['steal_params'] = '{"ccode":"0502","client_ip":"192.168.1.1","utid":"YuTEE+JjUwMCAXxMObYVb8Eg","client_ts":1539591989,"version":"0.5.82","ckey":"DIl58SLFxFNndSV1GFNnMQVYkx1PP5tKe1siZu/86PR1u/Wh1Ptd+WOZsHHWxysSfAOhNJpdVWsdVJNsfJ8Sxd8WKVvNfAS8aS8fAOzYARzPyPc3JvtnPHjTdKfESTdnuTW6ZPvk2pNDh4uFzotgdMEFkzQ5wZVXl2Pf1/Y6hLK0OnCNxBj3+nb0v72gZ6b0td+WOZsHHWxysSo/0y9D2K42SaB8Y/+aD2K42SaB8Y/+ahU+WOZsHcrxysooUeND"}';
		$data['biz_params'] = '{"vid":"' . self::$vid . '","current_showid":"314030"}';
		$data['ad_params'] = '{"site":1,"wintype":"interior","p":1,"fu":0,"vs":"1.0","rst":"mp4","dq":"hd3","os":"win","osv":"","d":"0","bt":"pc","aw":"w","needbf":1,"atm":""}';
		
		self::$data = json_encode($data);
		return self::$data;
	}
	static function get_curl($url, $post = 0, $cookie = 0, $header = 0, $referer = 0, $ua = 0, $nobaody = 0, $proxy = 0) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		$httpheader[] = "Accept:*/*";
		$httpheader[] = "Accept-Encoding:gzip,deflate,sdch";
		$httpheader[] = "Accept-Language:zh-CN,zh;q=0.8";
		$httpheader[] = "Connection:close";
		curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
		if ($post) {
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
		}
		if ($header) {
			curl_setopt($ch, CURLOPT_HEADER, true);
		}
		if ($cookie) {
			curl_setopt($ch, CURLOPT_COOKIE, $cookie);
		}
		if ($referer) {
			if ($referer == 1) {
				curl_setopt($ch, CURLOPT_REFERER, 'http://m.qzone.com/infocenter?g_f=');
			} else {
				curl_setopt($ch, CURLOPT_REFERER, $referer);
			}
		}
		if ($ua) {
			curl_setopt($ch, CURLOPT_USERAGENT, $ua);
		} else {
			curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
		}
		if ($nobaody) {
			curl_setopt($ch, CURLOPT_NOBODY, 1);
		}
		if ($proxy) {
			curl_setopt($ch, CURLOPT_PROXY, $proxy);
		}
		curl_setopt($ch, CURLOPT_ENCODING, "gzip");
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$ret = curl_exec($ch);
		curl_close($ch);
		return $ret;
	}
	
}

?>

3.爱奇艺

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
<?php
header("Content-type:text/json;charset=UTF-8");
$url = 'https://www.iqiyi.com/v_19rrdeqs18.html';
print_r(iqiyi::GetVideoData($url));

class iqiyi {
	private static $VideoUrl = Null; //请求视频地址
	private static $CacheParas = array(); //获取Cache请求参数
	private static $DataParas = array(); //获取Data请求参数
	private static $VideoHtmlCode = Null; //视频网页源代码
	private static $Cookie = 'P00003=1501832919;QC005=d8206ef0b1ef570a78ba87f5cdb8ef6c;__dfp=a0decd9801b81747cdb217625fa018935deb6c10ab389cc60e65b0f71bc08a3052@1541408067407@1540112067407;P00001=91UoMX3jkXn82m1rnm1YgWNWc4KuS5llxT9dW4f4xznfWD9QLirBFiv4JIaPMrWczYOa1f;QY00001=1501832919;'; //爱奇艺Cookie
	
	public static function GetVideoData($VideoUrl) {
		self::$VideoUrl = $VideoUrl;
		
		//==========================
		//初始化Cache请求参数
		$CacheUrl = self::initCacheUrl();
		
		//获取Cache数据
		$CacheData = self::GetCacheData($CacheUrl);
		
		//初始化Data请求地址,返回数组
		$DataUrl = self::initDataUrl($CacheData);
		
		//获取每段视频真实播放地址
		$RealVideoUrl = self::GetRealUrl($DataUrl);
		
		//生成单个Cache文件,返回播放地址
		$PlayUrl = self::toCacheFile($RealVideoUrl);
		
		//获取视频片名,图片信息
		$Info = self::getVideoInfo();
		
		$ret['name'] = $Info['name'];
		$ret['url'] = $PlayUrl;
		$ret['imageurl'] = 'https://' . $Info['imageurl'];
		return $ret;
		
	}
	
	private static function getVideoInfo() { //获取视频信息
		preg_match('/"albumName":"(.*?)"/', self::$VideoHtmlCode, $name);
		preg_match('/"imageUrl":"\/\/(.*?)"/', self::$VideoHtmlCode, $imageurl);
		
		return array(
			"name" => $name['1'],
			"imageurl" => $imageurl['1']
		);
	}
	
	
	private static function toCacheFile($RealVideoUrl) { //生成Cache文件,返回播放地址
		
		global $conf;
		
		$filename = md5(self::$VideoUrl);
		
		$filepath = './' . $filename . '.txt';
		
		$m3u8 = "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-TARGETDURATION:10\n#EXT-X-MEDIA-SEQUENCE:0\n";
		foreach ($RealVideoUrl as $v) {
			$m3u8 .= ("#EXTINF:600,\n" . $v . "\n");
		}
		$m3u8 .= '#EXT-X-ENDLIST';
		
		file_put_contents($filepath, $m3u8);
		
		$url = 'http://'.$_SERVER['HTTP_HOST'] . '/player.php?vid=' . $filename;
		
		return $url;
	}
	
	private static function GetRealUrl($DataUrl) { //获取视频真实播放地址
		foreach ($DataUrl as $value) {
			$ret = json_decode(self::get_curl($value), true);
			
			$UrlList[] = $ret['l'];
		}
		return empty($UrlList) ? 'GetRealUrl:ErrorCode_001' : $UrlList;
	}
	
	private static function initDataUrl($CacheData) { //构造分段视频请求地址
		if (!is_array($CacheData)) //判断数据是否合法
			return 'initDataUrl:ErrorCode_002';
		
		foreach ($CacheData['data']['program']['video'] as $value) { //遍历数组,取出有效数据
			if ($value['_selected'] == 1) {
				self::$DataParas['vid'] = $value['vid'];
				$video = ($value['fs']);
				break;
			}
		}
		preg_match('/QC005=(.{32});/', self::$Cookie, $qyid);
		preg_match('/QY00001=(\d*);/', self::$Cookie, $QY00001);
		
		self::$DataParas['QY00001'] = $QY00001['1']; //cookie->QY00001
		self::$DataParas['qyid'] = $qyid['1']; // cookie :cookie->QC005
		
		self::$DataParas['tvid'] = $CacheData['data']['tvid'];
		self::$DataParas['cid'] = 'afbe8fd3d73448c9'; //常量
		self::$DataParas['cross_domain'] = 1;
		self::$DataParas['ib'] = 4;
		self::$DataParas['ptime'] = 0;
		self::$DataParas['pv'] = 0.1;
		self::$DataParas['pri_idc'] = 'baiducdn_ct';
		self::$DataParas['qypid'] = self::$DataParas['tvid'] . '_02020031010000000000';
		
		$DataAPI = 'https://data.video.iqiyi.com/videos';
		
		foreach ($video as $value) {
			preg_match('/\/(.{32})\./', $value['l'], $ret);
			$t = $CacheData['data']['boss']['data']['t'];
			$signstr = $t . $ret['1'];
			
			$ibt = self::GetKey('cmd5x', $signstr);
			
			$DataUrl = $DataAPI . $value['l'] . "&QY00001=" . self::$DataParas['QY00001'] . "&cid=" . self::$DataParas['cid'] . "&cross-domain=" . self::$DataParas['cross_domain'] . "&ib=" . self::$DataParas['ib'] . "&ibt=$ibt&pri_idc=" . self::$DataParas['pri_idc'] . "&ptime=" . self::$DataParas['ptime'] . "&pv=" . self::$DataParas['pv'] . "&qyid=" . self::$DataParas['qyid'] . "&qypid=" . self::$DataParas['qypid'] . "&vid=" . self::$DataParas['vid'] . "&t=" . $t;
			
			$DataURL[] = $DataUrl;
		}
		
		return is_array($DataURL) ? $DataURL : 'initDataUrl:ErrorCode_001';
		
	}
	
	private static function GetCacheData($CacheUrl) { //获取Cache数据,返回数组
		$data = self::get_curl($CacheUrl);
		
		$CacheArray = json_decode(substr($data, 38, -15), true);
		
		return is_array($CacheArray) ? $CacheArray : 'GetCacheData:ErrorCode_001';
	}
	
	private static function initCacheUrl() { //构造获取Cache数据请求地址
		if (empty(self::$VideoUrl)) {
			return 'initCacheUrl:没有传入视频地址';
		}
		
		$VideoHtmlCode = self::get_curl(self::$VideoUrl);
		self::$VideoHtmlCode = $VideoHtmlCode;
		
		
		preg_match('/"tvId":(\d*?),/', $VideoHtmlCode, $tvid);
		preg_match('/"vid":"(.{32})"/', $VideoHtmlCode, $vid);
		preg_match('/P00003=(\d*?);/', self::$Cookie, $uid);
		preg_match('/QC005=(.{32});/', self::$Cookie, $k_uid);
		preg_match('/dfp=(.*?)@/', self::$Cookie, $dfp);
		preg_match('/P00001=(.*?);/', self::$Cookie, $pck);
		
		self::$CacheParas['tvid'] = $tvid['1'];
		self::$CacheParas['vid'] = $vid['1'];
		self::$CacheParas['uid'] = $uid['1'];
		self::$CacheParas['dfp'] = $dfp['1'];
		self::$CacheParas['pck'] = $pck['1'];
		self::$CacheParas['bop'] = '%7B%22version%22%3A%227.0%22%2C%22dfp%22%3A%22' . $dfp . '%22%7D';
		self::$CacheParas['k_uid'] = $k_uid['1'];
		self::$CacheParas['tm'] = self::getMillisecond();
		
		
		self::$CacheParas['authKey'] = self::GetKey('authKey', self::$CacheParas['tm'] . self::$CacheParas['tvid']);
		
		
		self::$CacheParas['cf'] = Null; //
		self::$CacheParas['ct'] = Null; //
		self::$CacheParas['s'] = Null; //
		self::$CacheParas['lid'] = Null; //
		self::$CacheParas['rs'] = '1'; //
		self::$CacheParas['vt'] = '0'; //
		self::$CacheParas['pt'] = '0'; //
		self::$CacheParas['d'] = '0'; //
		self::$CacheParas['k_tag'] = '1'; //
		self::$CacheParas['locale'] = 'zh_cn'; //
		self::$CacheParas['qd_v'] = '1'; //
		self::$CacheParas['ori'] = 'pcw'; //
		
		self::$CacheParas['prio'] = '%7B%22ff%22%3A%22f4v%22%2C%22code%22%3A2%7D';
		self::$CacheParas['bid'] = '600'; //
		self::$CacheParas['k_err_retries'] = '0'; //
		self::$CacheParas['k_ft1'] = '2748779069444';
		self::$CacheParas['ost'] = '0'; //
		self::$CacheParas['ppt'] = '0'; //
		self::$CacheParas['ps'] = '0'; //
		self::$CacheParas['src'] = '01010031010000000000'; //      
		self::$CacheParas['ut'] = '1'; //      
		self::$CacheParas['callback'] = 'Q838114a04d5d4d3adb265513f3244a36';
		
		$paras = "/jp/dash?tvid=" . self::$CacheParas['tvid'] . "&bid=" . self::$CacheParas['bid'] . "&vid=" . self::$CacheParas['vid'] . "&src=" . self::$CacheParas['src'] . "&vt=" . self::$CacheParas['vt'] . "&rs=" . self::$CacheParas['rs'] . "&uid=" . self::$CacheParas['uid'] . "&ori=" . self::$CacheParas['ori'] . "&ps=" . self::$CacheParas['ps'] . "&tm=" . self::$CacheParas['tm'] . "&qd_v=" . self::$CacheParas['qd_v'] . "&k_uid=" . self::$CacheParas['k_uid'] . "&pt=" . self::$CacheParas['pt'] . "&d=" . self::$CacheParas['d'] . "&s=" . self::$CacheParas['s'] . "&lid=" . self::$CacheParas['lid'] . "&cf=" . self::$CacheParas['cf'] . "&ct=" . self::$CacheParas['ct'] . "&authKey=" . self::$CacheParas['authKey'] . "&k_tag=" . self::$CacheParas['k_tag'] . "&ost=" . self::$CacheParas['ost'] . "&ppt=" . self::$CacheParas['ppt'] . "&dfp=" . self::$CacheParas['dfp'] . "&locale=" . self::$CacheParas['locale'] . "&prio=" . self::$CacheParas['prio'] . "&pck=" . self::$CacheParas['pck'] . "&k_err_retries=" . self::$CacheParas['k_err_retries'] . "&k_ft1=" . self::$CacheParas['k_ft1'] . "&bop=" . self::$CacheParas['bop'] . "&callback=" . self::$CacheParas['callback'] . "&ut=" . self::$CacheParas['ut'];
		
		
		self::$CacheParas['$vf'] = self::GetKey('cmd5x', $paras);
		
		$cacheHost = "https://cache.video.iqiyi.com";
		
		$cacheURL = $cacheHost . $paras . '&vf=' . self::$CacheParas['$vf'];
		
		return $cacheURL;
		
	}
	
	private static function GetKey($act, $data) { //act:authKey,cmd5x
		$api = 'http://182.254.150.166:558';
		if ($act == 'authKey') {
			$sign = 'act=authKey&signstr=';
		} else if ($act == 'cmd5x') {
			$sign = 'act=cmd5x&signstr=';
		} else {
			return 'GetKey:ErrorCode_001';
		}
		$sign .= urlencode(base64_encode($data));
		
		$key = trim(self::get_curl($api, $sign));
		
		return empty($key) ? 'GetKey:ErrorCode_002' : $key;
	}
	static function get_curl($url, $post = 0, $cookie = 0, $header = 0, $referer = 0, $ua = 0, $nobaody = 0, $proxy = 0) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		$httpheader[] = "Accept:*/*";
		$httpheader[] = "Accept-Encoding:gzip,deflate,sdch";
		$httpheader[] = "Accept-Language:zh-CN,zh;q=0.8";
		$httpheader[] = "Connection:close";
		curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
		if ($post) {
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
		}
		if ($header) {
			curl_setopt($ch, CURLOPT_HEADER, true);
		}
		if ($cookie) {
			curl_setopt($ch, CURLOPT_COOKIE, $cookie);
		}
		if ($referer) {
			if ($referer == 1) {
				curl_setopt($ch, CURLOPT_REFERER, 'http://m.qzone.com/infocenter?g_f=');
			} else {
				curl_setopt($ch, CURLOPT_REFERER, $referer);
			}
		}
		if ($ua) {
			curl_setopt($ch, CURLOPT_USERAGENT, $ua);
		} else {
			curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
		}
		if ($nobaody) {
			curl_setopt($ch, CURLOPT_NOBODY, 1);
		}
		if ($proxy) {
			curl_setopt($ch, CURLOPT_PROXY, $proxy);
		}
		curl_setopt($ch, CURLOPT_ENCODING, "gzip");
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$ret = curl_exec($ch);
		curl_close($ch);
		return $ret;
	}
	/*毫秒级时间戳*/
	static function getMillisecond() {
		list($s1, $s2) = explode(' ', microtime());
		return (float) sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
	}
	
}



?>
使用 Hugo 构建
主题 StackJimmy 设计