srs4.0dvr分支增加按需录像功能

按需录像需求:1. 时延短,接收和执行录像指令的时间要快,100ms以内。2. 录像文件时长不固定,定在[3s, 1800s]这个区间。最短3s,最长30min。

用法:外部进程向redis-queue发送record-start/record-stop指令来控制录像开始和结束。

Cmd格式:start-record|stop-record,, // videoID全局唯一。

redis-queue名称: {app}-{stream}  //rtmp-url格式:rtmp://host:1935/{app}/{stream}

为什么要选srs 4.0release分支呢?因为这个分支分别在centos7.9和debian11下编译,都是成功的,环境兼容性也强。

创建一个自己的srs repo: https://github.com/shitizenlism/srs4.0dvr/tree/4.0release。

fork ossrs/srs.git,跟随4.0release分支。一方面可以merge原分支的更新,自己的修改也不影响原作者的repo。等项目稳定后,再向原作者提交pull request。或者不提交也没关系。

核心函数是

int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)

{

    const char *app= req->app.c_str();

const char *stream=req->stream.c_str();

snprintf(queName,sizeof(queName),"%s-%s",app,stream);

ret=redis_queue_lpop(queName, value);

if (ret==1){

    srs_trace("fetch from redis-que[%s]: %s", queName,value);

      pSubStr[0] = strtok(value, sCut);   //cmd

      pSubStr[1] = strtok(NULL, sCut);    //VideoID

      pSubStr[2] = strtok(NULL, sCut);    //recordFilename

               

      if (!strcmp(pSubStr[0], "start_record")){

          if (segment->current()->duration()>=3){  //录像文件最短3s

             dvr_state = 2; // 状态值:0:init, 1:start, 2: stop.

          } else {

             dvr_state = 1; //

             dvr_saveFilename = pSubStr[2]

}

          …

} else (!strcmp(pSubStr[0], "stop_record"){

    …

}

}

if ((dvr_state==0)||(dvr_state==1))

{

   fragment = segment->current();

   if (fragment->duration() >= cduration) {  //录像文件最长由配置文件dvr.conf决定。

       dvr_state=2;

   }

}

if (dvr_state==2){

   //处理keyframe

}

// reap segment。保存当前录像文件。

if ((err = segment->close(dvr_saveFilename)) != srs_success) {

    srs_error_reset(err);

    return 0;

}

//创建下一个segment

if ((err = segment->open()) != srs_success) {

}

dvr_state=0;

return 1;

}

新增一个配置文件conf/dvr.segment2.conf

[opc@instance-20220112 trunk]$ cat conf/dvr.segment2.conf

listen              1935;

max_connections     1000;

srs_log_tank        console;

srs_log_file        ./logs/dvr.log;

srs_log_level       info;

daemon              off;

redis_server {

    host    127.0.0.1;

    port    6379;

    #pass    123456;

    db     1;

}

vhost __defaultVhost__ {

    dvr {

        enabled      on;

        dvr_path     ./objs/nginx/html/[app]/[stream].[timestamp].mp4;

        dvr_plan     segment;

        dvr_duration    1800;

        dvr_wait_keyframe       on;

    }

}

Make后启动srs进程。

$ ./objs/srs -c conf/dvr.segment2.conf

用obs推流后可以打到dvr.log中打印:

[2023-07-02 23:51:50.933][Trace][21943][4w0j4455] redis_init(127.0.0.1:6379,,db=1),ret=0

[2023-07-02 23:51:50.933][Trace][21943][4w0j4455] redis-server connected!

用redis-cli,发送start_record和stop_record命令。

127.0.0.1:6379[1]> rpush live-test start_record,A001,GB11112222A001

(integer) 1

127.0.0.1:6379[1]> rpush live-test stop_record,A001,GB11112222A001

(integer) 1

127.0.0.1:6379[1]> rpush live-test start_record,A001,GB11112222A002

(integer) 1

127.0.0.1:6379[1]>

打印消息:

[2023-07-02 23:54:02.422][Trace][22468][4966jnrj] fetch from redis-que[live-test]: start_record,A001,GB11112222A002

[2023-07-02 23:54:02.422][Trace][22468][4966jnrj] dvr_saveFilename= GB11112222A001

$ ls objs/nginx/html/live/

GB11112222A001.mp4    //start_record和stop_record之间的录像文件。

test.1688313223719.mp4  //stop_record和next start_stop之间的录像文件。

test.1688313245271.mp4.tmp  //当前录像文件。

你可能感兴趣的:(srs,dvr,录像)