不登录下载视频

1.抓包链接

1
https://ali-safety-video.acfun.cn/mediacloud/acfun/acfun_video/066a751af6d398da-87724884d9fd564ed2a3ab0dfdeba437-hls_720p_hevc_1.00005.ts?pkey=ABDiVCOe0GTSwXIaXKU8JXzAlFEdzU_jSgIZ55eS7qsvNCXUT2E5wthCwxN_cnliBWFQl5S8iINNPG4SOY62sWurFl4qX6cHpg5WYQx2VU2oOTmBnGBEqvyZ0Hiq_vdyW0rdJePqkV0Tb0qlRE2lpsWDtjU2rR_Aai29WJWDAy3vMaRtzm4jj_qWvKlcPZb13-VH3OA6PJz56-o_INy0WRW4McmYij6RsCQetFEYIodtCAxvZ1Y3CML6JPeP2g-GMT0&safety_id=AAJlC8jno2sethEJ78jWtt-t

2。编写代码下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <curl/curl.h>

// 回调函数,用于写入接收到的数据到文件
size_t write_data(void* ptr, size_t size, size_t nmemb, FILE* stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}

int main(void) {
CURL* curl;
CURLcode res;
long response_code = 0;
struct curl_slist* headers = NULL;
FILE* fp;

// 初始化libcurl
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
// 打开文件用于写入
fp = fopen("video.mp4", "wb");
if (!fp) {
fprintf(stderr, "Could not open file for writing\n");
return 1;
}

// 设置要访问的网址
curl_easy_setopt(curl, CURLOPT_URL, "https://ali-safety-video.acfun.cn/mediacloud/acfun/acfun_video/066a751af6d398da-87724884d9fd564ed2a3ab0dfdeba437-hls_720p_hevc_1.00005.ts?pkey=ABDiVCOe0GTSwXIaXKU8JXzAlFEdzU_jSgIZ55eS7qsvNCXUT2E5wthCwxN_cnliBWFQl5S8iINNPG4SOY62sWurFl4qX6cHpg5WYQx2VU2oOTmBnGBEqvyZ0Hiq_vdyW0rdJePqkV0Tb0qlRE2lpsWDtjU2rR_Aai29WJWDAy3vMaRtzm4jj_qWvKlcPZb13-VH3OA6PJz56-o_INy0WRW4McmYij6RsCQetFEYIodtCAxvZ1Y3CML6JPeP2g-GMT0&safety_id=AAJlC8jno2sethEJ78jWtt-t");

// 添加请求头
headers = curl_slist_append(headers, "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36");
headers = curl_slist_append(headers, "Accept: */*");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

// 设置回调函数,用于写入数据到文件
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

// 执行请求
res = curl_easy_perform(curl);

// 检查请求是否成功
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
else {
// 获取HTTP响应状态码
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
printf("HTTP Response Status Code: %ld\n", response_code);
}

// 清理
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
fclose(fp);
}

curl_global_cleanup();
return 0;
}

3. 循环下载所有视频片段

使用循环替换00005从00000开始下载所有视频片段,直到网站返回状态码404停止下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <stdio.h>
#include <curl/curl.h>

#define MAX_URL_LEN 512
#define MAX_FILENAME_LEN 32

// 回调函数,用于写入接收到的数据到文件
size_t write_data(void* ptr, size_t size, size_t nmemb, FILE* stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}

int main(void) {
CURL* curl;
CURLcode res;
long response_code = 0;
struct curl_slist* headers = NULL;
FILE* fp;
char url[MAX_URL_LEN];
char filename[MAX_FILENAME_LEN];
int segment = 0;

// 初始化libcurl
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
// 添加请求头
headers = curl_slist_append(headers, "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36");
headers = curl_slist_append(headers, "Accept: */*");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

while (1) {
// 构造视频片段的URL
snprintf(url, MAX_URL_LEN, "https://ali-safety-video.acfun.cn/mediacloud/acfun/acfun_video/066a751af6d398da-87724884d9fd564ed2a3ab0dfdeba437-hls_720p_hevc_1.%05d.ts?pkey=ABDiVCOe0GTSwXIaXKU8JXzAlFEdzU_jSgIZ55eS7qsvNCXUT2E5wthCwxN_cnliBWFQl5S8iINNPG4SOY62sWurFl4qX6cHpg5WYQx2VU2oOTmBnGBEqvyZ0Hiq_vdyW0rdJePqkV0Tb0qlRE2lpsWDtjU2rR_Aai29WJWDAy3vMaRtzm4jj_qWvKlcPZb13-VH3OA6PJz56-o_INy0WRW4McmYij6RsCQetFEYIodtCAxvZ1Y3CML6JPeP2g-GMT0&safety_id=AAJlC8jno2sethEJ78jWtt-t", segment);

// 构造文件名
snprintf(filename, MAX_FILENAME_LEN, "video_%05d.ts", segment);

// 打开文件用于写入
fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Could not open file %s for writing\n", filename);
break;
}

// 设置要访问的网址
curl_easy_setopt(curl, CURLOPT_URL, url);

// 设置回调函数,用于写入数据到文件
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

// 执行请求
res = curl_easy_perform(curl);

// 关闭文件
fclose(fp);

// 检查请求是否成功
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
break;
}
else {
// 获取HTTP响应状态码
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code == 404) {
printf("Segment %05d not found, stopping download.\n", segment);
break;
}
else {
printf("Downloaded segment %05d, HTTP Response Status Code: %ld\n", segment, response_code);
}
}

// 下一个视频片段
segment++;
}

// 清理
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}

curl_global_cleanup();
return 0;
}

3.循环下载所有视频片段到文件夹中后合并视频

  1. 编写代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>

#define MAX_URL_LEN 512
#define MAX_FILENAME_LEN 64
#define VIDEO_FOLDER "videos"
#pragma warning(disable:4996)

// 回调函数,用于写入接收到的数据到文件
size_t write_data(void* ptr, size_t size, size_t nmemb, FILE* stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}

// 创建文件夹
void create_folder(const char* folder) {
char command[MAX_FILENAME_LEN + 10];
snprintf(command, sizeof(command), "mkdir %s", folder);
system(command);
}

// 合并视频片段
void merge_videos(const char* folder, int total_segments) {
FILE* merge_file = fopen("merged_video.ts", "wb");
char segment_filename[MAX_FILENAME_LEN];
FILE* segment_file;
char buffer[8192];
size_t bytes;

if (!merge_file) {
fprintf(stderr, "Could not open file merged_video.ts for writing\n");
return;
}

for (int i = 0; i < total_segments; i++) {
snprintf(segment_filename, MAX_FILENAME_LEN, "%s/video_%05d.ts", folder, i);
segment_file = fopen(segment_filename, "rb");
if (!segment_file) {
fprintf(stderr, "Could not open segment file %s for reading\n", segment_filename);
continue;
}

while ((bytes = fread(buffer, 1, sizeof(buffer), segment_file)) > 0) {
fwrite(buffer, 1, bytes, merge_file);
}

fclose(segment_file);
}

fclose(merge_file);
}

int main(void) {
CURL* curl;
CURLcode res;
long response_code = 0;
struct curl_slist* headers = NULL;
FILE* fp;
char url[MAX_URL_LEN];
char filename[MAX_FILENAME_LEN];
int segment = 0;

// 初始化libcurl
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
// 创建文件夹
create_folder(VIDEO_FOLDER);

// 添加请求头
headers = curl_slist_append(headers, "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36");
headers = curl_slist_append(headers, "Accept: */*");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

while (1) {
// 构造视频片段的URL
snprintf(url, MAX_URL_LEN, "https://ali-safety-video.acfun.cn/mediacloud/acfun/acfun_video/066a751af6d398da-87724884d9fd564ed2a3ab0dfdeba437-hls_720p_hevc_1.%05d.ts?pkey=ABDiVCOe0GTSwXIaXKU8JXzAlFEdzU_jSgIZ55eS7qsvNCXUT2E5wthCwxN_cnliBWFQl5S8iINNPG4SOY62sWurFl4qX6cHpg5WYQx2VU2oOTmBnGBEqvyZ0Hiq_vdyW0rdJePqkV0Tb0qlRE2lpsWDtjU2rR_Aai29WJWDAy3vMaRtzm4jj_qWvKlcPZb13-VH3OA6PJz56-o_INy0WRW4McmYij6RsCQetFEYIodtCAxvZ1Y3CML6JPeP2g-GMT0&safety_id=AAJlC8jno2sethEJ78jWtt-t", segment);

// 构造文件名
snprintf(filename, MAX_FILENAME_LEN, "%s/video_%05d.ts", VIDEO_FOLDER, segment);

// 打开文件用于写入
fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Could not open file %s for writing\n", filename);
break;
}

// 设置要访问的网址
curl_easy_setopt(curl, CURLOPT_URL, url);

// 设置回调函数,用于写入数据到文件
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

// 执行请求
res = curl_easy_perform(curl);

// 关闭文件
fclose(fp);

// 检查请求是否成功
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
break;
}
else {
// 获取HTTP响应状态码
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code == 404) {
printf("Segment %05d not found, stopping download.\n", segment);
break;
}
else {
printf("Downloaded segment %05d, HTTP Response Status Code: %ld\n", segment, response_code);
}
}

// 下一个视频片段
segment++;
}

// 合并视频片段
merge_videos(VIDEO_FOLDER, segment);

// 清理
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}

curl_global_cleanup();
return 0;
}
  1. 编译后运行。

    得到完整视频并成功播放

4.合并后删除所有视频片段,只保留合并好的视频文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <windows.h>
#include <tchar.h>

#pragma warning(disable:4996)

#define MAX_URL_LEN 512
#define MAX_FILENAME_LEN 64
#define VIDEO_FOLDER "videos"

// 回调函数,用于写入接收到的数据到文件
size_t write_data(void* ptr, size_t size, size_t nmemb, FILE* stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}

// 创建文件夹
void create_folder(const char* folder) {
CreateDirectory(folder, NULL);
}

// 合并视频片段
void merge_videos(const char* folder, int total_segments) {
FILE* merge_file = fopen("merged_video.ts", "wb");
char segment_filename[MAX_FILENAME_LEN];
FILE* segment_file;
char buffer[8192];
size_t bytes;

if (!merge_file) {
fprintf(stderr, "Could not open file merged_video.ts for writing\n");
return;
}

for (int i = 0; i < total_segments; i++) {
snprintf(segment_filename, MAX_FILENAME_LEN, "%s/video_%05d.ts", folder, i);
segment_file = fopen(segment_filename, "rb");
if (!segment_file) {
fprintf(stderr, "Could not open segment file %s for reading\n", segment_filename);
continue;
}

while ((bytes = fread(buffer, 1, sizeof(buffer), segment_file)) > 0) {
fwrite(buffer, 1, bytes, merge_file);
}

fclose(segment_file);
}

fclose(merge_file);
}

// 删除视频片段
void delete_segments(const char* folder, int total_segments) {
char segment_filename[MAX_FILENAME_LEN];
for (int i = 0; i < total_segments; i++) {
snprintf(segment_filename, MAX_FILENAME_LEN, "%s/video_%05d.ts", folder, i);
if (remove(segment_filename) != 0) {
fprintf(stderr, "Error deleting file %s\n", segment_filename);
}
}
}

// 删除文件夹及其内容
void delete_folder(const char* folder) {
WIN32_FIND_DATA find_file_data;
HANDLE h_find = INVALID_HANDLE_VALUE;
char directory_search[MAX_FILENAME_LEN];

snprintf(directory_search, MAX_FILENAME_LEN, "%s\\*.*", folder);

h_find = FindFirstFile(directory_search, &find_file_data);

if (h_find == INVALID_HANDLE_VALUE) {
return;
}

do {
char path[MAX_FILENAME_LEN];
snprintf(path, sizeof(path), "%s\\%s", folder, find_file_data.cFileName);

if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (strcmp(find_file_data.cFileName, ".") != 0 && strcmp(find_file_data.cFileName, "..") != 0) {
delete_folder(path);
}
}
else {
remove(path);
}
} while (FindNextFile(h_find, &find_file_data) != 0);

FindClose(h_find);
RemoveDirectory(folder);
}

int main(void) {
CURL* curl;
CURLcode res;
long response_code = 0;
struct curl_slist* headers = NULL;
FILE* fp;
char url[MAX_URL_LEN];
char filename[MAX_FILENAME_LEN];
int segment = 0;

// 初始化libcurl
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
// 创建文件夹
create_folder(VIDEO_FOLDER);

// 添加请求头
headers = curl_slist_append(headers, "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36");
headers = curl_slist_append(headers, "Accept: */*");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

while (1) {
// 构造视频片段的URL
snprintf(url, MAX_URL_LEN, "https://ali-safety-video.acfun.cn/mediacloud/acfun/acfun_video/066a751af6d398da-87724884d9fd564ed2a3ab0dfdeba437-hls_720p_hevc_1.%05d.ts?pkey=ABDiVCOe0GTSwXIaXKU8JXzAlFEdzU_jSgIZ55eS7qsvNCXUT2E5wthCwxN_cnliBWFQl5S8iINNPG4SOY62sWurFl4qX6cHpg5WYQx2VU2oOTmBnGBEqvyZ0Hiq_vdyW0rdJePqkV0Tb0qlRE2lpsWDtjU2rR_Aai29WJWDAy3vMaRtzm4jj_qWvKlcPZb13-VH3OA6PJz56-o_INy0WRW4McmYij6RsCQetFEYIodtCAxvZ1Y3CML6JPeP2g-GMT0&safety_id=AAJlC8jno2sethEJ78jWtt-t", segment);

// 构造文件名
snprintf(filename, MAX_FILENAME_LEN, "%s/video_%05d.ts", VIDEO_FOLDER, segment);

// 打开文件用于写入
fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Could not open file %s for writing\n", filename);
break;
}

// 设置要访问的网址
curl_easy_setopt(curl, CURLOPT_URL, url);

// 设置回调函数,用于写入数据到文件
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

// 执行请求
res = curl_easy_perform(curl);

// 关闭文件
fclose(fp);

// 检查请求是否成功
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
break;
}
else {
// 获取HTTP响应状态码
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code == 404) {
printf("Segment %05d not found, stopping download.\n", segment);
break;
}
else {
printf("Downloaded segment %05d, HTTP Response Status Code: %ld\n", segment, response_code);
}
}

// 下一个视频片段
segment++;
}

// 合并视频片段
merge_videos(VIDEO_FOLDER, segment);

// 删除视频片段
delete_segments(VIDEO_FOLDER, segment);

// 删除文件夹
delete_folder(VIDEO_FOLDER);

// 清理
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}

curl_global_cleanup();
return 0;
}