package cn.ictgu.parse.video;
import cn.ictgu.dto.Video;
import cn.ictgu.parse.Parser;
import cn.ictgu.serv.model.Episode;
import cn.ictgu.tools.JsoupUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringEscapeUtils;
import org.jsoup.nodes.Document;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 乐视视频解析
* Created by Silence on 2017/1/7.
*/
@Log4j2
public class Letv implements Parser<Video>{
private final static String PROVIDER = "乐视视频";
private final static String cookie = "ark_uuid=d966d5301be94c5bb8fae78b9cd3038e; vjuids=-8a183d9b7.157666171cd.0.43147ea3e2342; OUTFOX_SEARCH_USER_ID_NCOO=410937176.92591244; tj2_lc=c9b56fa67fdcfb1a73c5fa08ac1cb90f; lb_live_c=105; leBlockOrder=8310%2C8526%2C8527%2C8313%2C8314%2C8315%2C8316%2C8317%2C8318%2C8319%2C8320%2C9471%2C8321%2C8322%2C8323%2C8324%2C8325%2C8326%2C8327%2C8328%2C8329%2C8330; _ga=GA1.2.15673798.1487080015; ws_live_c=84; currentLeft_miniPlayer=825; currentTop_miniPlayer=335; his_vid=27931278-27931200-28044388-27853094-27832999-27832992-27832988-27835220-27827468-27678466; m=letv_541bebab7973e32; sso_tk=102XXXY37RkeUCWkYNfggm1qdBtaOGkslkm3McsOlsyhH0Mm1wp8PzW2x3o7NlSxscm1VWgttK1EgwNCBGbb5vN74WkJm21jIVAoc1S52v8qYizuwm3eOGsm4; sso_nickname=1816xxx7640_108; casflag=1; ssouid=67945963; loginname=18164177640; loginnamecookie=18164177640; sso_picture=https%3A%2F%2Fi0.letvimg.com%2Fimg%2F201207%2F30%2Ftx70.png; sso_icon=https%3A%2F%2Fi1.letvimg.com%2Fimg%2F201207%2F30%2Ftx298.png%2Chttps%3A%2F%2Fi0.letvimg.com%2Fimg%2F201207%2F30%2Ftx200.png%2Chttps%3A%2F%2Fi0.letvimg.com%2Fimg%2F201207%2F30%2Ftx70.png%2Chttps%3A%2F%2Fi3.letvimg.com%2Fimg%2F201207%2F30%2Ftx50.png; utype=101; lfrom=www; u=eyJ1aWQiOiI2Nzk0NTk2MyIsIm5pY2tuYW1lIjoiMTgxNnh4eDc2NDBfMTA4IiwiZW1haWwiOiIiLCJuYW1lIjoibGV0dl81NDFiZWJhYjc5NzNlMzIiLCJzc291aWQiOiI2Nzk0NTk2MyJ9; ui=581fizEM5bz6IZHUOuUZzXSd821BxHUKhXBiwCqR98Aji%2BowYKCNmaTcRvcWZ7usBIkzJJMVKrZfYMtHHkcqZZlkbWujmPibe%2BcuMzJWQJ6tGsAN0bp1fcdccUrpybaG6Gl0eUaLEJsAJ6OinRt4wOROZxGTQdqzHvaaSgzkSStxGyyx7TYudOs; IPX_EX_1=1490575896599; ARK_IPX=27.21.127.215X27.21.6.118; IPX_EX_0=1490575896997; vjlast=1474891445.1490575893.11; _search=%E4%B8%89%E7%94%9F%E4%B8%89%E4%B8%96%2C%E6%96%97%E7%A0%B4%E8%8B%8D%E7%A9%B9%2C%E6%96%97%E6%88%98%E8%83%9C%E4%BD%9B%2C%E7%88%B5%E8%BF%B9%2C%E5%85%B0%E9%99%B5%E7%8E%8B%E5%A6%83%2C%E5%98%BF%E5%AD%A9%E5%AD%90; tj_env=1; bd_xid=178D3CF87F892133E76A7BBEB78C903E70564321; csrf=950b2b7fa61d6b3a2c65; sso_curr_country=CN; language=zh-cn; tj_uuid=14906735156053151055; tj_v2c=-28463173_2; logInPlayTime=1; newVideo=%7B%221%22%3A13%2C%222%22%3A95%2C%223%22%3A147%2C%224%22%3A590%2C%225%22%3A25%2C%228%22%3A8%2C%229%22%3A79%2C%2211%22%3A100%2C%2214%22%3A51%2C%2216%22%3A7%2C%2217%22%3A0%2C%2219%22%3A0%2C%2220%22%3A176%2C%2222%22%3A47%2C%2223%22%3A13%2C%2230%22%3A18473%2C%2232%22%3A0%2C%2233%22%3A0%2C%2234%22%3A7%2C%2235%22%3A0%2C%2236%22%3A2%2C%2238%22%3A0%2C%2239%22%3A23%2C%2240%22%3A0%2C%2242%22%3A0%2C%2243%22%3A0%2C%2245%22%3A18%2C%2246%22%3A0%2C%2247%22%3A0%2C%2248%22%3A0%2C%2249%22%3A0%2C%2250%22%3A0%2C%2251%22%3A0%2C%2252%22%3A0%2C%2253%22%3A0%2C%2254%22%3A0%2C%2255%22%3A0%2C%2256%22%3A1%2C%2260%22%3A0%2C%2261%22%3A0%2C%22200%22%3A1%2C%22333%22%3A0%2C%221009%22%3A1522%2C%221021%22%3A129%2C%221029%22%3A53%2C%221035%22%3A0%7D; tj_lc=178D3CF87F892133E76A7BBEB78C903E70564321; lang=zh_cn; geo=CN_17_223_3; fe_uv=1; _starttips1_=1490673526428; autoOpenApp=1";
private final static String ROUTE = "http://player-pc.le.com/mms/out/video/playJson.json?platid=3&splatid=304&tss=no&id=%s&detect=1&dvtype=1300&accessyx=1&domain=www.le.com&tkey=%s&devid=178D3CF87F892133E76A7BBEB78C903E70564321&source=1001&lang=cn®ion=cn&isHttps=0";
private final static String VIP_LOCATION = "%s%s&token=%s&uid=67945963&format=1&jsonp=vjs_149067353337651&expect=3&p1=0&p2=06&termid=2&ostype=macos&hwtype=un&uuid=1891087902108532_1&vid=%s&";
private static final String LETV_VIDEOS = "http://d.api.m.le.com/apipccard/dynamic?cid=2&vid=%s&platform=pc&isvip=1&type=episode,Cotherlist";
private final static String VID_REGEX = "([0-9]+)\\.html";
private final static String[] DIS_LIST = {"1300", "1000", "350"};
@Override
public Video parse(String url) {
final Video video = new Video();
video.setValue(url);
this.initVideo(video);
String vid = this.matchVid(url);
String routeUrl = String.format(ROUTE, vid, getTkey());
Document document = JsoupUtils.getDocWithPhone(routeUrl, cookie);
JSONObject object = JSONObject.parseObject(document.text());
JSONObject playurl = object.getJSONObject("msgs").getJSONObject("playurl");
String title = playurl.getString("title");
video.setTitle(title);
String image = playurl.getString("pic").replace("120_90","360_180");
video.setImage(image);
String domain = playurl.getJSONArray("domain").getString(0);
String dispatch = getDispatch(playurl.getJSONObject("dispatch"));
JSONObject yuanxian = object.getJSONObject("msgs").getJSONObject("yuanxian");
String locationUrl;
if (yuanxian != null){
String token = yuanxian.getString("token");
log.info("token: " + token);
locationUrl = String.format(VIP_LOCATION, domain, dispatch, token, vid);
}else {
locationUrl = String.format(VIP_LOCATION, domain, dispatch, "", vid);
}
log.info(locationUrl);
Document result = JsoupUtils.getDocWithPhone(locationUrl);
String text = StringEscapeUtils.unescapeJava(result.text());
text = text.replace("vjs_149067353337651(","");
text = text.replace(");","");
JSONObject videoJson = JSONObject.parseObject(text);
video.setPlayUrl(videoJson.getJSONArray("nodelist").getJSONObject(0).getString("location"));
return video;
}
private void initVideo(Video video){
video.setProvider(PROVIDER);
video.setParserName("Github");
video.setParser("http://github.com");
video.setType("H5");
}
@Override
public List<Episode> parseEpisodes(String videoUrl) {
List<Episode> episodes = new ArrayList<>();
Document document = JsoupUtils.getDocWithPhone(videoUrl);
Matcher matcher = Pattern.compile("([0-9]{5,})\\.html").matcher(document.html());
if (matcher.find()) {
String vid = matcher.group(1);
String videosAPI = String.format(LETV_VIDEOS, vid);
String data = JsoupUtils.getDocWithPhone(videosAPI).body().text();
JSONObject jsonObject = JSONObject.parseObject(data);
JSONArray array = jsonObject.getJSONObject("data").getJSONObject("episode").getJSONArray("videolist");
if (array.size()>1){
for (int i = array.size() - 1; i >= 0; i--) {
JSONObject object = array.getJSONObject(i);
Episode episode = new Episode();
Integer index = object.getInteger("episode");
if (index < 10) {
episode.setIndex("0" + index);
} else {
episode.setIndex("" + index);
}
episode.setValue(object.getString("url"));
episodes.add(episode);
}
}
}
return episodes;
}
private String matchVid(String videoUrl){
Matcher matcher = Pattern.compile(VID_REGEX).matcher(videoUrl);
if (matcher.find()){
return matcher.group(1);
}else {
Document realDocument = JsoupUtils.getDocWithPC(videoUrl);
matcher = Pattern.compile("vid:\"(.*?)\"").matcher(realDocument.html());
if (matcher.find())
return matcher.group(1);
}
return "";
}
/* 获取最清晰的视频线路 */
private String getDispatch(JSONObject dispatch){
for (String dis : DIS_LIST){
if (dispatch.containsKey(dis)){
return dispatch.getJSONArray(dis).getString(0);
}
}
return null;
}
/* 乐视tkey算法 */
private static String getTkey() {
int a = (int) (new Date().getTime() / 1000);
for (int i = 0; i < 8; i++) {
int b = a >> 1;
int c = (0x1 & a) << 31;
a = b + c;
}
int result = 0xB074319 ^ a;
return "" + result;
}
}