source: smplayer/trunk/src/youtube/retrieveyoutubeurl.cpp@ 142

Last change on this file since 142 was 142, checked in by Silvan Scherrer, 12 years ago

SMPlayer: update trunk to 0.8.5

File size: 5.9 KB
Line 
1/* smplayer, GUI front-end for mplayer.
2 Copyright (C) 2006-2013 Ricardo Villalba <rvm@users.sourceforge.net>
3 Copyright (C) 2010 Ori Rejwan
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19
20#include "retrieveyoutubeurl.h"
21#include <QUrl>
22
23RetrieveYoutubeUrl::RetrieveYoutubeUrl( QObject* parent ) : SimpleHttp(parent)
24{
25 connect(this, SIGNAL(downloadFinished(QByteArray)),
26 this, SLOT(parse(QByteArray)));
27
28 preferred_quality = FLV_360p;
29}
30
31RetrieveYoutubeUrl::~RetrieveYoutubeUrl() {
32}
33
34void RetrieveYoutubeUrl::fetchPage(const QString & url) {
35 download(url);
36 orig_url = url;
37}
38
39void RetrieveYoutubeUrl::parse(QByteArray text) {
40 qDebug("RetrieveYoutubeUrl::parse");
41
42 urlMap.clear();
43
44 QString replyString = QString::fromUtf8(text.constData(), text.size());
45
46 QRegExp rx_title(".*<title>(.*)</title>.*");
47 if (rx_title.indexIn(replyString) != -1) {
48 url_title = rx_title.cap(1).simplified();
49 url_title = QString(url_title).replace("&amp;","&").replace("&gt;", ">").replace("&lt;", "<").replace("&quot;","\"").replace("&#39;","'")/*.replace(" - YouTube", "")*/;
50 qDebug("RetrieveYoutubeUrl::parse: title '%s'", url_title.toUtf8().constData());
51 } else {
52 url_title = "Youtube video";
53 }
54
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);
78 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); */
85 }
86 }
87 else {
88 if (!n_url.isEmpty()) n_url += "&";
89 n_url += par;
90 }
91 }
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 }
99
100 qDebug("RetrieveYoutubeUrl::parse: url count: %d", urlMap.count());
101
102 QString p_url = findPreferredUrl();
103 if (!p_url.isNull()) {
104 emit gotUrls(urlMap);
105 emit gotPreferredUrl(p_url);
106 } else {
107 emit gotEmptyList();
108 }
109}
110
111QString RetrieveYoutubeUrl::findPreferredUrl() {
112 latest_preferred_url = findPreferredUrl(urlMap, preferred_quality);
113 return latest_preferred_url;
114}
115
116QString RetrieveYoutubeUrl::findPreferredUrl(const QMap<int, QString>& urlMap, Quality q) {
117 // Choose a url according to preferred quality
118 QString p_url;
119 //Quality q = preferred_quality;
120
121 if (q==MP4_1080p) {
122 p_url = urlMap.value(MP4_1080p, QString());
123 if (p_url.isNull()) p_url= urlMap.value(WEBM_1080p, QString());
124 if (p_url.isNull()) q = MP4_720p;
125 }
126
127 if (q==WEBM_1080p) {
128 p_url = urlMap.value(WEBM_1080p, QString());
129 if (p_url.isNull()) p_url= urlMap.value(MP4_1080p, QString());
130 if (p_url.isNull()) q = WEBM_720p;
131 }
132
133 if (q==MP4_720p) {
134 p_url = urlMap.value(MP4_720p, QString());
135 if (p_url.isNull()) p_url= urlMap.value(WEBM_720p, QString());
136 if (p_url.isNull()) p_url = urlMap.value(WEBM_480p, QString());
137 if (p_url.isNull()) q = MP4_360p;
138 }
139
140 if (q==WEBM_720p) {
141 p_url = urlMap.value(WEBM_720p, QString());
142 if (p_url.isNull()) p_url= urlMap.value(MP4_720p, QString());
143 if (p_url.isNull()) q = WEBM_480p;
144 }
145
146 if (q==WEBM_480p) {
147 p_url = urlMap.value(WEBM_480p, QString());
148 if (p_url.isNull()) q = WEBM_360p;
149 }
150
151 if (q==MP4_360p) {
152 p_url = urlMap.value(MP4_360p, QString());
153 if (p_url.isNull()) p_url= urlMap.value(WEBM_360p, QString());
154 if (p_url.isNull()) q = FLV_360p;
155 }
156
157 if (q==WEBM_360p) {
158 p_url = urlMap.value(WEBM_360p, QString());
159 if (p_url.isNull()) p_url= urlMap.value(MP4_360p, QString());
160 if (p_url.isNull()) q = FLV_360p;
161 }
162
163 // FLV, low priority
164 if (q==FLV_480p) {
165 p_url = urlMap.value(FLV_480p, QString());
166 if (p_url.isNull()) q = FLV_360p;
167 }
168
169 if (q==FLV_360p) {
170 p_url = urlMap.value(FLV_360p, QString());
171 if (p_url.isNull()) q = FLV_240p;
172 }
173
174 if (q==FLV_240p) {
175 p_url = urlMap.value(q, QString());
176 }
177
178 return p_url;
179}
180
181QString 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
190void 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);
199}
200
201#include "moc_retrieveyoutubeurl.cpp"
Note: See TracBrowser for help on using the repository browser.