4 #include "videodefinition.h"
7 YTJSVideo::YTJSVideo(const QString &videoId, QObject *parent)
8 : QObject(parent), videoId(videoId), definitionCode(0) {}
10 void YTJSVideo::loadStreamUrl() {
11 if (loadingStreamUrl) return;
12 loadingStreamUrl = true;
15 .callFunction(new JSResult(this), "videoInfo", {videoId})
16 .onJson([this](auto &doc) {
17 auto obj = doc.object();
19 QMap<int, QString> urlMap;
20 const auto formats = obj["formats"].toArray();
21 for (const auto &format : formats) {
22 bool isDashMpd = format["isDashMPD"].toBool();
23 if (isDashMpd) continue;
24 int itag = format["itag"].toInt();
25 QString url = format["url"].toString();
26 // qDebug() << itag << url;
27 urlMap.insert(itag, url);
29 if (urlMap.isEmpty()) {
30 loadingStreamUrl = false;
31 emit errorStreamUrl("No formats");
35 qDebug() << "available formats" << urlMap.keys();
36 const VideoDefinition &definition = YT3::instance().maxVideoDefinition();
37 const QVector<VideoDefinition> &definitions = VideoDefinition::getDefinitions();
38 int previousIndex = std::max(definitions.indexOf(definition), 0);
39 for (; previousIndex >= 0; previousIndex--) {
40 const VideoDefinition &previousDefinition = definitions.at(previousIndex);
41 qDebug() << "Testing format" << previousDefinition.getCode();
42 if (urlMap.contains(previousDefinition.getCode())) {
43 qDebug() << "Found format" << previousDefinition.getCode();
45 QString url = urlMap.value(previousDefinition.getCode());
46 definitionCode = previousDefinition.getCode();
49 if (!previousDefinition.hasAudio()) {
50 qDebug() << "Finding audio format";
51 static const QVector<int> audioFormats({251, 171, 140});
52 for (int audioFormat : audioFormats) {
53 qDebug() << "Trying audio format" << audioFormat;
54 auto i = urlMap.constFind(audioFormat);
55 if (i != urlMap.constEnd()) {
56 qDebug() << "Found audio format" << i.value();
63 loadingStreamUrl = false;
64 emit gotStreamUrl(url, audioUrl);
69 loadingStreamUrl = false;
70 emit errorStreamUrl(tr("Cannot get video stream for %1").arg(videoId));
72 .onError([this](auto &msg) {
73 loadingStreamUrl = false;
74 emit errorStreamUrl(msg);