123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #include "youtubeapi.hpp"
- namespace ytapi {
-
- void youtubeInit(std::string key) {
- api_key = key;
- }
- bool performCurlRequest(std::string url, std::stringstream* response) {
- // Добавляем ключ к каждому запросу
- url += "&key=";
- url += api_key;
-
- CURL* handle = curl_easy_init();
- if (!handle) return false;
- curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
- curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &writeHttpToString);
- curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
- curl_easy_perform(handle);
- curl_easy_cleanup(handle);
- return true;
- }
- void performCurlDownload(std::string url, std::string save_path) {
- CURL* handle = curl_easy_init();
- if (!handle) return;
- FILE* fp;
- fp = fopen(save_path.c_str(), "wb");
- curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
- curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &writeHttpToFile);
- curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp);
- curl_easy_perform(handle);
- curl_easy_cleanup(handle);
- fclose(fp);
- }
-
- std::string urlencode(const std::string& decoded) {
- const auto encoded_value = curl_easy_escape(nullptr, decoded.c_str(), static_cast<int>(decoded.length()));
- std::string result(encoded_value);
- curl_free(encoded_value);
- return result;
- }
- std::string urldecode(const std::string& encoded) {
- int output_length;
- const auto decoded_value = curl_easy_unescape(
- nullptr,
- encoded.c_str(),
- static_cast<int>(encoded.length()),
- &output_length
- );
- std::string result(decoded_value, output_length);
- curl_free(decoded_value);
- return result;
- }
- size_t writeHttpToString(char* ptr, size_t size, size_t nmemb, void* userdata)
- {
- std::string data((const char*) ptr, (size_t) size * nmemb);
- *((std::stringstream*) userdata) << data;
- return size * nmemb;
- }
- size_t writeHttpToFile(void* ptr, size_t size, size_t nmemb, FILE* userdata)
- {
- size_t written = fwrite(ptr, size, nmemb, userdata);
- return written;
- }
- std::vector<std::string> getVideoIDsByQuery(std::string query) {
- std::stringstream response;
- std::string url;
- // Формирование URL
- url += "https://youtube.googleapis.com/youtube/v3/search?type=video&part=snippet&maxResult=25&q=";
- url += urlencode(query);
-
- performCurlRequest(url, &response);
- return getVideoIDsFromJSON(response.str());
- }
- std::vector<std::string> getVideoIDsFromJSON(std::string input) {
- auto json = nlohmann::json::parse(input);
- auto items = json["items"];
- std::vector<std::string> output;
-
- for (auto it = items.begin(); it != items.end(); ++it) {
- auto item = it.value();
- auto yt_id = item["id"]["videoId"];
- output.push_back(yt_id);
- }
- return output;
- }
- video_result getVideoByYTID(std::string yt_id) {
- std::stringstream response;
- std::stringstream response_rating;
- std::string url;
- video_result output;
- // -- Общие сведения --
- url = "https://youtube.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id=";
- url += yt_id;
- performCurlRequest(url, &response);
- auto json = nlohmann::json::parse(response);
- auto item = json["items"][0];
- auto snippet = item["snippet"];
- auto content_details = item["contentDetails"];
- auto stats = item["statistics"];
- output.yt_id = yt_id;
- output.title = Glib::ustring(snippet["title"]);
- output.description = Glib::ustring(snippet["description"]);
- output.duration = std::string(content_details["duration"]);
- output.author_yt_id = std::string(snippet["channelId"]);
- output.author_name = Glib::ustring(snippet["channelTitle"]);
- output.published_at = std::string(snippet["publishedAt"]);
- output.views_count = std::stoi(stats["viewCount"].template get<std::string>());
- // -- Оценка видео --
- // TODO: с помощью API узнавать оценку видео которую я поставил
- output.rating = 0;
- // -- Превью --
- // С помощью .back() получаем самое большое изображение превью и
- // сохраняем его в ответ видео
- output.big_thumbnail = snippet["thumbnails"].back()["url"];
- return output;
- }
- void downloadMediumThumnail(std::string yt_id, std::string save_path)
- {
- // Формирование URL
- std::string url = "https://img.youtube.com/vi/" + yt_id + "/mqdefault.jpg";
- performCurlDownload(url, save_path);
- }
-
- void downloadLargeThumnail(std::string yt_id, std::string save_path)
- {
- // Формирование URL
- std::string url = "https://img.youtube.com/vi/" + yt_id + "/maxresdefault.jpg";
- performCurlDownload(url, save_path);
- }
- void downloadThumbnail(std::string url, std::string save_path)
- {
- performCurlDownload(url, save_path);
- }
- }
|