You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
8.4 KiB
206 lines
8.4 KiB
--- trunk/resources/services/youtube/youtube.js 2010/09/02 11:52:07 911
|
|
+++ trunk/resources/services/youtube/youtube.js 2012/05/08 17:34:53 975
|
|
@@ -3,7 +3,7 @@
|
|
* This file is part of xVideoServiceThief,
|
|
* an open-source cross-platform Video service download
|
|
*
|
|
-* Copyright (C) 2007 - 2010 Xesc & Technology
|
|
+* Copyright (C) 2007 - 2012 Xesc & Technology
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
@@ -25,9 +25,9 @@
|
|
|
|
function RegistVideoService()
|
|
{
|
|
- this.version = "2.1.5";
|
|
+ this.version = "3.0.6";
|
|
this.minVersion = "2.0.0a";
|
|
- this.author = "Xesc & Technology 2009";
|
|
+ this.author = "Xesc & Technology 2012";
|
|
this.website = "http://www.youtube.com/";
|
|
this.ID = "youtube.com";
|
|
this.caption = "YouTube";
|
|
@@ -38,7 +38,6 @@
|
|
function getVideoInformation(url)
|
|
{
|
|
const URL_YOUTBE = "http://www.youtube.com/watch?v=%1";
|
|
- const HD_VIDEO_RES = "22";
|
|
// init result
|
|
var result = new VideoDefinition();
|
|
// default URL
|
|
@@ -52,35 +51,112 @@
|
|
embededID = strRemove(embededID, 0, embededID.lastIndexOf("/v/") + 3);
|
|
youTubeURL = strFormat(URL_YOUTBE, embededID);
|
|
}
|
|
+ // cehck if is an embeded video (v2)
|
|
+ else if (youTubeURL.toString().indexOf("/embed/") != -1)
|
|
+ {
|
|
+ var embededID = copyBetween(youTubeURL + "?", "/embed/", "?");
|
|
+ youTubeURL = strFormat(URL_YOUTBE, embededID);
|
|
+ }
|
|
// download webpage
|
|
var http = new Http();
|
|
var html = http.downloadWebpage(youTubeURL);
|
|
+ // get cookies
|
|
+ result.cookies = http.getCookies("|");
|
|
// get the video title
|
|
result.title = copyBetween(html, "<title>", "</title>");
|
|
result.title = normalizeSpaces(result.title);
|
|
+ result.title = strReplace(result.title, "\n", "");
|
|
+ result.title = strReplace(result.title, " - YouTube", "");
|
|
// check if this video need a login
|
|
- result.needLogin = result.title == "Broadcast Yourself.";
|
|
+ result.needLogin = strIndexOf(html, 'id="verify-details"') != -1;
|
|
// if we can continue (no loggin needed)
|
|
if (result.needLogin) return result;
|
|
- // get the video info block
|
|
- var dirtyUrl = copyBetween(html, "fmt_stream_map=", "34%7Chttp");
|
|
- // we have an empty "dirtyUrl"?? if yes then we give it a second try
|
|
- if (dirtyUrl == "") dirtyUrl = copyBetween(html, "fmt_url_map=", "&") + "&";
|
|
- // get the video resolution
|
|
- var vidRes = getToken(dirtyUrl, "%7C", 0);
|
|
- // check if is a HD_VIDEO_RES (for HD videos the extension is mp4)
|
|
- if (vidRes == HD_VIDEO_RES) result.extension = ".mp4";
|
|
- // get the video url
|
|
- result.URL = getToken(dirtyUrl, "%7C", 1);
|
|
- // convert the hex codes to ascii
|
|
- result.URL = cleanUrl(result.URL);
|
|
- // remove the last "," and replace it with an "&" (if is needed)
|
|
- if (strLastIndexOf(result.URL, "&") < strLastIndexOf(result.URL, ","))
|
|
- result.URL = strRemove(result.URL, strLastIndexOf(result.URL, ","), result.URL.toString().length) + "&";
|
|
+ // get the video URL and extension
|
|
+ var videoInfo = getVideoUrlAndExtension(html);
|
|
+ result.URL = videoInfo.url;
|
|
+ result.extension = videoInfo.extension;
|
|
// return the video information
|
|
return result;
|
|
}
|
|
|
|
+function getVideoUrlAndExtension(html)
|
|
+{
|
|
+ // init result
|
|
+ var result = { url:null, extension:null };
|
|
+ // get the flashVars value
|
|
+ var flashVars = "?" + copyBetween(html, 'flashvars=\\"', '\\"');
|
|
+ // convert each "&" into "&"
|
|
+ flashVars = strReplace(flashVars, "\\u0026amp;", "&");
|
|
+ // get an array with all fmt_stream_map values
|
|
+ var fmt_stream_map_arr = splitString(getUrlParam(flashVars, "url_encoded_fmt_stream_map"), "url%3D", false);
|
|
+ // default selected video quality
|
|
+ var selectedFormat = -1;
|
|
+ // detect the better quality
|
|
+ for (var n = 0; n < fmt_stream_map_arr.length && selectedFormat == -1; n++)
|
|
+ {
|
|
+ fmt_stream_map_arr[n] = "?url=" + cleanUrl(fmt_stream_map_arr[n]).toString();
|
|
+ // remove the last "," (if exists)
|
|
+ if (strLastIndexOf(fmt_stream_map_arr[n], ",") == fmt_stream_map_arr[n].toString().length - 1)
|
|
+ fmt_stream_map_arr[n] = strRemove(fmt_stream_map_arr[n], fmt_stream_map_arr[n].toString().length - 1, 1);
|
|
+ // check video type
|
|
+ var vtype = getToken(getUrlParam(fmt_stream_map_arr[n], "type"), ";", 0);
|
|
+ // is known format?
|
|
+ if (vtype == "video/x-flv" || vtype == "video/mp4")
|
|
+ {
|
|
+ selectedFormat = n;
|
|
+ // configure video extension
|
|
+ result.extension = extensionFromVideoType(vtype);
|
|
+ }
|
|
+ }
|
|
+ // no format selected?
|
|
+ if (selectedFormat == -1) selectedFormat = 0;
|
|
+ // get the host url
|
|
+ var urlHost = getToken(fmt_stream_map_arr[selectedFormat], "?", 1);
|
|
+ urlHost = strReplace(urlHost, "url=", "");
|
|
+ // leave only the parameters
|
|
+ fmt_stream_map_arr[selectedFormat] = getToken(fmt_stream_map_arr[selectedFormat], "?", 2);
|
|
+ // get url parts
|
|
+ var urlParts = splitString(fmt_stream_map_arr[selectedFormat], "&", false);
|
|
+ // set the url host
|
|
+ result.url = urlHost + "?";
|
|
+ // build the initial url
|
|
+ for (var n = 0; n < urlParts.length; n++)
|
|
+ {
|
|
+ var pname = getToken(urlParts[n], "=", 0).toString();
|
|
+ var pvalue = getToken(urlParts[n], "=", 1).toString();
|
|
+ var duplicatedPname = strIndexOf(result.url, pname + "=") != -1;
|
|
+ // is an excluded param?
|
|
+ if (!duplicatedPname && pname != "fexp" && pname != "quality" && pname != "fallback_host" && pname != "type")
|
|
+ result.url += pname + "=" + pvalue + "&";
|
|
+ }
|
|
+ // remove the last &
|
|
+ if (strLastIndexOf(result.url, "&") == result.url.length - 1)
|
|
+ urlInitial = strRemove(result.url, result.url.length - 1, 1);
|
|
+ // get extra (optional) params
|
|
+ var ptchn = getUrlParam(flashVars, "ptchn");
|
|
+ if (ptchn != "") result.url += "ptchn=" + ptchn + "&";
|
|
+ var ptk = getUrlParam(flashVars, "ptk");
|
|
+ if (ptk != "") result.url += "ptk=" + ptk;
|
|
+ // configure the video extension (if is not yet configured)
|
|
+ if (!result.extension)
|
|
+ {
|
|
+ var vtype = getToken(getUrlParam(fmt_stream_map_arr[selectedFormat], "type"), ";", 0);
|
|
+ // configure video extension
|
|
+ result.extension = extensionFromVideoType(vtype);
|
|
+ }
|
|
+ // return
|
|
+ return result;
|
|
+}
|
|
+
|
|
+function extensionFromVideoType(vtype)
|
|
+{
|
|
+ if (vtype == "video/x-flv") return ".flv";
|
|
+ if (vtype == "video/mp4") return ".mp4";
|
|
+ if (vtype == "video/webm") return ".webm";
|
|
+ // default extension
|
|
+ return ".flv";
|
|
+}
|
|
+
|
|
/*
|
|
This function "normalizeSpaces(str)" will be deprecated on next xVST version
|
|
and replaced with the new "simplifyString(str)" function (added in xVST 2.3.1)
|
|
@@ -99,9 +175,11 @@
|
|
function searchVideos(keyWord, pageIndex)
|
|
{
|
|
const URL_SEARCH = "http://www.youtube.com/results?search_query=%1&page=%2&hl=%3";
|
|
- const HTML_SEARCH_START = "<!-- start search results -->";
|
|
- const HTML_SEARCH_FINISH = "<!-- end search results -->";
|
|
- const HTML_SEARCH_SEPARATOR = '<div class="video-entry">';
|
|
+ const HTML_SEARCH_START = '<div id="search-results">';
|
|
+ const HTML_SEARCH_FINISH = '<div id="search-pva-content">';
|
|
+ const HTML_SEARCH_SEPARATOR = '<div class="thumb-container">';
|
|
+ const HTML_SEARCH_SUMMARY_START = '<p class="num-results">';
|
|
+ const HTML_SEARCH_SUMMARY_END = '</p>';
|
|
// replace all spaces for "+"
|
|
keyWord = strReplace(keyWord, " ", "+");
|
|
// init search results object
|
|
@@ -110,7 +188,7 @@
|
|
var http = new Http();
|
|
var html = http.downloadWebpage(strFormat(URL_SEARCH, keyWord, pageIndex, searchResults.getUserLanguage()));
|
|
// get the search summary
|
|
- var summary = copyBetween(html, '<div id="search-num-results" class="name">', '</div>');
|
|
+ var summary = copyBetween(html, HTML_SEARCH_SUMMARY_START, HTML_SEARCH_SUMMARY_END);
|
|
searchResults.setSummary(cleanSummary(summary));
|
|
// get results html block
|
|
var htmlResults = copyBetween(html, HTML_SEARCH_START, HTML_SEARCH_FINISH);
|
|
@@ -148,14 +226,17 @@
|
|
var tmp, videoUrl, imageUrl, title, description, duration, rating;
|
|
// get video url
|
|
videoUrl = VIDEO_URL + copyBetween(html, 'href="', '"');
|
|
- // get title and image url
|
|
+ // get image url
|
|
tmp = copyBetween(html, '<img', '>') ;
|
|
- title = copyBetween(tmp, 'title="', '"');
|
|
imageUrl = copyBetween(tmp, 'src="', '"');
|
|
if (strIndexOf(imageUrl, "default.jpg") == -1) // if is not a "default.jpg"...
|
|
imageUrl = copyBetween(tmp, 'thumb="', '"');
|
|
+ imageUrl = "http:" + imageUrl;
|
|
+ // get video title
|
|
+ title = copyBetween(html, 'dir="ltr" title="', '"');
|
|
// get video description
|
|
- description = copyBetween(html, 'class="video-description">', '</div>');
|
|
+ description = copyBetween(html, '<p id="video-description-', '</p>');
|
|
+ description = copyBetween(description + '|', '>', '|');
|
|
// get video duration
|
|
duration = convertToSeconds(copyBetween(html, '<span class="video-time">', '</span>'));
|
|
// get rating
|