SRS启动流程

main函数

main函数所在文件为main/srs_main_server.cpp中。

该文件定义了一些全局变量:

  • _srs_log:全局的log文件
  • _srs_context:全局的context文件。是一个SrsThreadContext类,这个类使用map来存放协程指针到id的映射关系。std::map<srs_thread_t, int> cache;
  • _srs_config:全局配置文件

执行流程如图:
SRS执行流程

run_master

程序进入run_master。在该函数中,服务器做一些初始化工作并调用listern监听客户端的连接,然后调用do_cycle函数(死循环),做一些监控,更新时间及缓存等。

执行流程如图:

SRS_run_master

代码分析如下:

//run()调用run_master(),启动
srs_error_t run_master(SrsServer* svr)
{
    srs_error_t err = srs_success;
    //初始化st
    if ((err = svr->initialize_st()) != srs_success) {
        return srs_error_wrap(err, "initialize st");
    }
    //初始化signal:创建signal pipe
    if ((err = svr->initialize_signal()) != srs_success) {
        return srs_error_wrap(err, "initialize signal");
    }
    //将pid线程写进文件
    if ((err = svr->acquire_pid_file()) != srs_success) {
        return srs_error_wrap(err, "acquire pid file");
    }
    //监听客户端请求
    if ((err = svr->listen()) != srs_success) {
        return srs_error_wrap(err, "listen");
    }
    //注册信号(开启了新的协程)
    if ((err = svr->register_signal()) != srs_success) {
        return srs_error_wrap(err, "register signal");
    }
    //undo
    if ((err = svr->http_handle()) != srs_success) {
        return srs_error_wrap(err, "http handle");
    }
    //undo
    if ((err = svr->ingest()) != srs_success) {
        return srs_error_wrap(err, "ingest");
    }
    //服务器的循环
    if ((err = svr->cycle()) != srs_success) {
        return srs_error_wrap(err, "main cycle");
    }
    
    return err;
}
do_cycle
srs_error_t SrsServer::do_cycle()
{
    srs_error_t err = srs_success;
    
    // find the max loop
    int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES);
    
#ifdef SRS_AUTO_STAT
    max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_DISK_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES);
#endif
    // for asprocess.
    bool asprocess = _srs_config->get_asprocess();
    
    // the deamon thread, update the time cache
    while (true) {
        //这里handle为NULL
        if (handler && (err = handler->on_cycle()) != srs_success) {
            return srs_error_wrap(err, "handle callback");
        }
        
        // the interval in config. default=9.9
        int heartbeat_max_resolution = (int)(_srs_config->get_heartbeat_interval() / SRS_SYS_CYCLE_INTERVAL);
        
        // dynamic fetch the max. 1
        int dynamic_max = srs_max(max, heartbeat_max_resolution);
        
        for (int i = 0; i < dynamic_max; i++) {
            //主线程休眠,让出CPU,其他线程如conn接受连接
            srs_usleep(SRS_SYS_CYCLE_INTERVAL * 1000); //1000 * 1000, 1s
            
            // asprocess check.
            if (asprocess && ::getppid() != ppid) {
                return srs_error_new(ERROR_ASPROCESS_PPID, "asprocess ppid changed from %d to %d", ppid, ::getppid());
            }
            
            // gracefully quit for SIGINT or SIGTERM. 收到腿出信号,返回
            if (signal_gracefully_quit) {
                srs_trace("cleanup for gracefully terminate.");
                return err;
            }
            
            // for gperf heap checker,
            // @see: research/gperftools/heap-checker/heap_checker.cc
            // if user interrupt the program, exit to check mem leak.
            // but, if gperf, use reload to ensure main return normally,
            // because directly exit will cause core-dump.
#ifdef SRS_AUTO_GPERF_MC
            if (signal_gmc_stop) {
                srs_warn("gmc got singal to stop server.");
                return err;
            }
#endif
            
            // do persistence config to file.
            if (signal_persistence_config) {
                signal_persistence_config = false;
                srs_info("get signal to persistence config to file.");
                
                if ((err = _srs_config->persistence()) != srs_success) {
                    return srs_error_wrap(err, "config persistence to file");
                }
                srs_trace("persistence config to file success.");
            }
            
            // do reload the config. 重新加载配置的信号
            if (signal_reload) {
                signal_reload = false;
                srs_info("get signal to reload the config.");
                
                if ((err = _srs_config->reload()) != srs_success) {
                    return srs_error_wrap(err, "config reload");
                }
                srs_trace("reload config success.");
            }
            
            // notice the stream sources to cycle. 流资源循环
            if ((err = SrsSource::cycle_all()) != srs_success) {
                return srs_error_wrap(err, "source cycle");
            }
            
            // update the cache time 事件缓存
            if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) {
                srs_info("update current time cache.");
                srs_update_system_time_ms();
            }
            
#ifdef SRS_AUTO_STAT
            if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) {
                srs_info("update resource info, rss.");
                srs_update_system_rusage();
            }
            if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) {
                srs_info("update cpu info, cpu usage.");
                srs_update_proc_stat();
            }
            if ((i % SRS_SYS_DISK_STAT_RESOLUTION_TIMES) == 0) {
                srs_info("update disk info, disk iops.");
                srs_update_disk_stat();
            }
            if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) {
                srs_info("update memory info, usage/free.");
                srs_update_meminfo();
            }
            if ((i % SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES) == 0) {
                srs_info("update platform info, uptime/load.");
                srs_update_platform_info();
            }
            if ((i % SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES) == 0) {
                srs_info("update network devices info.");
                srs_update_network_devices();
            }
            if ((i % SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES) == 0) {
                srs_info("update network server kbps info.");
                resample_kbps();
            }
            if (_srs_config->get_heartbeat_enabled()) {
                if ((i % heartbeat_max_resolution) == 0) {
                    srs_info("do http heartbeat, for internal server to report.");
                    http_heartbeat->heartbeat();
                }
            }
#endif
            
            srs_info("server main thread loop");
        }
    }
    
    return err;
}
<think>好的,用户之前询问了如何在CentOS系统上部署流媒体服务器,我给出了两种方案,包括Nginx RTMP模块和SRS。现在用户又要求提供一个完整的SRS流程,我需要详细说明SRS的安装、配置和使用步骤。 首先,用户可能对SRS不太熟悉,需要先简要介绍SRS是什么,以及它的优势,比如轻量级、支持多种协议等。接着,要分步骤指导,确保用户能一步步操作。 用户之前的问题已经涉及到了系统准备和基础依赖的安装,但可能需要重复这部分内容,因为新的问题专门针对SRS,所以应该包含完整的流程,避免用户需要回看之前的回答。要确保所有步骤都是连贯的,从系统更新开始,安装依赖,下载SRS源码,编译安装,配置,启动服务,再到推流和播放的测试。 还要注意用户可能的实际应用场景,比如直播或点播,是否需要HLS或HTTP-FLV的支持,因此需要包含这些配置选项。同时,用户可能关心安全性和性能优化,比如防火墙设置、鉴权、SSL等,这些需要作为注意事项提到。 另外,用户可能需要验证服务是否正常运行,所以需要包含检查进程和查看日志的方法。最后,常见问题处理可以帮助用户自行解决一些可能遇到的问题,比如端口冲突或推流失败的情况。 需要确保命令准确,特别是下载链接和配置文件的路径,避免用户复制时出错。同时,用中文清晰解释每个步骤的目的,比如为什么需要安装FFmpeg,如何修改配置参数等。这样用户不仅能按步骤操作,还能理解背后的原理,方便后续的调整和优化。</think>以下是基于 **SRS(Simple RTMP Server)** 在 CentOS 系统上部署流媒体服务器的完整流程: --- ### 一、系统准备 1. **更新系统与安装依赖** ```bash sudo yum update -y sudo yum install epel-release git gcc make perl openssl-devel -y ``` 2. **安装 FFmpeg(用于推流测试或转码)** ```bash sudo yum install ffmpeg ffmpeg-devel -y ``` --- ### 二、SRS 安装 1. **克隆 SRS 源码** ```bash git clone https://github.com/ossrs/srs.git cd srs/trunk ``` 2. **编译与安装** ```bash ./configure --prefix=/usr/local/srs --with-ssl --with-hls --with-http-api make sudo make install ``` --- ### 三、SRS 配置 1. **基础 RTMP 配置** 编辑配置文件 `/usr/local/srs/conf/srs.conf`: ```conf listen 1935; max_connections 1000; pid /usr/local/srs/objs/srs.pid; daemon on; vhost __defaultVhost__ { enabled on; # RTMP 直播配置 rtmp { enabled on; } # HTTP-FLV 支持(Web播放) http_remux { enabled on; mount [vhost]/[app]/[stream].flv; } # HLS 支持(录播切片) hls { enabled on; hls_path ./objs/nginx/html/hls; hls_fragment 10; hls_window 60; } } ``` --- ### 四、启动 SRS 服务 1. **启动命令** ```bash cd /usr/local/srs ./objs/srs -c conf/srs.conf ``` 2. **验证进程状态** ```bash ps aux | grep srs ``` 3. **查看日志(排查问题)** ```bash tail -f ./objs/srs.log ``` --- ### 五、防火墙开放端口 ```bash sudo firewall-cmd --permanent --add-port=1935/tcp # RTMP 推流/拉流 sudo firewall-cmd --permanent --add-port=8080/tcp # HTTP-FLV/HLS 播放 sudo firewall-cmd --reload ``` --- ### 六、推流与播放测试 1. **推流(使用 FFmpeg)** ```bash ffmpeg -re -i input.mp4 -c copy -f flv rtmp://服务器IP/live/stream_key ``` 2. **播放方式** - **RTMP 拉流** ```bash ffplay rtmp://服务器IP/live/stream_key ``` - **HTTP-FLV 播放** ```bash ffplay http://服务器IP:8080/live/stream_key.flv ``` - **HLS 播放** ```bash ffplay http://服务器IP:8080/hls/stream_key.m3u8 ``` --- ### 七、高级功能配置(可选) 1. **鉴权配置** 在 `srs.conf` 中添加 Token 验证: ```conf vhost __defaultVhost__ { http_remux { enabled on; mount [vhost]/[app]/[stream].flv; auth { enabled on; secret your_secret_key; } } } ``` 2. **SSL 加密(RTMPS)** - 生成证书: ```bash openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout srs.key -out srs.crt ``` - 修改配置: ```conf listen 1935 ssl; ssl_certificate /path/to/srs.crt; ssl_certificate_key /path/to/srs.key; ``` --- ### 八、常见问题处理 1. **端口冲突** 检查 `1935` 或 `8080` 是否被占用: ```bash netstat -tunlp | grep 1935 ``` 2. **推流失败** 检查 SRS 日志和防火墙配置,确保推流地址格式正确(`rtmp://IP/app/stream`)。 3. **HLS 切片未生成** 确认 `hls_path` 目录权限: ```bash chmod 755 /usr/local/srs/objs/nginx/html/hls ``` --- ### 九、服务管理 1. **停止 SRS** ```bash kill -TERM $(cat /usr/local/srs/objs/srs.pid) ``` 2. **开机自启** 创建 Systemd 服务文件 `/etc/systemd/system/srs.service`: ```conf [Unit] Description=SRS Streaming Server After=network.target [Service] Type=forking ExecStart=/usr/local/srs/objs/srs -c /usr/local/srs/conf/srs.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID [Install] WantedBy=multi-user.target ``` 启用服务: ```bash sudo systemctl daemon-reload sudo systemctl enable srs sudo systemctl start srs ``` --- 通过以上步骤,您将完成 SRS 流媒体服务器的完整部署,支持 RTMP 直播、HLS 录播和 HTTP-FLV 低延迟播放,并可扩展鉴权、SSL 等安全功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值