youtubeapi.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "youtubeapi.hpp"
  2. namespace ytapi {
  3. void youtubeInit(std::string key) {
  4. api_key = key;
  5. }
  6. bool performCurlRequest(std::string url, std::stringstream* response) {
  7. // Добавляем ключ к каждому запросу
  8. url += "&key=";
  9. url += api_key;
  10. CURL* handle = curl_easy_init();
  11. if (!handle) return false;
  12. curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
  13. curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &writeHttpToString);
  14. curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
  15. curl_easy_perform(handle);
  16. curl_easy_cleanup(handle);
  17. return true;
  18. }
  19. void performCurlDownload(std::string url, std::string save_path) {
  20. CURL* handle = curl_easy_init();
  21. if (!handle) return;
  22. FILE* fp;
  23. fp = fopen(save_path.c_str(), "wb");
  24. curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
  25. curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &writeHttpToFile);
  26. curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp);
  27. curl_easy_perform(handle);
  28. curl_easy_cleanup(handle);
  29. fclose(fp);
  30. }
  31. std::string urlencode(const std::string& decoded) {
  32. const auto encoded_value = curl_easy_escape(nullptr, decoded.c_str(), static_cast<int>(decoded.length()));
  33. std::string result(encoded_value);
  34. curl_free(encoded_value);
  35. return result;
  36. }
  37. std::string urldecode(const std::string& encoded) {
  38. int output_length;
  39. const auto decoded_value = curl_easy_unescape(
  40. nullptr,
  41. encoded.c_str(),
  42. static_cast<int>(encoded.length()),
  43. &output_length
  44. );
  45. std::string result(decoded_value, output_length);
  46. curl_free(decoded_value);
  47. return result;
  48. }
  49. size_t writeHttpToString(char* ptr, size_t size, size_t nmemb, void* userdata)
  50. {
  51. std::string data((const char*) ptr, (size_t) size * nmemb);
  52. *((std::stringstream*) userdata) << data;
  53. return size * nmemb;
  54. }
  55. size_t writeHttpToFile(void* ptr, size_t size, size_t nmemb, FILE* userdata)
  56. {
  57. size_t written = fwrite(ptr, size, nmemb, userdata);
  58. return written;
  59. }
  60. std::vector<std::string> getVideoIDsByQuery(std::string query) {
  61. std::stringstream response;
  62. std::string url;
  63. // Формирование URL
  64. url += "https://youtube.googleapis.com/youtube/v3/search?type=video&part=snippet&maxResult=25&q=";
  65. url += urlencode(query);
  66. performCurlRequest(url, &response);
  67. return getVideoIDsFromJSON(response.str());
  68. }
  69. std::vector<std::string> getVideoIDsFromJSON(std::string input) {
  70. auto json = nlohmann::json::parse(input);
  71. auto items = json["items"];
  72. std::vector<std::string> output;
  73. for (auto it = items.begin(); it != items.end(); ++it) {
  74. auto item = it.value();
  75. auto yt_id = item["id"]["videoId"];
  76. output.push_back(yt_id);
  77. }
  78. return output;
  79. }
  80. video_result getVideoByYTID(std::string yt_id) {
  81. std::stringstream response;
  82. std::stringstream response_rating;
  83. std::string url;
  84. video_result output;
  85. // -- Общие сведения --
  86. url = "https://youtube.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id=";
  87. url += yt_id;
  88. performCurlRequest(url, &response);
  89. auto json = nlohmann::json::parse(response);
  90. auto item = json["items"][0];
  91. auto snippet = item["snippet"];
  92. auto content_details = item["contentDetails"];
  93. auto stats = item["statistics"];
  94. output.yt_id = yt_id;
  95. output.title = Glib::ustring(snippet["title"]);
  96. output.description = Glib::ustring(snippet["description"]);
  97. output.duration = std::string(content_details["duration"]);
  98. output.author_yt_id = std::string(snippet["channelId"]);
  99. output.author_name = Glib::ustring(snippet["channelTitle"]);
  100. output.published_at = std::string(snippet["publishedAt"]);
  101. output.views_count = std::stoi(stats["viewCount"].template get<std::string>());
  102. // -- Оценка видео --
  103. // TODO: с помощью API узнавать оценку видео которую я поставил
  104. output.rating = 0;
  105. // -- Превью --
  106. // С помощью .back() получаем самое большое изображение превью и
  107. // сохраняем его в ответ видео
  108. output.big_thumbnail = snippet["thumbnails"].back()["url"];
  109. return output;
  110. }
  111. void downloadMediumThumnail(std::string yt_id, std::string save_path)
  112. {
  113. // Формирование URL
  114. std::string url = "https://img.youtube.com/vi/" + yt_id + "/mqdefault.jpg";
  115. performCurlDownload(url, save_path);
  116. }
  117. void downloadLargeThumnail(std::string yt_id, std::string save_path)
  118. {
  119. // Формирование URL
  120. std::string url = "https://img.youtube.com/vi/" + yt_id + "/maxresdefault.jpg";
  121. performCurlDownload(url, save_path);
  122. }
  123. void downloadThumbnail(std::string url, std::string save_path)
  124. {
  125. performCurlDownload(url, save_path);
  126. }
  127. }