SRS源码——调用FFmpeg参数问题

 

在SRS的Ingest功能中,会调用本地FFmpeg进行拉流转码,

调用的核心代码在srs_app_ffmpeg.cpp SrsFFMPEG::start() 中:

    // memory leak in child process, it's ok.
        char** charpv_params = new char*[params.size() + 1];
        for (int i = 0; i < (int)params.size(); i++) {
            std::string& p = params[i];
            charpv_params[i] = (char*)p.data();
        }
        // EOF: NULL
        charpv_params[params.size()] = NULL;
        
        // TODO: execv or execvp
        ret = execv(ffmpeg.c_str(), charpv_params);
        if (ret < 0) {
            fprintf(stderr, "fork ffmpeg failed, errno=%d(%s)", 
                errno, strerror(errno));
        }
        exit(ret);    

 

SrsFFMPEG 这个类提供了一个用户设置额外参数的接口

void SrsFFMPEG::set_iparams(string iparams)
{
    _iparams = iparams;
}

但是是一次性的,也就是只能设置一个参数,

如果你想设置多个,不能用空格的方法隔开,例如我自己就这么写的:

set_iparams("-rtsp_transport tcp");

 结果死活都运行不成功,看log打印出来的参数是完全正确,而且我用同样的参数手动运行FFmpeg也是对的。

折腾了半天,最后还是通过仔细看代码发现问题所在:

 

重点在叫起 FFmpeg的函数:execv()

int execv(const char *path, char *const argv[]);

 

其参数是用字符串数组的方式存储,而SRS的代码里是直接将你填进去的参数当一个参数写进去,不看你的空格!

也就是说我的 "-rtsp_transport tcp" 在argv里面是这样的 

{"...", "...", "-rtsp_transport tcp", "..."}

是个无效参数,所以只能将其分开写入到存储参数的params变量中。

注意 SrsFFMPEG 并没有提供这样的接口,需要自己修改代码。

 

posted @ 2019-05-31 23:22  MyCPlusPlus  阅读(779)  评论(0编辑  收藏  举报