private HashMap<Integer, String> parseLinks(String html5_fmt_map, YouTubeSig ytSig) { final HashMap<Integer, String> links = new HashMap<Integer, String>(); if (html5_fmt_map != null) { if (html5_fmt_map.contains(UNSUPPORTEDRTMP)) { return links; } String[] html5_hits = new Regex(html5_fmt_map, "(.*?)(,|$)").getColumn(0); if (html5_hits != null) { for (String hit : html5_hits) { hit = unescape(hit); String hitUrl = new Regex(hit, "url=(http.*?)(\\&|$)").getMatch(0); String sig = new Regex(hit, "url=http.*?(\\&|$)(sig|signature)=(.*?)(\\&|$)").getMatch(2); if (sig == null) sig = new Regex(hit, "(sig|signature)=(.*?)(\\&|$)").getMatch(1); if (sig == null) sig = new Regex(hit, "(sig|signature)%3D(.*?)%26").getMatch(1); if (sig == null) { String temp = new Regex(hit, "(\\&|^)s=(.*?)(\\&|$)").getMatch(1); sig = ytSig != null && temp != null ? ytSig.calc(temp) : null; } String hitFmt = new Regex(hit, "itag=(\\d+)").getMatch(0); if (hitUrl != null && hitFmt != null) { hitUrl = unescape(hitUrl.replaceAll("\\\\/", "/")); if (hitUrl.startsWith("http%253A")) { hitUrl = Encoding.htmlDecode(hitUrl); } String inst = null; if (hitUrl.contains("sig")) { inst = Encoding.htmlDecode(Encoding.urlDecode(hitUrl, true)); } else { inst = Encoding.htmlDecode(Encoding.urlDecode(hitUrl, true) + "&signature=" + sig); } links.put(Integer.parseInt(hitFmt), inst); } } } } return links; }
private List<LinkInfo> extractLinksFromDashManifest( String dashManifestUrl, YouTubeSig ytSig, String filename, Date date, String videoId, String userName, String channelName, ThumbnailLinks thumbnailLinks) throws IOException, ParserConfigurationException, SAXException { dashManifestUrl = dashManifestUrl.replace("\\/", "/"); Pattern p = Pattern.compile("/s/([a-fA-F0-9\\.]+)/"); Matcher m = p.matcher(dashManifestUrl); if (m.find()) { String sig = m.group(1); String signature = ytSig.calc(sig); dashManifestUrl = dashManifestUrl.replaceAll("/s/([a-fA-F0-9\\.]+)/", "/signature/" + signature + "/"); } else if (dashManifestUrl.contains("/signature/")) { // dashManifestUrl as it is, empty block to review } else { return Collections.emptyList(); } HttpClient httpClient = HttpClientFactory.getInstance(HttpClientFactory.HttpContext.SEARCH); String dashDoc = httpClient.get(dashManifestUrl); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new InputSource(new StringReader(dashDoc))); NodeList nodes = doc.getElementsByTagName("BaseURL"); List<LinkInfo> infos = new ArrayList<LinkInfo>(); for (int i = 0; i < nodes.getLength(); i++) { Node item = nodes.item(i); String url = item.getTextContent(); int contentLength = -1; try { contentLength = Integer.parseInt(item.getAttributes().item(0).getTextContent()); } catch (Throwable e) { // ignore } int fmt = Integer.parseInt(new Regex(url, "itag=(\\d+)").getMatch(0)); Format format = FORMATS.get(fmt); if (format == null) { continue; } LinkInfo info = new LinkInfo( url, fmt, filename, contentLength, date, videoId, userName, channelName, thumbnailLinks, format); infos.add(info); } return infos; }