代码之家  ›  专栏  ›  技术社区  ›  Viewed

如何从popen中获得结果?

  •  0
  • Viewed  · 技术社区  · 1 年前

    我想为程序创建一个小补丁。我对C了解不多。

    当我的功能 get_streamlink 返回 buffer ,下一个代码无法通过获取视频 m3u8 url。当函数返回静态url时,视频显示成功。在这两种情况下,url和下一个代码是相同的。发生了什么?

    UPD:感谢您的评论。问题与 \n fgets .

    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);
    
        //...
    }
    

    enter image description here

    1 回复  |  直到 1 年前
        1
  •  2
  •   Ted Lyngmo    1 年前

    你需要删除尾随 \n / \r\n .

    由于您使用的是非标准函数, _popen ,您还可以使用MSVC中的另一个非标准扩展: basic_ifstream 建设者采取 FILE* 。有了它,你就可以使用 std::getline 在输入流上。

    #include <cstdio>
    #include <fstream>
    #include <iostream>
    #include <string>
    
    std::ifstream Popen(const char* command) {
        auto fp = _popen(command, "rt");
        return std::ifstream(fp);         // construct the ifstream using a FILE*
    }
    
    int main() {
        auto is = Popen("dir");
        std::string line;
        while (std::getline(is, line)) {
            std::cout << line << '\n';
        }
    }