Changeset 156 for smplayer/trunk/src/youtube/retrieveyoutubeurl.cpp
- Timestamp:
- Feb 21, 2014, 5:26:03 PM (11 years ago)
- Location:
- smplayer/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
smplayer/trunk
- Property svn:mergeinfo changed
/smplayer/vendor/current merged: 154
- Property svn:mergeinfo changed
-
smplayer/trunk/src/youtube/retrieveyoutubeurl.cpp
r142 r156 20 20 #include "retrieveyoutubeurl.h" 21 21 #include <QUrl> 22 23 RetrieveYoutubeUrl::RetrieveYoutubeUrl( QObject* parent ) : SimpleHttp(parent) 22 #include <QRegExp> 23 #include <QStringList> 24 #include <QFile> 25 #include "ytsig.h" 26 27 RetrieveYoutubeUrl::RetrieveYoutubeUrl( QObject* parent ) : QObject(parent) 24 28 { 25 connect(this, SIGNAL(downloadFinished(QByteArray)), 26 this, SLOT(parse(QByteArray))); 29 reply = 0; 30 manager = new QNetworkAccessManager(this); 31 connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(gotResponse(QNetworkReply*))); 27 32 28 33 preferred_quality = FLV_360p; 34 user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:5.0.1) Gecko/20100101 Firefox/5.0.1"; 29 35 } 30 36 … … 33 39 34 40 void RetrieveYoutubeUrl::fetchPage(const QString & url) { 35 download(url); 41 QNetworkRequest req(url); 42 req.setRawHeader("User-Agent", user_agent.toLatin1()); 43 reply = manager->get(req); 36 44 orig_url = url; 45 46 emit connecting(url); 47 } 48 49 void RetrieveYoutubeUrl::close() { 50 if (reply) reply->abort(); 51 } 52 53 void RetrieveYoutubeUrl::gotResponse(QNetworkReply* reply) { 54 if (reply->error() == QNetworkReply::NoError) { 55 int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); 56 qDebug("RetrieveYoutubeUrl::gotResponse: status: %d", status); 57 switch (status) { 58 case 301: 59 case 302: 60 case 307: 61 QString r_url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl().toString(); 62 qDebug("RetrieveYoutubeUrl::gotResponse: redirected: %s", r_url.toLatin1().constData()); 63 fetchPage(r_url); 64 return; 65 } 66 } else { 67 emit errorOcurred((int)reply->error(), reply->errorString()); 68 return; 69 } 70 parse(reply->readAll()); 37 71 } 38 72 … … 42 76 urlMap.clear(); 43 77 44 QString replyString = QString::fromUtf8(text.constData(), text.size());78 QString replyString = QString::fromUtf8(text); 45 79 46 80 QRegExp rx_title(".*<title>(.*)</title>.*"); … … 53 87 } 54 88 55 QRegExp regex("\\\"url_encoded_fmt_stream_map\\\"\\s*:\\s*\\\"([^\\\"]*)"); 56 regex.indexIn(replyString); 57 QString fmtArray = regex.cap(1); 58 fmtArray = sanitizeForUnicodePoint(fmtArray); 59 fmtArray.replace(QRegExp("\\\\(.)"), "\\1"); 60 htmlDecode(fmtArray); 61 QStringList codeList = fmtArray.split(','); 62 foreach(QString code, codeList) 63 { 64 // (2012-12-20) Youtube Fix by RVM for SMPlayer (http://smplayer.sourceforge.net) 65 66 /* qDebug("RetrieveYoutubeUrl::parse: code: '%s'", code.toLatin1().constData()); */ 67 68 int itag = 0; 69 QString n_url; 70 QString url; 71 QString s_itag; 72 73 QStringList par_list = code.split(QRegExp("&|\\?")); 74 foreach(QString par, par_list) { 75 /* qDebug("RetrieveYoutubeUrl::parse: par: %s", par.toLatin1().constData()); */ 76 77 if (par.startsWith("url=")) url = par.mid(4); 89 QRegExp regex("\\\"url_encoded_fmt_stream_map\\\"\\s*:\\s*\\\"([^\\\"]*)"); 90 regex.indexIn(replyString); 91 QString fmtArray = regex.cap(1); 92 fmtArray = sanitizeForUnicodePoint(fmtArray); 93 fmtArray.replace(QRegExp("\\\\(.)"), "\\1"); 94 95 bool signature_not_found = false; 96 97 QList<QByteArray> codeList = fmtArray.toLatin1().split(','); 98 foreach(QByteArray code, codeList) { 99 code = QUrl::fromPercentEncoding(code).toLatin1(); 100 //qDebug("code: %s", code.constData()); 101 102 QUrl line; 103 line.setEncodedQuery(code); 104 105 if (line.hasQueryItem("url")) { 106 QUrl url( line.queryItemValue("url") ); 107 line.setScheme(url.scheme()); 108 line.setHost(url.host()); 109 line.setPath(url.path()); 110 line.setEncodedQuery( line.encodedQuery() + "&" + url.encodedQuery() ); 111 line.removeQueryItem("url"); 112 113 if (line.hasQueryItem("sig")) { 114 line.addQueryItem("signature", line.queryItemValue("sig")); 115 line.removeQueryItem("sig"); 116 } 78 117 else 79 if ( par.startsWith("itag=")) {80 if (s_itag.isEmpty()) {81 s_itag = par;82 QRegExp rx("itag=(\\d+)");83 if (rx.indexIn(s_itag) != -1) itag = rx.cap(1).toInt();84 /* qDebug("RetrieveYoutubeUrl::parse: itag: %d", itag); */118 if (line.hasQueryItem("s")) { 119 QString signature = YTSig::aclara(line.queryItemValue("s")); 120 if (!signature.isEmpty()) { 121 line.addQueryItem("signature", signature); 122 } else { 123 signature_not_found = true; 85 124 } 125 line.removeQueryItem("s"); 86 126 } 87 else { 88 if (!n_url.isEmpty()) n_url += "&"; 89 n_url += par; 127 line.removeAllQueryItems("fallback_host"); 128 line.removeAllQueryItems("type"); 129 if ((line.hasQueryItem("itag")) && (line.hasQueryItem("signature"))) { 130 QString itag = line.queryItemValue("itag"); 131 line.removeAllQueryItems("itag"); // Remove duplicated itag 132 line.addQueryItem("itag", itag); 133 urlMap[itag.toInt()] = line.toString(); 134 //qDebug("line: %s", line.toString().toLatin1().constData()); 90 135 } 91 136 } 92 n_url = url + "?" + s_itag + "&" + n_url; 93 n_url.replace("&sig=", "&signature="); 94 95 /* qDebug("RetrieveYoutubeUrl::parse: n_url: '%s'", n_url.toLatin1().constData()); */ 96 97 urlMap[itag] = n_url; 98 } 137 } 99 138 100 139 qDebug("RetrieveYoutubeUrl::parse: url count: %d", urlMap.count()); 101 140 141 if ((urlMap.count() == 0) && (signature_not_found)) { 142 qDebug("RetrieveYoutubeUrl::parse: no url found with valid signature"); 143 emit signatureNotFound(url_title); 144 return; 145 } 146 102 147 QString p_url = findPreferredUrl(); 148 //qDebug("p_url: '%s'", p_url.toLatin1().constData()); 149 103 150 if (!p_url.isNull()) { 104 151 emit gotUrls(urlMap); … … 179 226 } 180 227 181 QString RetrieveYoutubeUrl::sanitizeForUnicodePoint(QString string) 182 { 183 QRegExp rx("\\\\u(\\d{4})"); 184 while (rx.indexIn(string) != -1) { 185 string.replace(rx.cap(0), QString(QChar(rx.cap(1).toInt(0,16)))); 186 } 187 return string; 188 } 189 190 void RetrieveYoutubeUrl::htmlDecode(QString& string) 191 { 192 string.replace("%3A", ":", Qt::CaseInsensitive); 193 string.replace("%2F", "/", Qt::CaseInsensitive); 194 string.replace("%3F", "?", Qt::CaseInsensitive); 195 string.replace("%3D", "=", Qt::CaseInsensitive); 196 string.replace("%25", "%", Qt::CaseInsensitive); 197 string.replace("%26", "&", Qt::CaseInsensitive); 198 string.replace("%3D", "=", Qt::CaseInsensitive); 228 QString RetrieveYoutubeUrl::sanitizeForUnicodePoint(QString string) { 229 QRegExp rx("\\\\u(\\d{4})"); 230 while (rx.indexIn(string) != -1) { 231 string.replace(rx.cap(0), QString(QChar(rx.cap(1).toInt(0,16)))); 232 } 233 return string; 234 } 235 236 void RetrieveYoutubeUrl::htmlDecode(QString& string) { 237 string.replace("%3A", ":", Qt::CaseInsensitive); 238 string.replace("%2F", "/", Qt::CaseInsensitive); 239 string.replace("%3F", "?", Qt::CaseInsensitive); 240 string.replace("%3D", "=", Qt::CaseInsensitive); 241 string.replace("%25", "%", Qt::CaseInsensitive); 242 string.replace("%26", "&", Qt::CaseInsensitive); 243 string.replace("%3D", "=", Qt::CaseInsensitive); 199 244 } 200 245
Note:
See TracChangeset
for help on using the changeset viewer.