diff -ur mediatomb/src/youtube_video_url.cc mediatomb-0.12.1/src/youtube_video_url.cc
--- mediatomb/src/youtube_video_url.cc 2010-12-24 15:40:11.917173541 +1000
+++ mediatomb-0.12.1/src/youtube_video_url.cc 2010-12-24 15:32:38.265167072 +1000
@@ -47,11 +47,11 @@
#define YOUTUBE_URL_PARAMS_REGEXP "var swfHTML.*\\;"
#define YOUTUBE_URL_LOCATION_REGEXP "\nLocation: (http://[^\n]+)\n"
#define YOUTUBE_URL_WATCH "http://www.youtube.com/watch?v="
-#define YOUTUBE_URL_GET "http://www.youtube.com/get_video?"
#define YOUTUBE_URL_PARAM_VIDEO_ID "video_id"
-#define YOUTUBE_URL_PARAM_T_REGEXP ".*&t=([^&]+)&"
-#define YOUTUBE_URL_PARAM_T "t"
+#define YOUTUBE_URL_PARAM_FMT_REGEXP ".*&fmt_url_map=([^&]+)&"
+#define YOUTUBE_URL_PARAM_FMT "fmt_url_map"
#define YOUTUBE_IS_HD_AVAILABLE_REGEXP "IS_HD_AVAILABLE[^:]*: *([^,]*)"
+
YouTubeVideoURL::YouTubeVideoURL()
{
curl_handle = curl_easy_init();
@@ -62,8 +62,9 @@
reVideoURLParams->compile(_(YOUTUBE_URL_PARAMS_REGEXP));
redirectLocation = Ref<RExp>(new RExp());
redirectLocation->compile(_(YOUTUBE_URL_LOCATION_REGEXP));
- param_t = Ref<RExp>(new RExp());
- param_t->compile(_(YOUTUBE_URL_PARAM_T_REGEXP));
+
+ FMT = Ref<RExp>(new RExp());
+ FMT->compile(_(YOUTUBE_URL_PARAM_FMT_REGEXP));
HD = Ref<RExp>(new RExp());
HD->compile(_(YOUTUBE_IS_HD_AVAILABLE_REGEXP));
@@ -82,7 +83,12 @@
String YouTubeVideoURL::getVideoURL(String video_id, bool mp4, bool hd)
{
- long retcode;
+ Ref<StringBuffer> buffer;
+ Ref<Matcher> matcher;
+
+ long retcode;
+ String params;
+ String urls;
String flv_location;
String watch;
#ifdef TOMBDEBUG
@@ -91,112 +97,50 @@
bool verbose = false;
#endif
- /*
-// ###########################################################
-
- String swfargs = read_text_file("/home/jin/Work/UPnP/MediaTomb/YouTube/swf_args_new2.txt");
-
- Ref<Matcher> m2 = param_t->matcher(swfargs);
-
- if (m2->next())
- {
- String hmm = m2->group(1);
- if (string_ok(hmm))
- log_debug("############### t: %s\n", hmm.c_str());
- else
- log_debug("no match?\n");
- }
- throw _Exception(_("OVER"));
-*/
-
-// ###########################################################
-
-
if (!string_ok(video_id))
throw _Exception(_("No video ID specified!"));
watch = _(YOUTUBE_URL_WATCH) + video_id;
-
Ref<URL> url(new URL(YOUTUBE_PAGESIZE));
- Ref<StringBuffer> buffer = url->download(watch, &retcode, curl_handle,
- false, verbose, true);
- if (retcode != 200)
- {
- throw _Exception(_("Failed to get URL for video with id ")
- + watch + _("HTTP response code: ") +
- String::from(retcode));
- }
-
- log_debug("------> GOT BUFFER %s\n", buffer->toString().c_str());
-
- Ref<Matcher> matcher = reVideoURLParams->matcher(buffer->toString());
- String params;
- if (matcher->next())
- {
-// params = trim_string(matcher->group(1));
- params = trim_string( matcher->group( 0 ) );
- /*
- int brace = params.index( '{' );
- if ( brace > 0 )
- params = params.substring( brace );
- brace = params.index( '}' );
- if ( brace > 0 )
- params = params.substring( 0, brace + 1 );
- */
- Ref<Matcher> m2 = param_t->matcher(params);
- if (m2->next())
- {
- String hmm = m2->group(1);
- if (string_ok(hmm))
- params = hmm;
- else
- {
- throw _Exception(_("Could not retrieve \"t\" parameter."));
- }
- }
+ buffer = url->download(watch, &retcode, curl_handle, false, verbose, false);
+ if(retcode != 200)
+ throw _Exception(_("Failed to get URL for video with id ") + watch + _("HTTP response code: ") + String::from(retcode));
+
+ log_debug("------> REQUEST URL1: %s\n", watch.c_str());
+ log_debug("------> GOT BUFFER1: %s\n", buffer->toString().c_str());
+
+ matcher = FMT->matcher(buffer->toString());
+ if(matcher->next())
+ {
+ urls = url_unescape(trim_string(matcher->group(1)).c_str());
+ log_debug("------> GOT BUFFER2: %s\n", params.c_str());
+ return whichURL(urls, mp4, hd);
}
- else
- {
- throw _Exception(_("Failed to get URL for video with id (step 1)") + video_id);
- }
-
- params = _(YOUTUBE_URL_GET) + YOUTUBE_URL_PARAM_VIDEO_ID + '=' +
- video_id + '&' + YOUTUBE_URL_PARAM_T + '=' + params;
- if (mp4)
- {
- String format = _("&fmt=18");
-
- if (hd)
- {
- matcher = HD->matcher(buffer->toString());
- if (matcher->next())
- {
- if (trim_string(matcher->group(1)) == "true")
- format = _("&fmt=22");
- }
- }
-
- params = params + format;
- }
-
- buffer = url->download(params, &retcode, curl_handle, true, verbose, true);
-
- matcher = redirectLocation->matcher(buffer->toString());
- if (matcher->next())
- {
- if (string_ok(trim_string(matcher->group(1))))
- return trim_string(matcher->group(1));
- else
- throw _Exception(_("Failed to get URL for video with id (step 2)")+
- video_id);
- }
+ throw _Exception(_("Could not retrieve YouTube video URL"));
+}
- if (retcode != 303)
+String YouTubeVideoURL::whichURL(String tmpStr, bool mp4, bool hd)
+{
+ while(tmpStr.find(",") > 0)
{
- throw _Exception(_("Unexpected reply from YouTube: ") +
- String::from(retcode));
+ String fmturl = tmpStr.substring(0, tmpStr.find(","));
+ tmpStr = tmpStr.substring(tmpStr.find(",") + 1);
+ if(fmturl.find("|") <= 0)
+ continue;
+
+ int fmt = atoi(fmturl.substring(0, fmturl.find("|")).c_str());
+ fmturl = fmturl.substring(fmturl.find("|") + 1);
+
+ log_debug("------> GOT BUFFER3: %d -- %s\n", fmt, fmturl.c_str());
+
+ if(hd && fmt == 22)
+ return fmturl;
+ if((hd || mp4) && fmt == 18)
+ return fmturl;
+ if(fmt == 5)
+ return fmturl;
}
throw _Exception(_("Could not retrieve YouTube video URL"));
diff -ur mediatomb/src/youtube_video_url.h mediatomb-0.12.1/src/youtube_video_url.h
--- mediatomb/src/youtube_video_url.h 2010-12-24 15:40:11.905172760 +1000
+++ mediatomb-0.12.1/src/youtube_video_url.h 2010-12-24 15:11:27.146641639 +1000
@@ -57,6 +57,7 @@
/// available
/// \return the url to the .flv or .mp4 file
zmm::String getVideoURL(zmm::String video_id, bool mp4, bool hd);
+ zmm::String whichURL(zmm::String tmpStr, bool mp4, bool hd);
protected:
// the handle *must never be used from multiple threads*
@@ -64,7 +65,8 @@
pthread_t pid;
zmm::Ref<RExp> reVideoURLParams;
zmm::Ref<RExp> redirectLocation;
- zmm::Ref<RExp> param_t;
+ zmm::Ref<RExp> param_fmt;
+ zmm::Ref<RExp> FMT;
zmm::Ref<RExp> HD;
};