Ignore:
Timestamp:
Feb 21, 2014, 5:26:03 PM (11 years ago)
Author:
Silvan Scherrer
Message:

SMPlayer: update trunk to 0.8.6

Location:
smplayer/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • smplayer/trunk

  • smplayer/trunk/src/youtube/retrieveyoutubeurl.cpp

    r142 r156  
    2020#include "retrieveyoutubeurl.h"
    2121#include <QUrl>
    22 
    23 RetrieveYoutubeUrl::RetrieveYoutubeUrl( QObject* parent ) : SimpleHttp(parent)
     22#include <QRegExp>
     23#include <QStringList>
     24#include <QFile>
     25#include "ytsig.h"
     26
     27RetrieveYoutubeUrl::RetrieveYoutubeUrl( QObject* parent ) : QObject(parent)
    2428{
    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*)));
    2732
    2833        preferred_quality = FLV_360p;
     34        user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:5.0.1) Gecko/20100101 Firefox/5.0.1";
    2935}
    3036
     
    3339
    3440void 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);
    3644        orig_url = url;
     45
     46        emit connecting(url);
     47}
     48
     49void RetrieveYoutubeUrl::close() {
     50        if (reply) reply->abort();
     51}
     52
     53void 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());
    3771}
    3872
     
    4276        urlMap.clear();
    4377
    44     QString replyString = QString::fromUtf8(text.constData(), text.size());
     78        QString replyString = QString::fromUtf8(text);
    4579
    4680        QRegExp rx_title(".*<title>(.*)</title>.*");
     
    5387        }
    5488
    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                        }
    78117                        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;
    85124                                }
     125                                line.removeQueryItem("s");
    86126                        }
    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());
    90135                        }
    91136                }
    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        }
    99138
    100139        qDebug("RetrieveYoutubeUrl::parse: url count: %d", urlMap.count());
    101140
     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
    102147        QString p_url = findPreferredUrl();
     148        //qDebug("p_url: '%s'", p_url.toLatin1().constData());
     149
    103150        if (!p_url.isNull()) {
    104151                emit gotUrls(urlMap);
     
    179226}
    180227
    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);
     228QString 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
     236void 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);
    199244}
    200245
Note: See TracChangeset for help on using the changeset viewer.