如何通过popen获取结果?C语言get_streamlink返回buffer失效问题排查
问题:动态获取的M3U8 URL无法播放,静态URL正常?
我想给某个程序写个小补丁,但C语言功底一般。现在遇到个问题:我的get_streamlink函数返回动态读取到的buffer时,后续代码没法通过这个M3U8 URL加载视频;但直接返回静态写死的URL时,视频就能正常播放。两种情况用的URL内容和后续代码完全一致,这是怎么回事?
更新:感谢各位评论,问题找到了——是fgets读取时带回的换行符\n搞的鬼。
相关代码
static char *get_streamlink(const char *url) { char *template = "streamlink %s best --stream-url"; char *buffer = (char *)malloc(5060); FILE *pPipe; struct dstr command = {0}; dstr_catf(&command, template, url); pPipe = _popen(command.array, "rt"); dstr_free(&command); while (fgets(buffer, 5060, pPipe)) { puts(buffer); } int endOfFileVal = feof(pPipe); int closeReturnVal = _pclose(pPipe); // failed return buffer; // OK // return "https://video-weaver.arn03.hls.ttvnw.net/v1/playlist/CvAEXGd8OH7.....m3u8"; } static void add_file(struct vlc_source *c, media_file_array_t *new_files, const char *path, int network_caching, int track_index, int subtitle_index, bool subtitle_enable, const char *hw_value, bool skip_b_frames) { struct media_file_data data; struct dstr new_path = {0}; libvlc_media_t *new_media; bool is_url = path && strstr(path, "://") != NULL; dstr_copy(&new_path, path); #ifdef _WIN32 if (!is_url) dstr_replace(&new_path, "/", "\\"); #endif dstr_copy(&new_path, get_streamlink(new_path.array)); path = new_path.array; new_media = get_media(&c->files, path); //... }
命令行输出截图

问题分析与解决办法
问题核心就是fgets的行为:它会把读取到的换行符\n也写入到buffer中。静态URL里没有这个多余的换行符,所以视频加载逻辑能正常识别;但带换行符的URL会被判定为无效地址,导致加载失败。
具体修正步骤:
- 移除换行符:在返回buffer之前,检查并去掉末尾的换行符,添加这段代码:
// 去除buffer末尾的换行符 size_t buf_len = strlen(buffer); if (buf_len > 0 && buffer[buf_len - 1] == '\n') { buffer[buf_len - 1] = '\0'; }
- 优化读取逻辑:原代码的
while(fgets(...))循环会反复覆盖buffer,最后只保留最后一行内容。如果streamlink只会输出一行URL,直接改成单次读取更合理:
// 替换原while循环,仅读取第一行结果 if (fgets(buffer, 5060, pPipe)) { puts(buffer); }
内容的提问来源于stack exchange,提问作者Viewed
相关产品推荐
相关产品推荐

