]> git.sur5r.net Git - minitube/blob - src/yt/ytjs/ytjssinglevideosource.cpp
2471ee9a4c47ad69c525532cda17b09c650f525b
[minitube] / src / yt / ytjs / ytjssinglevideosource.cpp
1 #include "ytjssinglevideosource.h"
2
3 #include "js.h"
4 #include "video.h"
5
6 YTJSSingleVideoSource::YTJSSingleVideoSource(QObject *parent)
7     : VideoSource(parent), video(nullptr) {}
8
9 void YTJSSingleVideoSource::loadVideos(int max, int startIndex) {
10     aborted = false;
11
12     if (startIndex == 1) {
13         if (video) {
14             if (name.isEmpty()) {
15                 name = video->getTitle();
16                 qDebug() << "Emitting name changed" << name;
17                 emit nameChanged(name);
18             }
19             emit gotVideos({video->clone()});
20         }
21     }
22
23     JS::instance()
24             .callFunction(new JSResult(this), "videoInfo", {videoId})
25             .onJson([this](auto &doc) {
26                 if (aborted) return;
27
28                 auto obj = doc.object();
29                 // qDebug() << doc.toJson();
30
31                 auto parseVideoObject = [](QJsonObject i) {
32                     Video *video = new Video();
33
34                     QString id = i["id"].toString();
35                     video->setId(id);
36
37                     QString title = i["title"].toString();
38                     video->setTitle(title);
39
40                     QString desc = i["description"].toString();
41                     if (desc.isEmpty()) desc = i["desc"].toString();
42                     video->setDescription(desc);
43
44                     const auto thumbs = i["thumbnails"].toArray();
45                     for (const auto &thumb : thumbs) {
46                         QString url = thumb["url"].toString();
47                         int width = thumb["width"].toInt();
48                         if (width >= 336)
49                             video->setLargeThumbnailUrl(url);
50                         else if (width >= 246)
51                             video->setMediumThumbnailUrl(url);
52                         else if (width >= 168)
53                             video->setThumbnailUrl(url);
54                     }
55
56                     int views = i["view_count"].toInt();
57                     video->setViewCount(views);
58
59                     int duration = i["length_seconds"].toInt();
60                     video->setViewCount(duration);
61
62                     QString channelId = i["ucid"].toString();
63                     video->setChannelId(channelId);
64
65                     QString channelName = i["author"].toString();
66                     video->setChannelTitle(channelName);
67
68                     return video;
69                 };
70
71                 QVector<Video *> videos;
72
73                 if (!video) {
74                     // parse video details
75                     videos << parseVideoObject(obj["videoDetails"].toObject());
76                 }
77
78                 const auto items = obj["related_videos"].toArray();
79                 videos.reserve(items.size());
80
81                 for (const auto &i : items) {
82                     videos << parseVideoObject(i.toObject());
83                 }
84
85                 if (videos.isEmpty()) {
86                     emit error("No results");
87                 } else {
88                     emit gotVideos(videos);
89                     emit finished(videos.size());
90                 }
91
92                 // fake more videos by loading videos related to the last one
93                 video = nullptr;
94                 if (!videos.isEmpty()) videoId = videos.last()->getId();
95             })
96             .onError([this](auto &msg) { emit error(msg); });
97 }
98
99 void YTJSSingleVideoSource::setVideo(Video *video) {
100     this->video = video;
101     videoId = video->getId();
102 }
103
104 void YTJSSingleVideoSource::abort() {
105     aborted = true;
106 }
107
108 QString YTJSSingleVideoSource::getName() {
109     return name;
110 }