From cdb471e46627557f1e6dfcde919dd33c41d94e6e Mon Sep 17 00:00:00 2001 From: Flavio Tordini Date: Mon, 29 Sep 2014 16:21:53 +0200 Subject: [PATCH] Preliminary DASH work --- src/video.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/video.h | 5 ++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/video.cpp b/src/video.cpp index 3c15efd..8f61dd0 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -23,6 +23,7 @@ $END_LICENSE */ #include #include "videodefinition.h" #include "jsfunctions.h" +#include "temporary.h" namespace The { NetworkAccess* http(); @@ -353,6 +354,19 @@ void Video::scrapeWebPage(QByteArray data) { fmtUrlMap.replace("\\u0026", "&"); // parseFmtUrlMap(fmtUrlMap, true); +#ifdef APP_DASH + QSettings settings; + QString definitionName = settings.value("definition", "360p").toString(); + if (definitionName == "1080p") { + QRegExp dashManifestRe("\"dashmpd\":\\s*\"([^\"]+)\""); + if (dashManifestRe.indexIn(html) != -1) { + dashManifestUrl = dashManifestRe.cap(1); + dashManifestUrl.remove('\\'); + qDebug() << "dashManifestUrl" << dashManifestUrl; + } + } +#endif + QRegExp jsPlayerRe("\"assets\":.+\"js\":\\s*\"([^\"]+)\""); if (jsPlayerRe.indexIn(html) != -1) { QString jsPlayerUrl = jsPlayerRe.cap(1); @@ -424,9 +438,49 @@ void Video::parseJsPlayer(QByteArray bytes) { captureFunction(sigFuncName, js); // qWarning() << sigFunctions; } + +#ifdef APP_DASH + if (!dashManifestUrl.isEmpty()) { + QRegExp sigRe("/s/([\\w\\.]+)"); + if (sigRe.indexIn(dashManifestUrl) != -1) { + qDebug() << "Decrypting signature for dash manifest"; + QString sig = sigRe.cap(1); + sig = decryptSignature(sig); + dashManifestUrl.replace(sigRe, "/signature/" + sig); + qDebug() << dashManifestUrl; + + m_streamUrl = dashManifestUrl; + this->definitionCode = 37; + emit gotStreamUrl(m_streamUrl); + loadingStreamUrl = false; + + /* + QObject *reply = The::http()->get(QUrl::fromEncoded(dashManifestUrl.toUtf8())); + connect(reply, SIGNAL(data(QByteArray)), SLOT(parseDashManifest(QByteArray))); + connect(reply, SIGNAL(error(QNetworkReply*)), SLOT(errorVideoInfo(QNetworkReply*))); + */ + + return; + } + } +#endif + parseFmtUrlMap(fmtUrlMap, true); } +void Video::parseDashManifest(QByteArray bytes) { + QFile file(Temporary::filename()); + if (!file.open(QIODevice::WriteOnly)) + qWarning() << file.errorString() << file.fileName(); + QDataStream stream(&file); + stream.writeRawData(bytes.constData(), bytes.size()); + + m_streamUrl = "file://" + file.fileName(); + this->definitionCode = 37; + emit gotStreamUrl(m_streamUrl); + loadingStreamUrl = false; +} + void Video::captureFunction(const QString &name, const QString &js) { QRegExp funcRe("function\\s+" + QRegExp::escape(name) + "\\s*\\([" + jsNameChars + ",\\s]*\\)\\s*\\{[^\\}]+\\}"); if (funcRe.indexIn(js) == -1) { diff --git a/src/video.h b/src/video.h index d169723..48b2f1a 100644 --- a/src/video.h +++ b/src/video.h @@ -98,7 +98,8 @@ private slots: void errorVideoInfo(QNetworkReply*); void scrapeWebPage(QByteArray); void gotHeadHeaders(QNetworkReply*); - void parseJsPlayer(QByteArray); + void parseJsPlayer(QByteArray bytes); + void parseDashManifest(QByteArray bytes); private: void getVideoInfo(); @@ -138,6 +139,8 @@ private: QString sigFuncName; QHash sigFunctions; QHash sigObjects; + + QString dashManifestUrl; }; // This is required in order to use QPointer