39 template<>
struct core<discord_core_api::discord_core_internal::data_class> {
40 using value_type = discord_core_api::discord_core_internal::data_class;
41 static constexpr auto parseValue =
42 createValue(
"artwork_url", &value_type::artworkUrl,
"description", &value_type::description,
"duration", &value_type::duration,
"media", &value_type::mediaVal,
"title",
43 &value_type::title,
"track_authorization", &value_type::trackAuthorization,
"avatar_url", &value_type::avatarUrl,
"permalink_url", &value_type::viewUrl);
46 template<>
struct core<discord_core_api::discord_core_internal::welcome_element> {
47 using value_type = discord_core_api::discord_core_internal::welcome_element;
48 static constexpr auto parseValue = createValue(
"data", &value_type::data,
"hydratable", &value_type::hydratable,
"tracks", &value_type::data);
51 template<>
struct core<discord_core_api::discord_core_internal::welcome> {
52 using value_type = discord_core_api::discord_core_internal::welcome;
53 static constexpr auto parseValue = createValue(&value_type::data);
56 template<>
struct core<discord_core_api::discord_core_internal::media> {
57 using value_type = discord_core_api::discord_core_internal::media;
58 static constexpr auto parseValue = createValue(
"transcodings", &value_type::transcodings);
61 template<>
struct core<discord_core_api::discord_core_internal::second_download_url> {
62 using value_type = discord_core_api::discord_core_internal::second_download_url;
63 static constexpr auto parseValue = createValue(
"url", &value_type::url);
66 template<>
struct core<discord_core_api::discord_core_internal::transcoding> {
67 using value_type = discord_core_api::discord_core_internal::transcoding;
68 static constexpr auto parseValue = createValue(
"preset", &value_type::preset,
"url", &value_type::url);
71 template<>
struct core<discord_core_api::discord_core_internal::raw_sound_cloud_song> {
72 using value_type = discord_core_api::discord_core_internal::raw_sound_cloud_song;
73 static constexpr auto parseValue = createValue(
"artwork_url", &value_type::artworkUrl,
"description", &value_type::description,
"duration", &value_type::duration,
"media",
74 &value_type::mediaVal,
"title", &value_type::title,
"track_authorization", &value_type::trackAuthorization,
"permalink_url", &value_type::viewUrl);
77 template<>
struct core<discord_core_api::discord_core_internal::sound_cloud_search_results> {
78 using value_type = discord_core_api::discord_core_internal::sound_cloud_search_results;
79 static constexpr auto parseValue = createValue(
"collection", &value_type::collection);
85 namespace discord_core_internal {
87 sound_cloud_request_builder::sound_cloud_request_builder(config_manager* configManagerNew) : https_client_core{ jsonifier::string{ configManagerNew->getBotToken() } } {};
89 inline search_type collectSearchType(jsonifier::string_view
string, jsonifier::string& stringNew) {
90 if (
string.find(
"soundcloud.com") != jsonifier::string::npos &&
string.find(
"/sets/") == jsonifier::string::npos) {
91 stringNew =
string.substr(
string.find(
"soundcloud.com/") + jsonifier::string{
"soundcloud.com/" }.size());
92 return search_type::single_song_with_id;
93 }
else if (
string.find(
"/sets/") != jsonifier::string::npos) {
94 stringNew =
string.substr(
string.find(
"soundcloud.com/") + jsonifier::string{
"soundcloud.com/" }.size());
95 return search_type::playlist;
98 return search_type::single_song_without_id;
102 jsonifier::vector<song> sound_cloud_request_builder::collectPlaylist(jsonifier::string_view songQuery) {
103 if (clientId ==
"") {
104 sound_cloud_request_builder::collectClientId();
107 https_workload_data dataPackage{ https_workload_type::SoundCloud_Get_Search_Results };
108 dataPackage.baseUrl =
"https://soundcloud.com/";
109 dataPackage.headersToInsert[
"User-Agent"] =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
110 dataPackage.relativePath = songQuery;
111 dataPackage.workloadClass = https_workload_class::Get;
112 https_response_data returnData = submitWorkloadAndGetResult(std::move(dataPackage));
113 jsonifier::vector<song> resultsFinal{};
114 auto findValue = returnData.responseData.find(
"window.__sc_hydration = ");
115 if (findValue != jsonifier::string::npos) {
116 returnData.responseData = returnData.responseData.substr(findValue + jsonifier::string{
"window.__sc_hydration = " }.size(),
117 returnData.responseData.find(
"</script>") -
118 (returnData.responseData.find(
"window.__sc_hydration = ") + jsonifier::string{
"window.__sc_hydration = " }.size()));
120 welcome resultsNew{};
121 parser.parseJson(resultsNew, returnData.responseData);
122 jsonifier::string avatarUrl{};
123 jsonifier::string collectionString{
"tracks?ids=" };
124 for (
auto& value: resultsNew.data) {
125 if (value.data.getType() == jsonifier::json_type::Object) {
126 auto newObject = value.data.operator jsonifier::raw_json_data::object_type();
127 avatarUrl = newObject[
"avatar_url"].operator jsonifier::string();
128 if (value.hydratable ==
"playlist") {
129 auto newerObject = value.data.operator jsonifier::raw_json_data::object_type();
130 for (
auto& [key, valueNew]: newerObject) {
131 if (key ==
"tracks") {
132 auto newArray = valueNew.operator jsonifier::raw_json_data::array_type();
133 uint32_t currentIndex{};
134 auto arraySize = newArray.size();
135 for (
auto& newValue: newArray) {
136 newObject = newValue.operator jsonifier::raw_json_data::object_type();
137 collectionString += jsonifier::toString(newValue.operator jsonifier::raw_json_data::object_type()[
"id"].operator uint64_t());
138 if (currentIndex < arraySize - 1) {
139 collectionString +=
"%2C";
143 collectionString +=
"&client_id=" + clientId +
"&%5Bobject%20Object%5D=&app_version=" + appVersion +
"&app_locale=en";
149 https_workload_data dataPackage02{ https_workload_type::SoundCloud_Get_Search_Results };
150 dataPackage02.baseUrl =
"https://api-v2.soundcloud.com/";
151 dataPackage02.headersToInsert[
"User-Agent"] =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
152 dataPackage02.relativePath = collectionString;
153 dataPackage02.workloadClass = https_workload_class::Get;
154 returnData = submitWorkloadAndGetResult(std::move(dataPackage02));
155 jsonifier::vector<jsonifier::raw_json_data> resultsNewer{};
156 parser.parseJson(resultsNewer, returnData.responseData);
157 for (
auto& value: resultsNewer) {
159 if (value.getType() == jsonifier::json_type::Object) {
160 auto newObject = value.operator jsonifier::raw_json_data::object_type();
161 avatarUrl = newObject[
"avatar_url"].operator jsonifier::string();
162 if (newObject[
"title"].
operator jsonifier::string() ==
"") {
166 for (
auto& valueNew: newObject[
"media"].
operator jsonifier::raw_json_data::object_type()[
"transcodings"].
operator jsonifier::raw_json_data::array_type()) {
167 if (valueNew.operator jsonifier::raw_json_data::object_type()[
"preset"].operator jsonifier::string() ==
"opus_0_0") {
169 results.firstDownloadUrl = valueNew.operator jsonifier::raw_json_data::object_type()[
"url"].operator jsonifier::string();
170 results.songId = valueNew.operator jsonifier::raw_json_data::object_type()[
"url"].operator jsonifier::string();
174 jsonifier::string newString = newObject[
"title"].operator jsonifier::string();
175 if (newString.size() > 0) {
176 if (newString.size() > 256) {
177 newString = newString.substr(0, 256);
179 results.songTitle = utf8MakeValid(newString);
181 newString = newObject[
"description"].operator jsonifier::string();
182 if (newString.size() > 0) {
183 if (newString.size() > 256) {
184 newString = newString.substr(0, 256);
186 results.description = utf8MakeValid(newString);
187 results.description +=
"...";
189 newString = newObject[
"artwork_url"].operator jsonifier::string();
190 if (newString.size() > 0) {
191 results.thumbnailUrl = utf8MakeValid(newString);
193 results.viewUrl = newObject[
"permalink_url"].operator jsonifier::string();
194 results.duration = time_stamp::convertMsToDurationString(
static_cast<uint64_t
>(newObject[
"duration"].
operator uint64_t()));
195 results.firstDownloadUrl +=
196 "?client_id=" + sound_cloud_request_builder::clientId +
"&track_authorization=" + newObject[
"track_authorization"].operator jsonifier::string();
197 if (newObject[
"artwork_url"].
operator jsonifier::string().find(
"-") != jsonifier::string::npos) {
198 jsonifier::string newerString =
199 newObject[
"artwork_url"].operator jsonifier::string().substr(0, newObject[
"artwork_url"].
operator jsonifier::string().findLastOf(
"-") + 1);
200 newerString +=
"t500x500.jpg";
201 results.thumbnailUrl = newerString;
202 }
else if (avatarUrl.find(
"-") != jsonifier::string::npos) {
203 jsonifier::string newerString = avatarUrl.substr(0, avatarUrl.findLastOf(
"-") + 1);
204 newerString +=
"t500x500.jpg";
205 results.thumbnailUrl = newerString;
207 results.type = song_type::SoundCloud;
208 resultsFinal.emplace_back(results);
213 }
catch (
const https_error& error) {
214 message_printer::printError<print_message_type::https>(
"sound_cloud_request_builder::collectSearchResults() Error: " + jsonifier::string{ error.what() });
219 song sound_cloud_request_builder::collectSingleResult(jsonifier::string_view songQuery) {
220 if (clientId ==
"") {
221 sound_cloud_request_builder::collectClientId();
224 https_workload_data dataPackage{ https_workload_type::SoundCloud_Get_Search_Results };
225 dataPackage.baseUrl =
"https://soundcloud.com/";
226 dataPackage.headersToInsert[
"User-Agent"] =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
227 dataPackage.relativePath = songQuery;
228 dataPackage.workloadClass = https_workload_class::Get;
229 https_response_data returnData = submitWorkloadAndGetResult(std::move(dataPackage));
231 auto findValue = returnData.responseData.find(
"window.__sc_hydration = ");
232 if (findValue != jsonifier::string::npos) {
233 returnData.responseData = returnData.responseData.substr(findValue + jsonifier::string{
"window.__sc_hydration = " }.size(),
234 returnData.responseData.find(
"</script>") -
235 (returnData.responseData.find(
"window.__sc_hydration = ") + jsonifier::string{
"window.__sc_hydration = " }.size()));
237 welcome resultsNew{};
238 parser.parseJson(resultsNew, returnData.responseData);
239 jsonifier::string avatarUrl{};
241 for (
auto& value: resultsNew.data) {
242 if (value.data.getType() == jsonifier::json_type::Object) {
243 auto newObject = value.data.operator jsonifier::raw_json_data::object_type();
244 avatarUrl = newObject[
"avatar_url"].operator jsonifier::string();
245 if (value.hydratable ==
"sound") {
246 if (newObject[
"title"].
operator jsonifier::string() ==
"") {
251 newObject[
"media"].
operator jsonifier::raw_json_data::object_type()[
"transcodings"].
operator jsonifier::raw_json_data::array_type()) {
252 if (valueNew.operator jsonifier::raw_json_data::object_type()[
"preset"].operator jsonifier::string() ==
"opus_0_0") {
254 results.firstDownloadUrl = valueNew.operator jsonifier::raw_json_data::object_type()[
"url"].operator jsonifier::string();
255 results.songId = valueNew.operator jsonifier::raw_json_data::object_type()[
"url"].operator jsonifier::string();
259 jsonifier::string newString = newObject[
"title"].operator jsonifier::string();
260 if (newString.size() > 0) {
261 if (newString.size() > 256) {
262 newString = newString.substr(0, 256);
264 results.songTitle = utf8MakeValid(newString);
266 newString = newObject[
"description"].operator jsonifier::string();
267 if (newString.size() > 0) {
268 if (newString.size() > 256) {
269 newString = newString.substr(0, 256);
271 results.description = utf8MakeValid(newString);
272 results.description +=
"...";
274 newString = newObject[
"artwork_url"].operator jsonifier::string();
275 if (newString.size() > 0) {
276 results.thumbnailUrl = utf8MakeValid(newString);
278 results.viewUrl = newObject[
"permalink_url"].operator jsonifier::string();
279 results.duration = time_stamp::convertMsToDurationString(
static_cast<uint64_t
>(newObject[
"duration"].
operator uint64_t()));
280 results.firstDownloadUrl +=
281 "?client_id=" + sound_cloud_request_builder::clientId +
"&track_authorization=" + newObject[
"track_authorization"].operator jsonifier::string();
282 if (newObject[
"artwork_url"].
operator jsonifier::string().find(
"-") != jsonifier::string::npos) {
283 jsonifier::string newerString =
284 newObject[
"artwork_url"].operator jsonifier::string().substr(0, newObject[
"artwork_url"].
operator jsonifier::string().findLastOf(
"-") + 1);
285 newerString +=
"t500x500.jpg";
286 results.thumbnailUrl = newerString;
287 }
else if (avatarUrl.find(
"-") != jsonifier::string::npos) {
288 jsonifier::string newerString = avatarUrl.substr(0, avatarUrl.findLastOf(
"-") + 1);
289 newerString +=
"t500x500.jpg";
290 results.thumbnailUrl = newerString;
296 results.type = song_type::SoundCloud;
298 }
catch (
const https_error& error) {
299 message_printer::printError<print_message_type::https>(
"sound_cloud_request_builder::collectSearchResults() Error: " + jsonifier::string{ error.what() });
304 jsonifier::vector<song> sound_cloud_request_builder::collectSearchResults(jsonifier::string_view songQuery, uint64_t limit) {
305 if (clientId ==
"") {
306 sound_cloud_request_builder::collectClientId();
309 jsonifier::string newString{};
310 jsonifier::vector<song> results{};
311 auto searchType = collectSearchType(songQuery, newString);
312 if (searchType == search_type::single_song_with_id) {
313 auto result = collectSingleResult(newString);
314 if (result.songId !=
"") {
315 results.emplace_back(result);
318 }
else if (searchType == search_type::playlist) {
319 return collectPlaylist(newString);
321 https_workload_data dataPackage{ https_workload_type::SoundCloud_Get_Search_Results };
322 dataPackage.baseUrl = baseUrl02;
323 dataPackage.headersToInsert[
"User-Agent"] =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
324 dataPackage.relativePath =
"/search?q=" + urlEncode(songQuery) +
"&facet=model&client_id=" + sound_cloud_request_builder::clientId;
325 dataPackage.workloadClass = https_workload_class::Get;
326 https_response_data returnData = submitWorkloadAndGetResult(std::move(dataPackage));
327 sound_cloud_search_results resultsNew{};
328 parser.parseJson(resultsNew, returnData.responseData);
329 for (
auto& value: resultsNew.collection) {
331 if (value.title ==
"") {
335 for (
auto& valueNew: value.mediaVal.transcodings) {
336 if (valueNew.preset ==
"opus_0_0") {
338 songNew.firstDownloadUrl = valueNew.url;
339 songNew.songId = valueNew.url;
343 newString = value.title;
344 if (newString.size() > 0) {
345 if (newString.size() > 256) {
346 newString = newString.substr(0, 256);
348 songNew.songTitle = utf8MakeValid(newString);
350 newString = value.description;
351 if (newString.size() > 0) {
352 if (newString.size() > 256) {
353 newString = newString.substr(0, 256);
355 songNew.description = utf8MakeValid(newString);
356 songNew.description +=
"...";
358 newString = value.artworkUrl;
359 if (newString.size() > 0) {
360 songNew.thumbnailUrl = newString;
362 songNew.type = song_type::SoundCloud;
363 songNew.viewUrl = value.viewUrl;
364 songNew.duration = time_stamp::convertMsToDurationString(value.duration);
365 songNew.firstDownloadUrl +=
"?client_id=" + sound_cloud_request_builder::clientId +
"&track_authorization=" + value.trackAuthorization;
366 if (songNew.thumbnailUrl.find(
"-") != jsonifier::string::npos) {
367 jsonifier::string newerString = songNew.thumbnailUrl.substr(0, songNew.thumbnailUrl.findLastOf(
"-") + 1);
368 newerString +=
"t500x500.jpg";
369 songNew.thumbnailUrl = newerString;
371 results.emplace_back(songNew);
372 if (results.size() >= limit) {
378 }
catch (
const https_error& error) {
379 message_printer::printError<print_message_type::https>(
"sound_cloud_request_builder::collectSearchResults() Error: " + jsonifier::string{ error.what() });
384 song sound_cloud_request_builder::constructDownloadInfo(
const song& songNew, uint64_t recursionDepth) {
386 https_workload_data dataPackage01{ https_workload_type::SoundCloud_Get_Download_Links };
387 if (songNew.firstDownloadUrl.find(
".com") != jsonifier::string::npos) {
388 dataPackage01.baseUrl = songNew.firstDownloadUrl.substr(0, songNew.firstDownloadUrl.find(
".com") + 4);
389 dataPackage01.relativePath = songNew.firstDownloadUrl.substr(songNew.firstDownloadUrl.find(
".com") + 4);
393 dataPackage01.workloadClass = https_workload_class::Get;
394 dataPackage01.headersToInsert[
"Connection"] =
"Keep-Alive";
395 dataPackage01.headersToInsert[
"User-Agent"] =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36";
396 https_response_data results = submitWorkloadAndGetResult(std::move(dataPackage01));
397 second_download_url downloadUrl{};
398 song newerSong{ songNew };
399 parser.parseJson(downloadUrl, results.responseData);
400 newerSong.secondDownloadUrl = downloadUrl.url;
401 if (newerSong.secondDownloadUrl.find(
"/playlist") != jsonifier::string::npos) {
402 https_workload_data dataPackage{ https_workload_type::SoundCloud_Get_Download_Links };
403 dataPackage.baseUrl = newerSong.secondDownloadUrl;
404 dataPackage.workloadClass = https_workload_class::Get;
405 https_response_data resultsNew = submitWorkloadAndGetResult(std::move(dataPackage));
406 jsonifier::string newString{ resultsNew.responseData };
407 newerSong.finalDownloadUrls.clear();
408 while (newString.find(
"#EXTINF:") != jsonifier::string::npos) {
409 jsonifier::string newString01 =
"#EXTINF:";
410 jsonifier::string newString02 = newString.substr(newString.find(
"#EXTINF:") + newString01.size());
411 auto commandFind = newString02.find(
",");
412 jsonifier::string newString00 = newString02.substr(0, commandFind);
413 jsonifier::string newString03 = newString02.substr(commandFind + 2, newString02.find(
"#EXTINF:") - (newString00.size() + 3));
414 newString = newString02.substr(commandFind);
415 if (newString03.find(
"#EXT-X-ENDLIST") != jsonifier::string::npos) {
416 newString03 = newString03.substr(0, newString03.find(
"#EXT-X-ENDLIST"));
418 jsonifier::string newString04 = newString03.substr(newString03.findFirstOf(
"1234567890"));
419 uint64_t firstNumber01 = jsonifier::strToUint64(newString04.substr(0, newString04.find(
"/")).data());
420 jsonifier::string newString05 = newString04.substr(newString04.find(
"/") + 1);
421 uint64_t secondNumber = jsonifier::strToUint64(newString05.substr(0, newString05.find(
"/")).data());
422 download_url downloadUrlNew{};
423 downloadUrlNew.urlPath = newString03;
424 downloadUrlNew.contentSize = secondNumber - firstNumber01;
425 newerSong.finalDownloadUrls.emplace_back(downloadUrlNew);
427 for (uint64_t x = 0; x < newerSong.finalDownloadUrls.size(); ++x) {
428 if (x == newerSong.finalDownloadUrls.size() - 1) {
429 newerSong.finalDownloadUrls.at(x).urlPath = newerSong.finalDownloadUrls.at(x).urlPath.substr(0, newerSong.finalDownloadUrls.at(x).urlPath.size() - 1);
432 for (
auto& value: newerSong.finalDownloadUrls) {
433 newerSong.contentLength += value.contentSize;
436 https_workload_data dataPackage02{ https_workload_type::SoundCloud_Get_Search_Results };
437 dataPackage02.baseUrl = newerSong.secondDownloadUrl;
438 dataPackage02.workloadClass = https_workload_class::Get;
439 dataPackage02.headersToInsert[
"Connection"] =
"Keep-Alive";
440 dataPackage02.headersToInsert[
"User-Agent"] =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36";
441 auto headersNew = submitWorkloadAndGetResult(std::move(dataPackage02));
442 uint64_t valueBitRate{};
443 uint64_t valueLength{};
444 if (headersNew.responseHeaders.find(
"x-amz-meta-bitrate") != headersNew.responseHeaders.end()) {
445 valueBitRate = jsonifier::strToUint64(headersNew.responseHeaders.find(
"x-amz-meta-bitrate")->second.data());
447 if (headersNew.responseHeaders.find(
"x-amz-meta-duration") != headersNew.responseHeaders.end()) {
448 valueLength = jsonifier::strToUint64(headersNew.responseHeaders.find(
"x-amz-meta-duration")->second.data());
450 download_url downloadUrlNew{};
451 downloadUrlNew.contentSize =
static_cast<uint64_t
>(((valueBitRate * valueLength) / 8) - 193);
452 downloadUrlNew.urlPath = newerSong.secondDownloadUrl;
453 newerSong.finalDownloadUrls.emplace_back(downloadUrlNew);
456 }
catch (
const https_error& error) {
457 if (recursionDepth <= 10) {
459 return constructDownloadInfo(songNew, recursionDepth);
461 message_printer::printError<print_message_type::https>(
"YouTubeRequestBuilder::constructDownloadInfo() Error: " + jsonifier::string{ error.what() });
467 song sound_cloud_request_builder::collectFinalSong(
const song& songNew) {
468 return constructDownloadInfo(songNew, 0);
471 jsonifier::string sound_cloud_request_builder::collectClientId() {
472 jsonifier::string clientIdNew{};
474 https_workload_data dataPackage02{ https_workload_type::SoundCloud_Get_Client_Id };
475 dataPackage02.baseUrl = baseUrl;
476 dataPackage02.relativePath =
"/search?q=testValue";
477 dataPackage02.headersToInsert[
"User-Agent"] =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36";
478 dataPackage02.workloadClass = https_workload_class::Get;
479 https_response_data returnData = submitWorkloadAndGetResult(std::move(dataPackage02));
480 jsonifier::vector<jsonifier::string> assetPaths{};
481 jsonifier::string newString01 =
"crossorigin src=";
482 jsonifier::string newerString{};
483 newerString = returnData.responseData;
484 if (newerString.find(newString01) != jsonifier::string::npos) {
485 jsonifier::string newString = newerString.substr(newerString.find(newString01) + newString01.size());
486 jsonifier::string newString02 = newString.substr(1, newString.find(
".js") + 2);
487 assetPaths.emplace_back(newString02);
488 while (newString.find(
"crossorigin src=") != jsonifier::string::npos) {
489 jsonifier::string newString03 = newString.substr(1, newString.find(
".js") + 2);
490 newString = newString.substr(newString.find(
"crossorigin src=") + newString01.size());
491 assetPaths.emplace_back(newString03);
493 https_workload_data dataPackage03{ https_workload_type::SoundCloud_Get_Client_Id };
494 dataPackage03.baseUrl = assetPaths[5];
495 dataPackage03.workloadClass = https_workload_class::Get;
496 https_response_data returnData02 = submitWorkloadAndGetResult(std::move(dataPackage03));
497 jsonifier::string newerString02{};
498 newerString02.insert(newerString02.begin(), returnData02.responseData.begin(), returnData02.responseData.end());
500 jsonifier::string newString03 =
501 newerString02.substr(newerString02.find(
"JSON.stringify({client_id:\"") + jsonifier::string_view{
"JSON.stringify({client_id:\"" }.size());
503 if (newString03.find(
"\",nonce:e.nonce}))))") != jsonifier::string::npos) {
504 clientIdNew = newString03.substr(0, newString03.find(
"\",nonce:e.nonce}))))"));
506 if (returnData02.responseCode != 200) {
507 message_printer::printError<print_message_type::https>(
"sound_cloud_api::collectClientID() Error: " +
508 jsonifier::toString(returnData.responseCode.operator uint64_t()) + jsonifier::string{ newerString02.data() });
511 }
catch (
const https_error& error) {
512 message_printer::printError<print_message_type::https>(
"sound_cloud_request_builder::collectClientId() Error" + jsonifier::string{ error.what() });
517 sound_cloud_api::sound_cloud_api(config_manager* configManagerNew,
const snowflake guildIdNew) : sound_cloud_request_builder{ configManagerNew } {
518 guildId =
static_cast<snowflake
>(guildIdNew);
519 if (sound_cloud_request_builder::clientId ==
"") {
520 sound_cloud_request_builder::clientId = collectClientId();
524 void sound_cloud_api::weFailedToDownloadOrDecode(
const song& songNew, std::coroutine_handle<co_routine<void, false>::promise_type> threadHandle, uint64_t recursionDepth) {
525 std::this_thread::sleep_for(1s);
526 if (recursionDepth < 10) {
528 song songNewer = constructDownloadInfo(songNew, 0);
529 downloadAndStreamAudio(songNewer, threadHandle, recursionDepth);
531 discord_core_client::getVoiceConnection(guildId).skip(
true);
535 bool sound_cloud_api::areWeWorking() {
536 return areWeWorkingBool.load(std::memory_order_acquire);
539 co_routine<void, false> sound_cloud_api::downloadAndStreamAudio(
const song songNew, std::coroutine_handle<co_routine<void, false>::promise_type> threadHandle,
540 uint64_t currentReconnectTries) {
542 areWeWorkingBool.store(
true, std::memory_order_release);
543 if (currentReconnectTries == 0) {
544 threadHandle =
co_await newThreadAwaitable<void, false>();
547 jsonifier::vector<https_workload_data> workloadVector{};
548 for (uint64_t x = 0; x < songNew.finalDownloadUrls.size(); ++x) {
549 https_workload_data dataPackage03{ https_workload_type::SoundCloud_Get_Search_Results };
550 if (counter < songNew.finalDownloadUrls.size()) {
551 jsonifier::string baseUrlNew =
552 songNew.finalDownloadUrls.at(x).urlPath.substr(0, jsonifier::string_view{
"https://cf-hls-opus-media.sndcdn.com/media/" }.size());
553 jsonifier::string relativeUrl =
554 songNew.finalDownloadUrls.at(x).urlPath.substr(jsonifier::string_view{
"https://cf-hls-opus-media.sndcdn.com/media/" }.size());
555 dataPackage03.baseUrl = baseUrlNew;
556 dataPackage03.relativePath = relativeUrl;
558 dataPackage03.workloadClass = https_workload_class::Get;
559 workloadVector.emplace_back(std::move(dataPackage03));
561 jsonifier::vector<jsonifier::string> buffer{};
562 ogg_demuxer demuxer{};
563 for (uint64_t x = 0; x < songNew.finalDownloadUrls.size(); ++x) {
564 https_response_data result{ submitWorkloadAndGetResult(std::move(workloadVector.at(x))) };
565 if (result.responseCode != 200) {
566 weFailedToDownloadOrDecode(songNew, threadHandle, currentReconnectTries);
567 areWeWorkingBool.store(
false, std::memory_order_release);
571 if (result.responseData.size() > 0) {
572 buffer.emplace_back(std::move(result.responseData));
573 demuxer.writeData({ buffer.back().data(), buffer.back().size() });
574 demuxer.proceedDemuxing();
576 if (threadHandle.promise().stopRequested()) {
577 areWeWorkingBool.store(
false, std::memory_order_release);
580 bool didWeReceive{
true };
582 audio_frame_data frameData{};
583 didWeReceive = demuxer.collectFrame(frameData);
584 if (threadHandle.promise().stopRequested()) {
585 areWeWorkingBool.store(
false, std::memory_order_release);
588 if (frameData.currentSize != 0) {
589 discord_core_client::getSongAPI(guildId).audioDataBuffer.send(std::move(frameData));
591 }
while (didWeReceive && !threadHandle.promise().stopRequested());
592 if (threadHandle.promise().stopRequested()) {
593 areWeWorkingBool.store(
false, std::memory_order_release);
596 std::this_thread::sleep_for(1ms);
598 areWeWorkingBool.store(
false, std::memory_order_release);
599 discord_core_client::getVoiceConnection(guildId).skip(
false);
600 audio_frame_data frameData{};
601 discord_core_client::getSongAPI(guildId).audioDataBuffer.send(std::move(frameData));
603 }
catch (
const https_error& error) {
604 message_printer::printError<print_message_type::https>(
"sound_cloud_request_builder::downloadAndStreamAudio() Error: " + jsonifier::string{ error.what() });
605 weFailedToDownloadOrDecode(songNew, threadHandle, currentReconnectTries);
606 areWeWorkingBool.store(
false, std::memory_order_release);
611 jsonifier::vector<song> sound_cloud_api::searchForSong(jsonifier::string_view searchQuery, uint64_t limit) {
612 return collectSearchResults(searchQuery, limit);
615 jsonifier::string sound_cloud_request_builder::clientId{};
The main namespace for the forward-facing interfaces.