Skip to content

Commit

Permalink
Merge pull request #24 from BayernMuller/feature/migration-communicat…
Browse files Browse the repository at this point in the history
…ion-to-cli

refactor: reorganize directory structure by renaming lib to cli in communication and utils
  • Loading branch information
BayernMuller authored Nov 2, 2024
2 parents 9308149 + a3c066b commit 072ad4a
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 202 deletions.
4 changes: 4 additions & 0 deletions cli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
58 changes: 2 additions & 56 deletions cli/cli.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
#include "../cli/cli.h"
#include <curl/curl.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <args.hxx>

std::size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
std::string *buffer = reinterpret_cast<std::string *>(userp);
std::size_t realsize = size * nmemb;
buffer->append(reinterpret_cast<char *>(contents), realsize);
return realsize;
}
#include "communication/shazam.h"

int CLI::Run(int argc, char **argv)
{
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
1 change: 0 additions & 1 deletion cli/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_
121 changes: 121 additions & 0 deletions cli/communication/shazam.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include "communication/shazam.h"
#include <curl/curl.h>
#include <algorithm>
#include <random>
#include <sstream>
#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<std::string *>(userp);
std::size_t realsize = size * nmemb;
buffer->append(reinterpret_cast<char *>(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)];
}
24 changes: 24 additions & 0 deletions cli/communication/shazam.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef CLI_COMMUNICATION_SHAZAM_H_
#define CLI_COMMUNICATION_SHAZAM_H_

#include <string>

// 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_
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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_
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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_
6 changes: 3 additions & 3 deletions lib/utils/uuid4.h → cli/utils/uuid4.h
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <random>
Expand Down Expand Up @@ -47,4 +47,4 @@ std::string generate()
}
} // namespace uuid4

#endif // LIB_UTILS_UUID4_H_
#endif // CLI_UTILS_UUID4_H_
28 changes: 0 additions & 28 deletions include/vibra.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_
1 change: 0 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 072ad4a

Please sign in to comment.