]> git.sur5r.net Git - minitube/blob - src/video.cpp
0fb30b3cbb6b4d65ee22a39b94c5e7f3b3efb767
[minitube] / src / video.cpp
1 #include "video.h"
2 #include "networkaccess.h"
3 #include <QtNetwork>
4
5 namespace The {
6     NetworkAccess* http();
7 }
8
9 Video::Video() : m_thumbnailUrls(QList<QUrl>()) {
10     m_duration = 0;
11     m_viewCount = -1;
12 }
13
14 void Video::preloadThumbnail() {
15     if (m_thumbnailUrls.isEmpty()) return;
16     QObject *reply = The::http()->get(m_thumbnailUrls.first());
17     connect(reply, SIGNAL(data(QByteArray)), SLOT(setThumbnail(QByteArray)));
18 }
19
20 void Video::setThumbnail(QByteArray bytes) {
21     m_thumbnail = QImage::fromData(bytes);
22     emit gotThumbnail();
23 }
24
25 const QImage Video::thumbnail() const {
26     return m_thumbnail;
27 }
28
29 void Video::scrapeStreamUrl() {
30
31     // https://develop.participatoryculture.org/trac/democracy/browser/trunk/tv/portable/flashscraper.py
32
33     QUrl webpage = m_webpage;
34     // qDebug() << webpage.toString();
35
36     // Get Video ID
37     // youtube-dl line 428
38     // QRegExp re("^((?:http://)?(?:\\w+\\.)?youtube\\.com/(?:(?:v/)|(?:(?:watch(?:\\.php)?)?\\?(?:.+&)?v=)))?([0-9A-Za-z_-]+)(?(1).+)?$");
39     QRegExp re("^http://www\\.youtube\\.com/watch\\?v=([0-9A-Za-z_-]+).*");
40     bool match = re.exactMatch(webpage.toString());
41     if (!match || re.numCaptures() < 1) {
42         emit errorStreamUrl(QString("Cannot get video id for %1").arg(webpage.toString()));
43         return;
44     }
45     videoId = re.cap(1);
46     // if (!videoId) return false;
47     // qDebug() << videoId;
48
49     // Get Video Token
50     QUrl normalizedUrl = QUrl(QString("http://www.youtube.com/get_video_info?video_id=")
51                               .append(videoId).append("&el=embedded&ps=default&eurl="));
52
53     QObject *reply = The::http()->get(normalizedUrl);
54     connect(reply, SIGNAL(data(QByteArray)), SLOT(gotVideoInfo(QByteArray)));
55     connect(reply, SIGNAL(error(QNetworkReply*)), SLOT(errorVideoInfo(QNetworkReply*)));
56
57     // see you in gotVideoInfo...
58 }
59
60 void  Video::gotVideoInfo(QByteArray data) {
61     QString videoInfo = QString::fromUtf8(data);
62
63     QRegExp re = QRegExp("^.*&token=([^&]+).*$");
64     bool match = re.exactMatch(videoInfo);
65
66     // on regexp failure, stop and report error
67     if (!match || re.numCaptures() < 1) {
68         qDebug() << videoInfo;
69         re = QRegExp("^.*&reason=([^&]+).*$");
70         match = re.exactMatch(videoInfo);
71         if (match) {
72             // report the error in the status bar
73             QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(qApp->topLevelWidgets().first());
74             QString errorMessage = QUrl::fromEncoded(re.cap(1).toUtf8()).toString().replace("+", " ");
75             int indexOfTag = errorMessage.indexOf("<");
76             if (indexOfTag != -1) {
77                 errorMessage = errorMessage.left(indexOfTag);
78             }
79             if (mainWindow) mainWindow->statusBar()->showMessage(errorMessage);
80             emit errorStreamUrl(errorMessage);
81         } else
82             emit errorStreamUrl("Error parsing video info");
83         return;
84     }
85
86     QString videoToken = re.cap(1);
87     // FIXME proper decode
88     videoToken = videoToken.replace("%3D", "=");
89     // qDebug() << "token" << videoToken;
90
91     QUrl videoUrl = QUrl(QString("http://www.youtube.com/get_video?video_id=")
92                          .append(videoId)
93                          .append("&t=").append(videoToken)
94                          .append("&eurl=&el=embedded&ps=default&fmt=18"));
95
96     m_streamUrl = videoUrl;
97
98     emit gotStreamUrl(videoUrl);
99 }
100
101 void Video::errorVideoInfo(QNetworkReply *reply) {
102     emit errorStreamUrl(tr("Network error: %1 for %2").arg(reply->errorString(), reply->url().toString()));
103 }