以下内容仅供学习使用,请勿用于非法用途
代码是在今年三月份写的,当时候捣鼓了一天,现在也有点忘了,就直接把代码贴出来吧,今天测试了一下还是可以用的
代码中有一些包还有方法是自己的,就不都粘贴出来了,如果直接复制代码的话,会有报错,需要再手动改改
<!--相关依赖-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
package com.Yang.watermark;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TencentVideo{
String url = "";
String appVersion = "1.0.143";
String platform = "10201";
String v = "3.5.57";
String encryptVer = "9.1";
public TencentVideo(String url) {
this.url = url;
}
@Override
public String execute() {
String start = "<link rel=\"canonical\" href=";
HttpResponse response = requestNoHeader(url);
String body = response.body();
int indexOf = body.indexOf(start);
body = body.substring(indexOf + start.length() + 1);
int index = body.indexOf("\" />");
body = body.substring(0,index);
String[] split = body.split("/");
String vid = split[split.length - 1].replaceAll(".html","");
String[] split2 = url.split("/");
String coverid = split2[split2.length - 1].replaceAll(".html","");
//这儿替换成自己的生产随机数的方法就可以
String flowid = RandomCharUtil.getRandomNumberLowerLetterChar(32) + "_" + platform;
String tm = String.valueOf(System.currentTimeMillis()).substring(0,10);
String rfid = RandomCharUtil.getRandomNumberLowerLetterChar(32) + "_" + tm;
//这儿是cKet加密字符串的获取方式,调用自己的node服务,下文中有说明
String cKey = HttpUtil.get("http://Ip:port/?vid="+ vid +"&tm=" + tm);
log.info("vid:{}",vid);
log.info("coverid:{}",coverid);
log.info("flowid:{}",flowid);
log.info("tm:{}",tm);
log.info("rfid:{}",rfid);
log.info("url:{}",url);
log.info("cKey:{}",cKey);
//登录了腾讯视频之后可以拿到cookie,直接粘贴在这儿就行
String cookieStr = "";
String[] split3 = cookieStr.split("; ");
Map<String, String> cookieMap = new HashMap<String, String>();
if(cookieStr != "" && cookieStr != null) {
for(String str : split3) {
cookieMap.put(str.split("=")[0], str.split("=")[1]);
}
}
HttpRequest post = HttpUtil.createPost("https://vd.l.qq.com/proxyhttp");
post.header("Referer" , url);
String buildParam = buildParam(coverid, flowid, url, rfid, vid, cKey, tm , cookieMap);
post.body(buildParam);
//执行
String res = post.execute().body();
log.info(res);
JSONArray ul = JSONObject.parseObject(res).getJSONObject("vinfo").getJSONObject("vl").getJSONArray("vi").getJSONObject(0).getJSONObject("ul").getJSONArray("ui");
//这里拿数组最后一个,清晰度最高的
JSONObject ui = ul.getJSONObject(ul.size()-1);
if(cookieStr == "") {
//没有登录使用这种方式获取,但是如果是vip电影获取出来的只有5分钟
return ui.getString("url") + ui.getJSONObject("hls").getString("pt");
}
//如果登录了可以使用这种方式获取
return ui.getString("url");
}
public static String get(String address) {
return new TencentVideo(address).execute();
}
public static void main(String[] args) {
log.info(TencentVideo.get("https://v.qq.com/x/cover/050w2y6nen7rud1.html"));
// TencentVideo.get("https://v.qq.com/x/cover/bqejbbv8mgtusrs/u00242ise58.html");
}
public String buildParam(String coverid,String flowid,String url,String rfid , String vid , String cKey , String tm , Map<String, String> cookieMap) {
boolean haveCookie = false;
if(!cookieMap.isEmpty()) {
haveCookie = true;
}
StringBuffer adparam = new StringBuffer();
adparam.append("ad_type=LD|KB|PVL").append("&");
adparam.append("adaptor=2").append("&");
adparam.append("appversion="+ appVersion).append("&");
adparam.append("chid=0").append("&");
adparam.append("coverid=" + coverid).append("&");
adparam.append("dtype=1").append("&");
adparam.append("flowid=" + flowid).append("&");
adparam.append("from=0").append("&");
adparam.append("guid=" + "d1384f3028935f6465a473a5a07113b5").append("&");
adparam.append("live=0").append("&");
adparam.append("pf=in").append("&");
adparam.append("platform=" + platform).append("&");
adparam.append("pf_ex=pc").append("&");
adparam.append("plugin=1.0.0").append("&");
adparam.append("pt=").append("&");
adparam.append("pu=0").append("&");
adparam.append("refer=" + url).append("&");
adparam.append("req_type=1").append("&");
adparam.append("resp_type=json").append("&");
adparam.append("rfid=" + rfid).append("&");
adparam.append("tpid=1").append("&");
adparam.append("ty=web").append("&");
adparam.append("url=" + url).append("&");
adparam.append("v=" + v).append("&");
adparam.append("vid=" + vid).append("&");
adparam.append("vptag=www_baidu_com");
if(haveCookie) {
String uid = cookieMap.get("vqq_vuserid");
String tkn = cookieMap.get("vqq_vusession");
String opid = cookieMap.get("vqq_openid");
String lt = cookieMap.get("main_login");
String atkn = cookieMap.get("vqq_access_token");
String appid = cookieMap.get("vqq_appid");
adparam.append("&");
adparam.append("uid=" + uid).append("&");
adparam.append("tkn=" + tkn).append("&");
adparam.append("lt=" + lt).append("&");
adparam.append("opid=" + opid).append("&");
adparam.append("atkn=" + atkn).append("&");
adparam.append("appid=" + appid);
}
StringBuffer vinfoparam = new StringBuffer();
vinfoparam.append("appVer=" + v).append("&");
vinfoparam.append("cKey=" + cKey).append("&");
vinfoparam.append("charge=0").append("&");
vinfoparam.append("defaultfmt=auto").append("&");
vinfoparam.append("defn=fhd").append("&");//取值:fhd(蓝光) shd(超清) hd(高清) sd(标清)
vinfoparam.append("defnpayver=1").append("&");
vinfoparam.append("defsrc=1").append("&");
vinfoparam.append("dlver=2").append("&");
vinfoparam.append("drm=32").append("&");
vinfoparam.append("dtype=3").append("&");
vinfoparam.append("ehost=" + url).append("&");
vinfoparam.append("encryptVer=" + encryptVer).append("&");
vinfoparam.append("fhdswitch=0").append("&");
vinfoparam.append("flowid=" + flowid).append("&");
vinfoparam.append("fp2p=1").append("&");
vinfoparam.append("guid=" + "d1384f3028935f6465a473a5a07113b5").append("&");
vinfoparam.append("hdcp=0").append("&");
vinfoparam.append("host=v.qq.com").append("&");
vinfoparam.append("isHLS=1").append("&");
if(haveCookie) {
String uid = cookieMap.get("vqq_vuserid");
String tkn = cookieMap.get("vqq_vusession");
String opid = cookieMap.get("vqq_openid");
String lt = cookieMap.get("main_login");
String atkn = cookieMap.get("vqq_access_token");
String appid = cookieMap.get("vqq_appid");
String logintoken = "{\"main_login\":\""+ lt +"\",\"openid\":\""+ opid +"\",\"appid\":\""+ appid +"\",\"access_token\":\""+atkn+"\",\"vuserid\":\""+uid+"\",\"vusession\":\""+tkn+"\"}";
vinfoparam.append("logintoken=" + URLEncoder.encode(logintoken)).append("&");
}
vinfoparam.append("otype=ojson").append("&");
vinfoparam.append("platform=" + platform).append("&");
vinfoparam.append("refer=v.qq.com").append("&");
vinfoparam.append("sdtfrom=v1010").append("&");
vinfoparam.append("show1080p=1").append("&");
vinfoparam.append("spadseg=1").append("&");
vinfoparam.append("spau=1").append("&");
vinfoparam.append("spaudio=15").append("&");
vinfoparam.append("spgzip=1").append("&");
vinfoparam.append("sphls=2").append("&");
vinfoparam.append("sphttps=1").append("&");
vinfoparam.append("spwm=4").append("&");
vinfoparam.append("tm=" + tm).append("&");
vinfoparam.append("unid=cdbb5f0a6aad11ea981ca042d48ad00a").append("&");
vinfoparam.append("vid=" + vid);
//构造参数时buid可取值
//1.vinfoad(包含视频信息和广告)
//2.onlyvinfo(只包含视频信息)
return "{\"buid\":\"vinfoad\",\"adparam\":\"" + adparam.toString() + "\",\"vinfoparam\":\"" + vinfoparam.toString() + "\"}";
}
HttpResponse requestNoHeader(String url) {
return HttpUtil.createGet(url).execute();
}
}
上边的代码中预留了一个调用 node 服务的地方,这个是一堆加密的玩意儿,需要一个 node 服务,还有一个 wasm 文件
点击此处下载 node 服务的 js 代码以及 wasm 文件
下载好之后直接按照 node 命令启动服务即可
启动之后把 node 服务的 ip 和端口填写在 Java 代码中(49 行左右)
接下来就可以运行 Java 脚本执行获取结果了,最后获取到的是 m3u8 的地址
里边有一些参数是固定的值(unid)(guid)之类的,不要去修改它,代码呢,可能写的比较low,哈哈哈
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于