Advertisement
camilosasuketbs

Untitled

Jan 9th, 2023
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.81 KB | None | 0 0
  1. #include <Windows.h>
  2. #include <fstream>
  3. #include <iostream>
  4. #include <array>
  5. #include <string>
  6. #include <vector>
  7. #include <regex>
  8. #include <chrono>
  9. #include "gumbo.h"
  10. #include <cpr/cpr.h>
  11.  
  12. extern "C"
  13. {
  14. #include <libavformat/avformat.h>
  15. #include <libavcodec/avcodec.h>
  16. #include <libavutil/avutil.h>
  17. #include <libswscale/swscale.h>
  18. }
  19.  
  20. std::string protocols{ "file,http,https,tls,tcp" };
  21.  
  22. class av_packet_pointer
  23. {
  24. public:
  25.  
  26. AVPacket * m_p;
  27.  
  28. av_packet_pointer()
  29. {
  30.  
  31. m_p = av_packet_alloc();
  32.  
  33. }
  34.  
  35.  
  36. ~av_packet_pointer()
  37. {
  38. av_packet_free(&m_p);
  39.  
  40. }
  41.  
  42. operator AVPacket * () { return m_p; }
  43.  
  44. AVPacket * operator ->() { return m_p; }
  45.  
  46. };
  47.  
  48. int main(int argc, char * argv[])
  49. {
  50. // Set the URL of the live stream website
  51. std::string url = "https://www.twitch.tv/ca2software";
  52. auto r = cpr::Get(cpr::Url{ url });
  53.  
  54. //// Check the status code to ensure the request was successful
  55. //if (r.status_code == 200) {
  56. // // Parse the website data using Gumbo
  57. // GumboOutput* output = gumbo_parse(r.text.c_str());
  58. // // Find all of the <a> elements in the document
  59. // std::vector<GumboNode*> anchors;
  60. // GumboVector* anchor_vector = &output->root->v.element.children;
  61. // for (unsigned int i = 0; i < anchor_vector->length; ++i) {
  62. // GumboNode* node = static_cast<GumboNode*>(anchor_vector->data[i]);
  63. // if (node->type == GUMBO_NODE_ELEMENT &&
  64. // node->v.element.tag == GUMBO_TAG_A) {
  65. // anchors.push_back(node);
  66. // }
  67. // }
  68. // Find the <a> element with the M3U8 manifest file URL
  69. std::string manifest_url{ "https://video-weaver.lhr08.hls.ttvnw.net/v1/playlist/CqgFUF8AHWpIPV_PDqy-Nzef7Kfax0IWeQyjfzMZr7moMc7uYmyAUxO4xbUcUWg1zjx-8sWpqCwHGm84aeoU2Gz8u-0AqDYvs8G8JbR2lFUjH0FK_XRl17E2MAy3vjurpR-fMPSjzsorM2yj0D0UPSEwCUPYlYsv-bpbbbnBmrUAgwz5HbHpR-MsTL_NiG-nxiQ1EQmaDdezmKGtAJlkJsf170ImzyvI8MOMl1tWfj0Mx-GIp8B6uarF4JcCpWQxGPWGUiU0w3P9WK-FkvzfdutL0ETHsdpZlxe46FL3YKCSwhykIapLCQEGG9JBZeyVTEY74ETd7m6qtP71wvln0E5l7Po4Awrsb5owkGcbK41H5D-MxrbX9zoBLQfywH0Jj8zEWAfPnICrgmyKEdFMHoSoLVbgtFyPv_KQjMVPq2rBMqtLYINKucN_CsSAQraNaZqTHoBa64p_JwCxmREL8Trlvc9EOpRcBMhITkS3en9056bPOgCwU0JaWdkkv89JVMFdMjH2wfEWu5wurJ9WpKrgRH1nbfhMwlueM8sg6BpQdJ4lnqa9kC9YD2pCp40oVzKoiiY6gcW3jTP1y8ayWCkLXZr-rnUlP5xT9SYXbYt7Tn89ea_5WbL9Rm2VJiPo63NjwW91xz3BNNEpqaF-4rDkqQ6KR2K4MmZ8MVVcXjwWd5uk0QisLiyihzf1DjQr4dvvsNpSZ0e64wwRw7tXPtSJO5iDrknRRMvmWFO5IMD9OMRjviqaw25H0VFFnxwh8kZ82dimrgXYxyR2VYuOaBr2HAak9-iXheNjJWV1v14TEk4DZ7QlJ4-2GsAAnz7kRPCKc6MVJiCXM2Z_kiFxBvGck4S1_7LUewFs9Ojjf_3xMBnSwcGsQiTFJkwg63EgZvHf7WNsa6UTXVsaDOaCWtwiXNlqkV-_jyABKgl1cy1lYXN0LTEwgAQ.m3u8" };
  70. /*for (const auto& anchor : anchors) {
  71. GumboAttribute* href = gumbo_get_attribute(&anchor->v.element.attributes, "href");
  72. if (href && strlen(href->value) > 4 && std::string(href->value).compare(strlen(href->value) - 4, 4, ".m3u8") == 0)
  73. {
  74. manifest_url = href->value;
  75. break;
  76. }
  77. }*/
  78. // Download the manifest file if a URL was found
  79. if (!manifest_url.empty()) {
  80. r = cpr::Get(cpr::Url{ manifest_url });
  81.  
  82. // Check the status code to ensure the request was successful
  83. if (r.status_code == 200)
  84. {
  85. // Save the manifest file data to a string
  86. std::string manifest = r.text;
  87. // Extract the URLs of the media files from the manifest file data
  88. std::regex media_url_regex(R"(https://[^\s,"]+.ts)");
  89. std::sregex_iterator it(manifest.begin(), manifest.end(), media_url_regex);
  90. std::sregex_iterator end;
  91. std::vector<std::string> media_urls;
  92.  
  93. while (it != end) {
  94. media_urls.push_back(it->str());
  95. ++it;
  96. }
  97.  
  98. // Initialize the FFmpeg libraries
  99. avformat_network_init();
  100. // Open the output MP4 file for writing
  101. AVFormatContext * output_format_context = NULL;
  102. avformat_alloc_output_context2(&output_format_context, NULL, NULL, "output.mp4");
  103. AVStream * output_video_stream = avformat_new_stream(output_format_context, NULL);
  104. const AVCodec * output_video_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
  105. AVCodecContext * output_video_codec_context = avcodec_alloc_context3(output_video_codec);
  106. output_video_codec_context->width = 1280;
  107. output_video_codec_context->height = 720;
  108. avcodec_parameters_from_context(output_video_stream->codecpar, output_video_codec_context);
  109. av_dump_format(output_format_context, 0, "R:\\LiveStream\\output.mp4", 1);
  110. if (avio_open(&output_format_context->pb, "R:\\LiveStream\\output.mp4", AVIO_FLAG_WRITE) < 0) {
  111. std::cerr << "Failed to open output file" << std::endl;
  112. return 1;
  113. }
  114. avformat_write_header(output_format_context, NULL);
  115.  
  116.  
  117. int fileIterator{ 0 };
  118. // Loop through the media file URLs and download and write each one
  119. for (const auto & media_url : media_urls) {
  120. // Download the media file
  121. r = cpr::Get(cpr::Url{ media_url });
  122. // Check the status code to ensure the request was successful
  123. if (r.status_code != 200) {
  124. std::cerr << "Failed to download media file" << std::endl;
  125. return 1;
  126. }
  127.  
  128. // Save the media file data to a string
  129. std::string media_data = r.text;
  130. // Save the media file data to a temporary file
  131.  
  132. //std::string filename = std::to_string(++fileIterator) + ".ts";
  133. std::ofstream tmp_file("tmp.ts", std::ios::binary);
  134. tmp_file.write(media_data.c_str(), media_data.length());
  135. tmp_file.close();
  136.  
  137. // Open the temporary TS file for reading
  138. AVFormatContext * input_format_context = avformat_alloc_context();
  139. input_format_context->protocol_whitelist = protocols.data();
  140. avformat_open_input(&input_format_context, "tmp.ts", NULL, NULL);
  141. avformat_find_stream_info(input_format_context, NULL);
  142.  
  143. // Find the first video stream in the file
  144. int video_stream_index = -1;
  145. for (unsigned int i = 0; i < input_format_context->nb_streams; i++) {
  146. if (input_format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
  147. video_stream_index = i;
  148. break;
  149. }
  150. }
  151. if (video_stream_index == -1) {
  152. std::cerr << "Failed to find video stream in media file" << std::endl;
  153. return 1;
  154. }
  155.  
  156. // Open the video codec for the stream
  157. const AVCodec * input_video_codec = avcodec_find_decoder(input_format_context->streams[video_stream_index]->codecpar->codec_id);
  158. AVCodecContext * input_video_codec_context = avcodec_alloc_context3(input_video_codec);
  159. avcodec_parameters_to_context(input_video_codec_context, input_format_context->streams[video_stream_index]->codecpar);
  160. avcodec_open2(input_video_codec_context, input_video_codec, NULL);
  161. // Allocate memory for the decoded video frame
  162. AVFrame * input_video_frame = av_frame_alloc();
  163. if (!input_video_frame)
  164. {
  165. std::cerr << "Failed to allocate input frame\n";
  166. return 1;
  167. }
  168.  
  169. AVFrame * output_video_frame = av_frame_alloc();
  170. if (!output_video_frame)
  171. {
  172. std::cerr << "Failed to allocate output frame\n";
  173. return -1;
  174. }
  175.  
  176. // Encode and write the frame
  177. av_packet_pointer packet{};
  178.  
  179.  
  180. //if (!packet) {
  181. // // Handle packet allocation failure
  182. // std::cerr << "Failed to allocate packet!\n";
  183. //}
  184. //else
  185. //{
  186. //
  187. //}
  188. // Define the scaling context
  189. struct SwsContext * sws_context = nullptr;
  190.  
  191. // Decode and write the video frames
  192. while (true)
  193. {
  194.  
  195. auto res = av_read_frame(input_format_context, packet);
  196.  
  197. if (res < 0)
  198. {
  199.  
  200. break;
  201.  
  202. }
  203.  
  204. if (packet->size <= 0)
  205. {
  206. break;
  207.  
  208. }
  209. if (packet->stream_index == video_stream_index)
  210. {
  211. // Send the packet to the decoder
  212. int result = avcodec_send_packet(input_video_codec_context, packet);
  213. if (result < 0) {
  214. std::cerr << "Failed to send packet to decoder" << std::endl;
  215. return 1;
  216. }
  217. packet->size -= result;
  218. packet->data += result;
  219.  
  220. // Receive a decoded frame from the decoder
  221. result = avcodec_receive_frame(input_video_codec_context, input_video_frame);
  222. if (result == AVERROR(EAGAIN) || result == AVERROR_EOF) {
  223. // No frame was produced, continue decoding
  224. continue;
  225. }
  226. else if (result < 0) {
  227. std::cerr << "Failed to receive frame from decoder" << std::endl;
  228. return 1;
  229. }
  230.  
  231.  
  232. if (sws_context == nullptr)
  233. {
  234.  
  235. sws_context = sws_getContext(input_video_codec_context->width, input_video_codec_context->height, input_video_codec_context->pix_fmt,
  236. output_video_codec_context->width, output_video_codec_context->height, output_video_codec_context->pix_fmt,
  237. SWS_BICUBIC, NULL, NULL, NULL);
  238.  
  239. }
  240.  
  241. // Write the decoded frame to the output file if one was received
  242. if (result >= 0)
  243. {
  244. // Convert the frame to the desired format if necessary
  245. sws_scale(sws_context, input_video_frame->data, input_video_frame->linesize, 0, input_video_codec_context->height, output_video_frame->data, output_video_frame->linesize);
  246.  
  247. // Set the frame's pts value
  248. output_video_frame->pts = av_rescale_q(input_video_frame->pts, input_format_context->streams[video_stream_index]->time_base, output_video_stream->time_base);
  249.  
  250. // Encode and write the frame
  251. av_packet_pointer output_packet{};
  252. if (!output_packet) {
  253. // Handle packet allocation failure
  254. std::cerr << "Failed to allocate output_packet!\n";
  255. }
  256.  
  257. int result = avcodec_send_frame(output_video_codec_context, output_video_frame);
  258. if (result < 0) {
  259. std::cerr << "Failed to send frame for encoding" << std::endl;
  260. return 1;
  261. }
  262. result = avcodec_receive_packet(output_video_codec_context, output_packet);
  263. if (result == 0) {
  264. // Set the packet's pts and dts values
  265. output_packet->pts = av_rescale_q(output_packet->pts, output_video_codec_context->time_base, output_video_stream->time_base);
  266. output_packet->dts = av_rescale_q(output_packet->dts, output_video_codec_context->time_base, output_video_stream->time_base);
  267. output_packet->duration = av_rescale_q(output_packet->duration, output_video_codec_context->time_base, output_video_stream->time_base);
  268. output_packet->stream_index = output_video_stream->index;
  269. av_interleaved_write_frame(output_format_context, output_packet);
  270. }
  271. }
  272. }
  273.  
  274. }
  275. // Clean up
  276. av_frame_free(&input_video_frame);
  277. av_frame_free(&output_video_frame);
  278. avcodec_free_context(&input_video_codec_context);
  279. avcodec_free_context(&output_video_codec_context);
  280. avformat_close_input(&input_format_context);
  281. avformat_free_context(output_format_context);
  282. sws_freeContext(sws_context);
  283. }
  284.  
  285. // Write the trailer and close the output file
  286. av_write_trailer(output_format_context);
  287. avio_close(output_format_context->pb);
  288. avformat_free_context(output_format_context);
  289. }
  290. else {
  291. std::cerr << "Failed to download manifest file" << std::endl;
  292. return 1;
  293. }
  294. }
  295. else {
  296. std::cerr << "Failed to download website data" << std::endl;
  297. return 1;
  298. }
  299.  
  300. return 0;
  301. }
  302.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement