boolean savetextdata() throws IOException { boolean rc = false; // read html lines one by one and search for java script array of video URLs String sline = ""; while (sline != null) { sline = this.textreader.readLine(); try { if (this.iRecursionCount == 0 && sline.matches("(.*)\"url_encoded_fmt_stream_map\":(.*)")) { rc = true; HashMap<String, String> ssourcecodevideourls = new HashMap<String, String>(); sline = sline.replaceFirst(".*\"url_encoded_fmt_stream_map\": \"", ""); sline = sline.replaceFirst("\".*", ""); sline = sline.replace("%25", "%"); sline = sline.replace("\\u0026", "&"); sline = sline.replace("\\", ""); // by anonymous String[] ssourcecodeyturls = sline.split(","); debugoutput( "ssourcecodeuturls.length: ".concat(Integer.toString(ssourcecodeyturls.length))); String sResolutions = JFCMainClient.isgerman() ? "gefundene Video URL für Auflösung: " : "found video URL for resolution: "; for (String urlString : ssourcecodeyturls) { // assuming rtmpe is used for all resolutions, if found once - end download if (urlString.matches(".*conn=rtmpe.*")) { debugoutput("RTMPE found. cannot download this one!"); output( JFCMainClient.isgerman() ? "Herunterladen des Videos wegen nicht unterstütztem Protokoll (RTMPE) leider nicht möglich!" : "Unable to download video due to unsupported protocol (RTMPE). sry!"); break; } String[] fmtUrlPair = urlString.split("url=http", 2); fmtUrlPair[1] = "url=http" + fmtUrlPair[1] + "&" + fmtUrlPair[0]; // grep itag=xz out and use xy as hash key // 2013-02 itag now has up to 3 digits fmtUrlPair[0] = fmtUrlPair[1].substring( fmtUrlPair[1].indexOf("itag=") + 5, fmtUrlPair[1].indexOf("itag=") + 5 + 1 + (fmtUrlPair[1].matches(".*itag=[0-9]{2}.*") ? 1 : 0) + (fmtUrlPair[1].matches(".*itag=[0-9]{3}.*") ? 1 : 0)); fmtUrlPair[1] = fmtUrlPair[1].replaceFirst("url=http%3A%2F%2F", "http://"); fmtUrlPair[1] = fmtUrlPair[1] .replaceAll("%3F", "?") .replaceAll("%2F", "/") .replaceAll("%3B", ";") .replaceAll("%2C", ",") .replaceAll("%3D", "=") .replaceAll("%26", "&") .replaceAll("%252C", "%2C") .replaceAll("sig=", "signature=") .replaceAll("&s=", "&signature=") .replaceAll("\\?s=", "?signature="); // remove duplicated &itag=xy if (StringUtils.countMatches(fmtUrlPair[1], "itag=") == 2) fmtUrlPair[1] = fmtUrlPair[1].replaceFirst("itag=[0-9]{1,3}", ""); try { ssourcecodevideourls.put(fmtUrlPair[0], fmtUrlPair[1]); // save that URL // debugoutput(String.format( "video url saved with key %s: // %s",fmtUrlPair[0],ssourcecodevideourls.get(fmtUrlPair[0]) )); sResolutions = sResolutions.concat( fmtUrlPair[0].equals("37") ? "1080p mpeg, " : // HD type=video/mp4;+codecs="avc1.64001F,+mp4a.40.2" fmtUrlPair[0].equals("22") ? "720p mpeg, " : // HD type=video/mp4;+codecs="avc1.64001F,+mp4a.40.2" fmtUrlPair[0].equals("84") ? "1080p 3d mpeg, " : // HD 3D type=video/mp4;+codecs="avc1.64001F,+mp4a.40.2" fmtUrlPair[0].equals("35") ? "480p flv, " : // SD type=video/x-flv fmtUrlPair[0].equals("18") ? "360p mpeg, " : // SD type=video/mp4;+codecs="avc1.42001E,+mp4a.40.2" fmtUrlPair[0].equals("34") ? "360p flv, " : // SD type=video/x-flv fmtUrlPair[0].equals("82") ? "360p 3d mpeg, " : // SD 3D // type=video/mp4;+codecs="avc1.42001E,+mp4a.40.2" fmtUrlPair[0].equals("36") ? "240p mpeg 3gpp, " : // LD // type=video/3gpp;+codecs="mp4v.20.3,+mp4a.40.2" fmtUrlPair[0].equals("17") ? "114p mpeg 3gpp, " : // LD // type=video/3gpp;+codecs="mp4v.20.3,+mp4a.40.2" fmtUrlPair[0].equals("46") ? "1080p webm, " : // HD // type=video/webm;+codecs="vp8.0,+vorbis"& fmtUrlPair[0].equals("45") ? "720p webm, " : // HD // type=video/webm;+codecs="vp8.0,+vorbis" fmtUrlPair[0].equals("100") ? "1080p 3d webm, " : // HD 3D // type=video/webm;+codecs="vp8.0,+vorbis"& fmtUrlPair[0].equals("44") ? "480p webm, " : // SD // type=video/webm;+codecs="vp8.0,+vorbis" fmtUrlPair[0].equals("43") ? "360p webm, " : // SD // type=video/webm;+codecs="vp8.0,+vorbis" fmtUrlPair[0].equals( "102") ? "360p 3d webm, " : // SD 3D // type=video/webm;+codecs="vp8.0,+vorbis"& fmtUrlPair[0] .equals( "5") ? "240p flv, " : // LD // type=video/x-flv "unknown resolution! (" .concat( fmtUrlPair[ 0]) .concat( ")")); } catch (java.lang.ArrayIndexOutOfBoundsException aioobe) { } } // for if (JFCMainClient.frame != null) output(sResolutions); debugoutput(sResolutions); int iindex; iindex = 0; this.vNextVideoURL.removeAllElements(); debugoutput( "ssourcecodevideourls.length: " .concat(Integer.toString(ssourcecodevideourls.size()))); // figure out what resolution-button is pressed now and fill list with possible URLs switch (JFCMainClient.getIdlbuttonstate()) { case 4: // HD // try 1080p/720p in selected format first. if it's not available than the other // format will be used if (JFCMainClient.getBmpgbuttonstate()) iindex = addMPEG_HD_Urls(iindex, ssourcecodevideourls); if (JFCMainClient.getBwebmbuttonstate()) iindex = addWBEM_HD_Urls(iindex, ssourcecodevideourls); // there are no FLV HD URLs for now, so at least try mpg,wbem HD then iindex = addMPEG_HD_Urls(iindex, ssourcecodevideourls); iindex = addWBEM_HD_Urls(iindex, ssourcecodevideourls); // $FALL-THROUGH$ case 2: // SD // try to download desired format first, if it's not available we take the other of // same res if (JFCMainClient.getBmpgbuttonstate()) iindex = addMPEG_SD_Urls(iindex, ssourcecodevideourls); if (JFCMainClient.getBwebmbuttonstate()) iindex = addWBEM_SD_Urls(iindex, ssourcecodevideourls); if (JFCMainClient.getBflvbuttonstate()) iindex = addFLV_SD_Urls(iindex, ssourcecodevideourls); iindex = addMPEG_SD_Urls(iindex, ssourcecodevideourls); iindex = addWBEM_SD_Urls(iindex, ssourcecodevideourls); iindex = addFLV_SD_Urls(iindex, ssourcecodevideourls); // $FALL-THROUGH$ case 1: // LD // TODO this.sFilenameResPart = "(LD)"; // adding LD to filename because HD-Videos are // almost already named HD (?) if (JFCMainClient.getBmpgbuttonstate()) iindex = addMPEG_LD_Urls(iindex, ssourcecodevideourls); if (JFCMainClient.getBwebmbuttonstate()) { // there are no wbem LD URLs for now } if (JFCMainClient.getBflvbuttonstate()) iindex = addFLV_LD_Urls(iindex, ssourcecodevideourls); // we must ensure all (16) possible URLs get added to the list so that the list of // URLs is never empty iindex = addMPEG_LD_Urls(iindex, ssourcecodevideourls); iindex = addFLV_LD_Urls(iindex, ssourcecodevideourls); break; default: // this.vNextVideoURL = null; this.sVideoURL = null; break; } // if the first 2 entries are null than there are no URLs for the selected resolution // strictly speaking this is only true for HD as there are only two URLs in contrast to // three of SD - in this case the output will not be shown but downloading should work // anyway if (this.vNextVideoURL.get(0).getsURL() == null && this.vNextVideoURL.get(1).getsURL() == null) { String smsg = JFCMainClient.isgerman() ? "Video URL für ausgewählte Auflösung nicht gefunden! versuche geringere Auflösung..." : "could not find video url for selected resolution! trying lower res..."; output(smsg); debugoutput(smsg); } // remove null entries in list - we later try to download the first (index 0) and if it // fails the next one (at index 1) and so on for (int x = this.vNextVideoURL.size() - 1; x >= 0; x--) { if (this.vNextVideoURL.get(x).getsURL() == null) this.vNextVideoURL.remove(x); } try { this.sVideoURL = this.vNextVideoURL.get(0).getsURL(); debugoutput( String.format( "trying this one: %s %s %s", this.vNextVideoURL.get(0).getsITAG(), this.vNextVideoURL.get(0).getsQUALITY(), this.vNextVideoURL.get(0).getsTYPE())); } catch (ArrayIndexOutOfBoundsException aioobe) { } this.setTitle( this.getTitle() .concat( JFCMainClient.isbSaveIDinFilename() ? "." + this.vNextVideoURL.get(0).getsYTID() : "") .concat( !this.vNextVideoURL.get(0).getsRESPART().equals("") ? "." + this.vNextVideoURL.get(0).getsRESPART() : "")); } if (this.iRecursionCount == 0 && sline.matches("(.*)<meta name=\"title\" content=(.*)")) { String stmp = sline.replaceFirst("(.*)<meta name=\"title\" content=", "").trim(); // change html characters to their UTF8 counterpart stmp = UTF8.changeHTMLtoUTF8(stmp); stmp = stmp.replaceFirst("^\"", "").replaceFirst("\">$", ""); this.setTitle(stmp); // complete file name without path } } catch (NullPointerException npe) { } } // while return rc; } // savetextdata()