File indexing completed on 2024-05-12 16:21:19

0001 // SPDX-FileCopyrightText: 2021 Jonah Brüchert <jbb@kaidan.im>
0002 //
0003 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 
0005 #ifndef YTMUSIC_H
0006 #define YTMUSIC_H
0007 
0008 #include <string>
0009 #include <optional>
0010 #include <map>
0011 #include <variant>
0012 #include <vector>
0013 #include <memory>
0014 
0015 constexpr auto TESTED_YTMUSICAPI_VERSION = "1.5.1";
0016 
0017 struct YTMusicPrivate;
0018 
0019 namespace meta {
0020 struct Thumbnail {
0021     std::string url;
0022     int width;
0023     int height;
0024 
0025     bool operator<(const Thumbnail &other) const {
0026         return height < other.height;
0027     }
0028 };
0029 struct Artist {
0030     std::string name;
0031     std::optional<std::string> id;
0032 };
0033 struct Album {
0034     std::string name;
0035     std::optional<std::string> id;
0036 };
0037 }
0038 
0039 
0040 namespace search {
0041 ///
0042 /// Base class for Video and Song, which share most attributes.
0043 ///
0044 struct Media {
0045     std::string video_id;
0046     std::string title;
0047     std::vector<meta::Artist> artists;
0048     std::optional<std::string> duration;
0049     std::vector<meta::Thumbnail> thumbnails;
0050 };
0051 
0052 struct Video : public Media {
0053     std::optional<std::string> views;
0054 };
0055 
0056 struct Playlist {
0057     std::string browse_id;
0058     std::string title;
0059     std::optional<std::string> author;
0060     std::string item_count;
0061     std::vector<meta::Thumbnail> thumbnails;
0062 };
0063 
0064 struct Song : public Media {
0065     std::optional<meta::Album> album;
0066     std::optional<bool> is_explicit;
0067 };
0068 
0069 struct Album {
0070     std::optional<std::string> browse_id;
0071     std::string title;
0072     std::string type;
0073     std::vector<meta::Artist> artists;
0074     std::optional<std::string> year;
0075     bool is_explicit;
0076     std::vector<meta::Thumbnail> thumbnails;
0077 };
0078 
0079 struct Artist {
0080     std::string browse_id;
0081     std::string artist;
0082     std::optional<std::string> shuffle_id;
0083     std::optional<std::string> radio_id;
0084     std::vector<meta::Thumbnail> thumbnails;
0085 };
0086 
0087 struct TopResult {
0088     std::string category;
0089     std::string result_type;
0090     std::optional<std::string> video_id;
0091     std::optional<std::string> title;
0092     std::vector<meta::Artist> artists;
0093     std::vector<meta::Thumbnail> thumbnails;
0094 };
0095 
0096 using SearchResultItem = std::variant<Video, Playlist, Song, Album, Artist, TopResult>;
0097 };
0098 
0099 
0100 namespace artist {
0101 struct Artist {
0102     template<typename T>
0103     struct Section {
0104         std::optional<std::string> browse_id;
0105         std::vector<T> results;
0106         std::optional<std::string> params;
0107     };
0108 
0109     struct Song {
0110         struct Album {
0111             std::string name;
0112             std::string id;
0113         };
0114 
0115         std::string video_id;
0116         std::string title;
0117         std::vector<meta::Thumbnail> thumbnails;
0118         std::vector<meta::Artist> artist;
0119         Album album;
0120     };
0121 
0122     struct Album {
0123         std::string title;
0124         std::vector<meta::Thumbnail> thumbnails;
0125         std::optional<std::string> year;
0126         std::string browse_id;
0127         std::optional<std::string> type;
0128     };
0129 
0130     struct Video {
0131         std::string title;
0132         std::vector<meta::Thumbnail> thumbnails;
0133         std::optional<std::string> views;
0134         std::string video_id;
0135         std::string playlist_id;
0136     };
0137 
0138     struct Single {
0139         std::string title;
0140         std::vector<meta::Thumbnail> thumbnails;
0141         std::string year;
0142         std::string browse_id;
0143     };
0144 
0145     std::optional<std::string> description;
0146     std::optional<std::string> views;
0147     std::string name;
0148     std::string channel_id;
0149     std::optional<std::string> subscribers;
0150     bool subscribed;
0151     std::vector<meta::Thumbnail> thumbnails;
0152     std::optional<Section<Song>> songs;
0153     std::optional<Section<Album>> albums;
0154     std::optional<Section<Single>> singles;
0155     std::optional<Section<Video>> videos;
0156 };
0157 }
0158 
0159 namespace album {
0160     struct Track {
0161         std::optional<bool> is_explicit;
0162         std::string title;
0163         std::vector<meta::Artist> artists;
0164         std::optional<std::string> album;
0165         std::optional<std::string> video_id;
0166         std::optional<std::string> duration;
0167         std::optional<std::string> like_status;
0168     };
0169 
0170     struct Album {
0171         struct ReleaseDate {
0172             int year;
0173             int month;
0174             int day;
0175         };
0176 
0177         std::string title;
0178         int track_count;
0179         std::string duration;
0180         std::string audio_playlist_id;
0181         std::optional<std::string> year;
0182         std::optional<std::string> description;
0183         std::vector<meta::Thumbnail> thumbnails;
0184         std::vector<Track> tracks;
0185         std::vector<meta::Artist> artists;
0186     };
0187 }
0188 
0189 namespace song {
0190 struct Song {
0191     struct Thumbnail {
0192         std::vector<meta::Thumbnail> thumbnails;
0193     };
0194 
0195     std::string video_id;
0196     std::string title;
0197     std::string length;
0198     std::string channel_id;
0199     bool is_owner_viewer;
0200     bool is_crawlable;
0201     Thumbnail thumbnail;
0202     std::string view_count;
0203     std::string author;
0204     bool is_private;
0205     bool is_unplugged_corpus;
0206     bool is_live_content;
0207     std::vector<std::string> artists;
0208 };
0209 }
0210 
0211 namespace playlist {
0212 struct Track {
0213     std::optional<std::string> video_id;
0214     std::string title;
0215     std::vector<meta::Artist> artists;
0216     std::optional<meta::Album> album;
0217     std::optional<std::string> duration;
0218     std::optional<std::string> like_status;
0219     std::vector<meta::Thumbnail> thumbnails;
0220     bool is_available;
0221     std::optional<bool> is_explicit;
0222 };
0223 
0224 struct Playlist {
0225     std::string id;
0226     std::string privacy;
0227     std::string title;
0228     std::vector<meta::Thumbnail> thumbnails;
0229     meta::Artist author;
0230     std::optional<std::string> year;
0231     std::string duration;
0232     int track_count;
0233     std::vector<Track> tracks;
0234 };
0235 }
0236 
0237 namespace video_info {
0238 struct Format {
0239     std::optional<float> quality;
0240     std::string url;
0241     std::string vcodec;
0242     std::string acodec;
0243 
0244     // More, but not interesting for us right now
0245 };
0246 
0247 struct VideoInfo {
0248     std::string id;
0249     std::string title;
0250     std::string artist;
0251     std::string channel;
0252     std::vector<Format> formats;
0253     std::string thumbnail;
0254 
0255     // More, but not interesting for us right now
0256 };
0257 }
0258 
0259 namespace watch {
0260 struct Playlist {
0261     struct Track {
0262         std::string title;
0263         std::optional<std::string> length;
0264         std::string video_id;
0265         std::optional<std::string> playlistId;
0266         std::vector<meta::Thumbnail> thumbnail;
0267         std::optional<std::string> like_status;
0268         std::vector<meta::Artist> artists;
0269         std::optional<meta::Album> album;
0270     };
0271 
0272     std::vector<Track> tracks;
0273     std::optional<std::string> lyrics;
0274 };
0275 }
0276 
0277 struct Lyrics {
0278     std::optional<std::string> source;
0279     std::string lyrics;
0280 };
0281 
0282 class YTMusic
0283 {
0284 public:
0285     YTMusic(const std::optional<std::string> &auth = std::nullopt,
0286             const std::optional<std::string> &user = std::nullopt,
0287             const std::optional<bool> requests_session = std::nullopt,
0288             const std::optional<std::map<std::string, std::string>> &proxies = std::nullopt,
0289             const std::string &language = "en");
0290 
0291     ~YTMusic();
0292 
0293     std::vector<search::SearchResultItem> search(const std::string &query,
0294                                                  const std::optional<std::string> &filter = std::nullopt,
0295                                                  const std::optional<std::string> &scope = std::nullopt,
0296                                                  const int limit = 100,
0297                                                  const bool ignore_spelling = false) const;
0298 
0299     /// https://ytmusicapi.readthedocs.io/en/latest/reference.html#ytmusicapi.YTMusic.get_artist
0300     artist::Artist get_artist(const std::string &channel_id) const;
0301 
0302     /// https://ytmusicapi.readthedocs.io/en/latest/reference.html#ytmusicapi.YTMusic.get_album
0303     album::Album get_album(const std::string &browse_id) const;
0304 
0305     /// https://ytmusicapi.readthedocs.io/en/latest/reference.html#ytmusicapi.YTMusic.get_song
0306     std::optional<song::Song> get_song(const std::string &video_id) const;
0307 
0308     /// https://ytmusicapi.readthedocs.io/en/latest/reference.html#ytmusicapi.YTMusic.get_playlist
0309     playlist::Playlist get_playlist(const std::string &playlist_id, int limit = 1024) const;
0310 
0311     /// https://ytmusicapi.readthedocs.io/en/latest/reference.html#ytmusicapi.YTMusic.get_artist_albums
0312     std::vector<artist::Artist::Album> get_artist_albums(const std::string &channel_id, const std::string &params) const;
0313 
0314     /// youtube-dl's extract_info function
0315     video_info::VideoInfo extract_video_info(const std::string &video_id) const;
0316 
0317     /// https://ytmusicapi.readthedocs.io/en/latest/reference.html#ytmusicapi.YTMusic.get_watch_playlist
0318     watch::Playlist get_watch_playlist(const std::optional<std::string> &videoId = std::nullopt,
0319                                       const std::optional<std::string> &playlistId = std::nullopt,
0320                                       int limit = 25) const;
0321 
0322     Lyrics get_lyrics(const std::string &browse_id) const;
0323 
0324     std::string get_version() const;
0325 
0326     // TODO wrap more methods
0327 
0328 private:
0329     std::unique_ptr<YTMusicPrivate> d;
0330 };
0331 
0332 #endif // YTMUSIC_H