From a3c066b1af0fc0231adcc586a23e38930a6f1dbd Mon Sep 17 00:00:00 2001 From: BayernMuller Date: Sat, 2 Nov 2024 21:34:57 +0900 Subject: [PATCH] refactor: reorganize directory structure by renaming lib to cli in communication and utils refactor: update include guards from LIB to CLI for consistency refactor: remove unused Shazam-related functions feat: include communication module in vibra executable refactor: relocate Shazam communication logic to separate file and modify usage in CLI --- cli/CMakeLists.txt | 4 + cli/cli.cpp | 58 +---------- cli/cli.h | 1 - cli/communication/shazam.cpp | 121 +++++++++++++++++++++++ cli/communication/shazam.h | 24 +++++ {lib => cli}/communication/timezones.h | 6 +- {lib => cli}/communication/user_agents.h | 6 +- {lib => cli}/utils/uuid4.h | 6 +- include/vibra.h | 28 ------ lib/CMakeLists.txt | 1 - lib/communication/shazam.cpp | 66 ------------- lib/communication/shazam.h | 19 ---- lib/vibra.cpp | 22 ----- 13 files changed, 160 insertions(+), 202 deletions(-) create mode 100644 cli/communication/shazam.cpp create mode 100644 cli/communication/shazam.h rename {lib => cli}/communication/timezones.h (92%) rename {lib => cli}/communication/user_agents.h (98%) rename {lib => cli}/utils/uuid4.h (90%) delete mode 100644 lib/communication/shazam.cpp delete mode 100644 lib/communication/shazam.h diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index c170d3f..17c6f95 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -11,11 +11,15 @@ FetchContent_Populate(args) add_executable(vibra main.cpp cli.cpp + communication/shazam.cpp ) # Add the args include directory to the target target_include_directories(vibra PRIVATE ${args_SOURCE_DIR}) +# Add the include directory to the target +target_include_directories(vibra PRIVATE ${CMAKE_SOURCE_DIR}/cli) + # Find libcurl find_library(CURL_LIBRARY NAMES curl) diff --git a/cli/cli.cpp b/cli/cli.cpp index ee3974d..6d42ab8 100644 --- a/cli/cli.cpp +++ b/cli/cli.cpp @@ -1,17 +1,9 @@ #include "../cli/cli.h" -#include #include #include #include #include - -std::size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ - std::string *buffer = reinterpret_cast(userp); - std::size_t realsize = size * nmemb; - buffer->append(reinterpret_cast(contents), realsize); - return realsize; -} +#include "communication/shazam.h" int CLI::Run(int argc, char **argv) { @@ -93,7 +85,7 @@ int CLI::Run(int argc, char **argv) } else if (recognize) { - std::cout << getMetadataFromShazam(fingerprint) << std::endl; + std::cout << Shazam::Recognize(fingerprint) << std::endl; } return 0; } @@ -122,49 +114,3 @@ Fingerprint *CLI::getFingerprintFromStdin(int chunk_seconds, int sample_rate, in return vibra_get_fingerprint_from_float_pcm(buffer.data(), bytes, sample_rate, bits_per_sample, channels); } - -std::string CLI::getMetadataFromShazam(const Fingerprint *fingerprint) -{ - auto content = vibra_get_shazam_request_json(fingerprint); - auto user_agent = vibra_get_shazam_random_user_agent(); - std::string url = vibra_get_shazam_host(); - - CURL *curl = curl_easy_init(); - std::string read_buffer; - - if (curl) - { - struct curl_slist *headers = nullptr; - headers = curl_slist_append(headers, "Accept-Encoding: gzip, deflate, br"); - headers = curl_slist_append(headers, "Accept: */*"); - headers = curl_slist_append(headers, "Connection: keep-alive"); - headers = curl_slist_append(headers, "Content-Type: application/json"); - headers = curl_slist_append(headers, "Content-Language: en_US"); - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_POST, 1L); - curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, content); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &read_buffer); - - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br"); - curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); - - CURLcode res = curl_easy_perform(curl); - if (res != CURLE_OK) - { - std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl; - } - - std::int64_t http_code = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - if (http_code != 200) - { - std::cerr << "HTTP code: " << http_code << std::endl; - } - curl_slist_free_all(headers); - curl_easy_cleanup(curl); - } - return read_buffer; -} diff --git a/cli/cli.h b/cli/cli.h index b200e96..3acbbb2 100644 --- a/cli/cli.h +++ b/cli/cli.h @@ -13,7 +13,6 @@ class CLI Fingerprint *getFingerprintFromMusicFile(const std::string &music_file); Fingerprint *getFingerprintFromStdin(int chunk_seconds, int sample_rate, int channels, int bits_per_sample, bool is_signed); - std::string getMetadataFromShazam(const Fingerprint *fingerprint); }; #endif // CLI_CLI_H_ diff --git a/cli/communication/shazam.cpp b/cli/communication/shazam.cpp new file mode 100644 index 0000000..249befa --- /dev/null +++ b/cli/communication/shazam.cpp @@ -0,0 +1,121 @@ +#include "communication/shazam.h" +#include +#include +#include +#include +#include "communication/timezones.h" +#include "communication/user_agents.h" +#include "utils/uuid4.h" +#include "../../include/vibra.h" + +// static variables initialization +constexpr char Shazam::HOST[]; + +std::size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp) +{ + std::string *buffer = reinterpret_cast(userp); + std::size_t realsize = size * nmemb; + buffer->append(reinterpret_cast(contents), realsize); + return realsize; +} + +std::string Shazam::Recognize(const Fingerprint *fingerprint) +{ + auto content = getRequestContent(fingerprint->uri, fingerprint->sample_ms); + auto user_agent = getUserAgent(); + std::string url = getShazamHost(); + + CURL *curl = curl_easy_init(); + std::string read_buffer; + + if (curl) + { + struct curl_slist *headers = nullptr; + headers = curl_slist_append(headers, "Accept-Encoding: gzip, deflate, br"); + headers = curl_slist_append(headers, "Accept: */*"); + headers = curl_slist_append(headers, "Connection: keep-alive"); + headers = curl_slist_append(headers, "Content-Type: application/json"); + headers = curl_slist_append(headers, "Content-Language: en_US"); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent.c_str()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, content.c_str()); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &read_buffer); + + curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br"); + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + + CURLcode res = curl_easy_perform(curl); + if (res != CURLE_OK) + { + std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl; + } + + std::int64_t http_code = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + if (http_code != 200) + { + std::cerr << "HTTP code: " << http_code << std::endl; + } + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + } + return read_buffer; +} + +std::string Shazam::getShazamHost() +{ + std::string host = HOST + uuid4::generate() + "/" + uuid4::generate(); + host += "?sync=true&" + "webv3=true&" + "sampling=true&" + "connected=&" + "shazamapiversion=v3&" + "sharehub=true&" + "video=v3"; + return host; +} + +std::string Shazam::getRequestContent(const std::string &uri, unsigned int sample_ms) +{ + std::mt19937 gen(std::random_device{}()); + std::uniform_int_distribution<> dis_float(0.0, 1.0); + + auto timezone = getTimezone(); + double fuzz = dis_float(gen) * 15.3 - 7.65; + + std::stringstream json_buf; + json_buf << "{"; + json_buf << "\"geolocation\":{"; + json_buf << "\"altitude\":" << dis_float(gen) * 400 + 100 + fuzz << ","; + json_buf << "\"latitude\":" << dis_float(gen) * 180 - 90 + fuzz << ","; + json_buf << "\"longitude\":" << dis_float(gen) * 360 - 180 + fuzz; + json_buf << "},"; + json_buf << "\"signature\":{"; + json_buf << "\"samplems\":" << sample_ms << ","; + json_buf << "\"timestamp\":" << time(nullptr) * 1000ULL << ","; + json_buf << "\"uri\":\"" << uri << "\""; + json_buf << "},"; + json_buf << "\"timestamp\":" << time(nullptr) * 1000ULL << ","; + json_buf << "\"timezone\":" + << "\"" << timezone << "\""; + json_buf << "}"; + std::string content = json_buf.str(); + return content; +} + +std::string Shazam::getUserAgent() +{ + std::mt19937 gen(std::random_device{}()); + std::uniform_int_distribution<> dis_useragent(0, USER_AGENTS_SIZE - 1); + return USER_AGENTS[dis_useragent(gen)]; +} + +std::string Shazam::getTimezone() +{ + std::mt19937 gen(std::random_device{}()); + std::uniform_int_distribution<> dis_timezone(0, EUROPE_TIMEZONES_SIZE - 1); + return EUROPE_TIMEZONES[dis_timezone(gen)]; +} diff --git a/cli/communication/shazam.h b/cli/communication/shazam.h new file mode 100644 index 0000000..4a4f18d --- /dev/null +++ b/cli/communication/shazam.h @@ -0,0 +1,24 @@ +#ifndef CLI_COMMUNICATION_SHAZAM_H_ +#define CLI_COMMUNICATION_SHAZAM_H_ + +#include + +// forward declaration +struct Fingerprint; +// + +class Shazam +{ + static constexpr char HOST[] = "https://amp.shazam.com/discovery/v5/fr/FR/android/-/tag/"; + + public: + static std::string Recognize(const Fingerprint *fingerprint); + + private: + static std::string getShazamHost(); + static std::string getUserAgent(); + static std::string getRequestContent(const std::string &uri, unsigned int sample_ms); + static std::string getTimezone(); +}; + +#endif // CLI_COMMUNICATION_SHAZAM_H_ diff --git a/lib/communication/timezones.h b/cli/communication/timezones.h similarity index 92% rename from lib/communication/timezones.h rename to cli/communication/timezones.h index 608dbf0..aa30c3d 100644 --- a/lib/communication/timezones.h +++ b/cli/communication/timezones.h @@ -1,5 +1,5 @@ -#ifndef LIB_COMMUNICATION_TIMEZONES_H_ -#define LIB_COMMUNICATION_TIMEZONES_H_ +#ifndef CLI_COMMUNICATION_TIMEZONES_H_ +#define CLI_COMMUNICATION_TIMEZONES_H_ static constexpr const char *EUROPE_TIMEZONES[] = { "Europe/Amsterdam", "Europe/Andorra", "Europe/Astrakhan", "Europe/Athens", @@ -21,4 +21,4 @@ static constexpr const char *EUROPE_TIMEZONES[] = { constexpr unsigned int EUROPE_TIMEZONES_SIZE = sizeof(EUROPE_TIMEZONES) / sizeof(EUROPE_TIMEZONES[0]); -#endif // LIB_COMMUNICATION_TIMEZONES_H_ +#endif // CLI_COMMUNICATION_TIMEZONES_H_ diff --git a/lib/communication/user_agents.h b/cli/communication/user_agents.h similarity index 98% rename from lib/communication/user_agents.h rename to cli/communication/user_agents.h index 365b4db..80e29dc 100644 --- a/lib/communication/user_agents.h +++ b/cli/communication/user_agents.h @@ -1,5 +1,5 @@ -#ifndef LIB_COMMUNICATION_USER_AGENTS_H_ -#define LIB_COMMUNICATION_USER_AGENTS_H_ +#ifndef CLI_COMMUNICATION_USER_AGENTS_H_ +#define CLI_COMMUNICATION_USER_AGENTS_H_ // // https://github.com/SaswatPadhi/FlashProfileDemo/blob/c1e3f05d09f6443568a606dc0a439d6ebb057ae1/tests/hetero/user_agents.json @@ -109,4 +109,4 @@ static constexpr const char *USER_AGENTS[] = { constexpr unsigned int USER_AGENTS_SIZE = sizeof(USER_AGENTS) / sizeof(USER_AGENTS[0]); -#endif // LIB_COMMUNICATION_USER_AGENTS_H_ +#endif // CLI_COMMUNICATION_USER_AGENTS_H_ diff --git a/lib/utils/uuid4.h b/cli/utils/uuid4.h similarity index 90% rename from lib/utils/uuid4.h rename to cli/utils/uuid4.h index df563b0..f9152d8 100644 --- a/lib/utils/uuid4.h +++ b/cli/utils/uuid4.h @@ -1,5 +1,5 @@ -#ifndef LIB_UTILS_UUID4_H_ -#define LIB_UTILS_UUID4_H_ +#ifndef CLI_UTILS_UUID4_H_ +#define CLI_UTILS_UUID4_H_ #include #include @@ -47,4 +47,4 @@ std::string generate() } } // namespace uuid4 -#endif // LIB_UTILS_UUID4_H_ +#endif // CLI_UTILS_UUID4_H_ diff --git a/include/vibra.h b/include/vibra.h index a517b29..89f8e47 100644 --- a/include/vibra.h +++ b/include/vibra.h @@ -89,34 +89,6 @@ const char *vibra_get_uri_from_fingerprint(Fingerprint *fingerprint); * @note This function is thread-unsafe. */ unsigned int vibra_get_sample_ms_from_fingerprint(Fingerprint *fingerprint); - -/** - * @brief Generate a Shazam request JSON from a fingerprint. - * - * @param fingerprint Pointer to the fingerprint. - * @return const char* The Shazam request JSON as a C-string. - * - * @note This function is thread-unsafe and the returned pointer should not be freed. - */ -const char *vibra_get_shazam_request_json(const Fingerprint *fingerprint); - -/** - * @brief Get the Shazam host URL. - * - * @return const char* The Shazam host URL as a C-string. - * - * @note This function is thread-unsafe and the returned pointer should not be freed. - */ -const char *vibra_get_shazam_host(); - -/** - * @brief Get a random Shazam user agent string. - * - * @return const char* A random Shazam user agent as a C-string. - * - * @note This function is thread-unsafe and the returned pointer should not be freed. - */ -const char *vibra_get_shazam_random_user_agent(); } // extern "C" #endif // INCLUDE_VIBRA_H_ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index da0a7b8..3a97e60 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -6,7 +6,6 @@ set(LIBVIBRA_SOURCES algorithm/signature_generator.cpp audio/wav.cpp audio/downsampler.cpp - communication/shazam.cpp ) # Add shared and static libraries for libvibra diff --git a/lib/communication/shazam.cpp b/lib/communication/shazam.cpp deleted file mode 100644 index 5fb9ff3..0000000 --- a/lib/communication/shazam.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "communication/shazam.h" -#include -#include -#include -#include "algorithm/signature.h" -#include "communication/timezones.h" -#include "communication/user_agents.h" -#include "utils/uuid4.h" - -// static variables initialization -constexpr char Shazam::HOST[]; - -std::string Shazam::GetShazamHost() -{ - std::string host = HOST + uuid4::generate() + "/" + uuid4::generate(); - host += "?sync=true&" - "webv3=true&" - "sampling=true&" - "connected=&" - "shazamapiversion=v3&" - "sharehub=true&" - "video=v3"; - return host; -} - -std::string Shazam::GetRequestContent(const std::string &uri, unsigned int sample_ms) -{ - std::mt19937 gen(std::random_device{}()); - std::uniform_int_distribution<> dis_float(0.0, 1.0); - - auto timezone = getTimezone(); - double fuzz = dis_float(gen) * 15.3 - 7.65; - - std::stringstream json_buf; - json_buf << "{"; - json_buf << "\"geolocation\":{"; - json_buf << "\"altitude\":" << dis_float(gen) * 400 + 100 + fuzz << ","; - json_buf << "\"latitude\":" << dis_float(gen) * 180 - 90 + fuzz << ","; - json_buf << "\"longitude\":" << dis_float(gen) * 360 - 180 + fuzz; - json_buf << "},"; - json_buf << "\"signature\":{"; - json_buf << "\"samplems\":" << sample_ms << ","; - json_buf << "\"timestamp\":" << time(nullptr) * 1000ULL << ","; - json_buf << "\"uri\":\"" << uri << "\""; - json_buf << "},"; - json_buf << "\"timestamp\":" << time(nullptr) * 1000ULL << ","; - json_buf << "\"timezone\":" - << "\"" << timezone << "\""; - json_buf << "}"; - std::string content = json_buf.str(); - return content; -} - -std::string Shazam::GetUserAgent() -{ - std::mt19937 gen(std::random_device{}()); - std::uniform_int_distribution<> dis_useragent(0, USER_AGENTS_SIZE - 1); - return USER_AGENTS[dis_useragent(gen)]; -} - -std::string Shazam::getTimezone() -{ - std::mt19937 gen(std::random_device{}()); - std::uniform_int_distribution<> dis_timezone(0, EUROPE_TIMEZONES_SIZE - 1); - return EUROPE_TIMEZONES[dis_timezone(gen)]; -} diff --git a/lib/communication/shazam.h b/lib/communication/shazam.h deleted file mode 100644 index 16c43b6..0000000 --- a/lib/communication/shazam.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LIB_COMMUNICATION_SHAZAM_H_ -#define LIB_COMMUNICATION_SHAZAM_H_ - -#include - -class Shazam -{ - static constexpr char HOST[] = "https://amp.shazam.com/discovery/v5/fr/FR/android/-/tag/"; - - public: - static std::string GetShazamHost(); - static std::string GetUserAgent(); - static std::string GetRequestContent(const std::string &uri, unsigned int sample_ms); - - private: - static std::string getTimezone(); -}; - -#endif // LIB_COMMUNICATION_SHAZAM_H_ diff --git a/lib/vibra.cpp b/lib/vibra.cpp index b7ca77c..623db90 100644 --- a/lib/vibra.cpp +++ b/lib/vibra.cpp @@ -2,7 +2,6 @@ #include "algorithm/signature_generator.h" #include "audio/downsampler.h" #include "audio/wav.h" -#include "communication/shazam.h" #include "utils/ffmpeg.h" Fingerprint *_get_fingerprint_from_wav(const Wav &wav); @@ -55,27 +54,6 @@ unsigned int vibra_get_sample_ms_from_fingerprint(Fingerprint *fingerprint) return fingerprint->sample_ms; } -const char *vibra_get_shazam_request_json(const Fingerprint *fingerprint) -{ - static std::string content; - content = Shazam::GetRequestContent(fingerprint->uri, fingerprint->sample_ms); - return content.c_str(); -} - -const char *vibra_get_shazam_host() -{ - static std::string host; - host = Shazam::GetShazamHost(); - return host.c_str(); -} - -const char *vibra_get_shazam_random_user_agent() -{ - static std::string user_agent; - user_agent = Shazam::GetUserAgent(); - return user_agent.c_str(); -} - Fingerprint *_get_fingerprint_from_wav(const Wav &wav) { LowQualityTrack pcm = Downsampler::GetLowQualityPCM(wav);