mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #179, refine dvr code to more simple.
This commit is contained in:
parent
3d225e1bc7
commit
95b4baee7c
6 changed files with 609 additions and 429 deletions
|
@ -281,6 +281,12 @@ vhost dvr.srs.com {
|
||||||
# whether enabled dvr features
|
# whether enabled dvr features
|
||||||
# default: off
|
# default: off
|
||||||
enabled on;
|
enabled on;
|
||||||
|
# the dvr plan. canbe:
|
||||||
|
# session reap flv when session end(unpublish).
|
||||||
|
# segment reap flv when flv duration exceed the specified dvr_duration.
|
||||||
|
# api reap flv when api required.
|
||||||
|
# default: session
|
||||||
|
dvr_plan session;
|
||||||
# the dvr output path.
|
# the dvr output path.
|
||||||
# we supports some variables to generate the filename.
|
# we supports some variables to generate the filename.
|
||||||
# [vhost], the vhost of stream.
|
# [vhost], the vhost of stream.
|
||||||
|
@ -314,22 +320,28 @@ vhost dvr.srs.com {
|
||||||
# dvr_path /data/ossrs.net/live/2015/01/livestream-03-10.57.30.776.flv;
|
# dvr_path /data/ossrs.net/live/2015/01/livestream-03-10.57.30.776.flv;
|
||||||
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#custom-path
|
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#custom-path
|
||||||
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#custom-path
|
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#custom-path
|
||||||
|
# segment,session apply it.
|
||||||
|
# api apply before api specified the path.
|
||||||
# default: ./objs/nginx/html
|
# default: ./objs/nginx/html
|
||||||
dvr_path ./objs/nginx/html;
|
dvr_path ./objs/nginx/html;
|
||||||
# the dvr plan. canbe:
|
# the duration for dvr file, reap if exeed, in seconds.
|
||||||
# session reap flv when session end(unpublish).
|
# segment apply it.
|
||||||
# segment reap flv when flv duration exceed the specified dvr_duration.
|
# session,api ignore.
|
||||||
# default: session
|
|
||||||
dvr_plan session;
|
|
||||||
# the param for plan(segment), in seconds.
|
|
||||||
# default: 30
|
# default: 30
|
||||||
dvr_duration 30;
|
dvr_duration 30;
|
||||||
# the param for plan(segment),
|
|
||||||
# whether wait keyframe to reap segment,
|
# whether wait keyframe to reap segment,
|
||||||
# if off, reap segment when duration exceed the dvr_duration,
|
# if off, reap segment when duration exceed the dvr_duration,
|
||||||
# if on, reap segment when duration exceed and got keyframe.
|
# if on, reap segment when duration exceed and got keyframe.
|
||||||
|
# segment apply it.
|
||||||
|
# session,api ignore.
|
||||||
# default: on
|
# default: on
|
||||||
dvr_wait_keyframe on;
|
dvr_wait_keyframe on;
|
||||||
|
# whether dvr auto start when publish.
|
||||||
|
# if off, dvr wait for api to start it.
|
||||||
|
# api apply it.
|
||||||
|
# segment,session ignore.
|
||||||
|
# default: on
|
||||||
|
dvr_autostart on;
|
||||||
# about the stream monotonically increasing:
|
# about the stream monotonically increasing:
|
||||||
# 1. video timestamp is monotonically increasing,
|
# 1. video timestamp is monotonically increasing,
|
||||||
# 2. audio timestamp is monotonically increasing,
|
# 2. audio timestamp is monotonically increasing,
|
||||||
|
@ -340,10 +352,11 @@ vhost dvr.srs.com {
|
||||||
# 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
|
# 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
|
||||||
# 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
|
# 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
|
||||||
# 3. off, disable the time jitter algorithm, like atc.
|
# 3. off, disable the time jitter algorithm, like atc.
|
||||||
|
# apply for all dvr plan.
|
||||||
# default: full
|
# default: full
|
||||||
time_jitter full;
|
time_jitter full;
|
||||||
|
|
||||||
# on_dvr
|
# on_dvr, never config in here, should config in http_hooks.
|
||||||
# for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com
|
# for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com
|
||||||
# @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#http-callback
|
# @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#http-callback
|
||||||
# @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#http-callback
|
# @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#http-callback
|
||||||
|
|
|
@ -1418,6 +1418,7 @@ int SrsConfig::check_config()
|
||||||
string m = conf->at(j)->name.c_str();
|
string m = conf->at(j)->name.c_str();
|
||||||
if (m != "enabled" && m != "dvr_path" && m != "dvr_plan"
|
if (m != "enabled" && m != "dvr_path" && m != "dvr_plan"
|
||||||
&& m != "dvr_duration" && m != "dvr_wait_keyframe" && m != "time_jitter"
|
&& m != "dvr_duration" && m != "dvr_wait_keyframe" && m != "time_jitter"
|
||||||
|
&& m != "dvr_autostart"
|
||||||
) {
|
) {
|
||||||
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
srs_error("unsupported vhost dvr directive %s, ret=%d", m.c_str(), ret);
|
srs_error("unsupported vhost dvr directive %s, ret=%d", m.c_str(), ret);
|
||||||
|
@ -3377,6 +3378,23 @@ bool SrsConfig::get_dvr_wait_keyframe(string vhost)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsConfig::get_dvr_autostart(string vhost)
|
||||||
|
{
|
||||||
|
SrsConfDirective* dvr = get_dvr(vhost);
|
||||||
|
|
||||||
|
if (!dvr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsConfDirective* conf = dvr->get("dvr_autostart");
|
||||||
|
|
||||||
|
if (!conf || conf->arg0() != "off") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsConfig::get_dvr_time_jitter(string vhost)
|
int SrsConfig::get_dvr_time_jitter(string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* dvr = get_dvr(vhost);
|
SrsConfDirective* dvr = get_dvr(vhost);
|
||||||
|
|
|
@ -60,6 +60,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html"
|
#define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html"
|
||||||
#define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session"
|
#define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session"
|
||||||
#define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment"
|
#define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment"
|
||||||
|
#define SRS_CONF_DEFAULT_DVR_PLAN_API "api"
|
||||||
#define SRS_CONF_DEFAULT_DVR_PLAN SRS_CONF_DEFAULT_DVR_PLAN_SESSION
|
#define SRS_CONF_DEFAULT_DVR_PLAN SRS_CONF_DEFAULT_DVR_PLAN_SESSION
|
||||||
#define SRS_CONF_DEFAULT_DVR_DURATION 30
|
#define SRS_CONF_DEFAULT_DVR_DURATION 30
|
||||||
#define SRS_CONF_DEFAULT_TIME_JITTER "full"
|
#define SRS_CONF_DEFAULT_TIME_JITTER "full"
|
||||||
|
@ -921,14 +922,18 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual std::string get_dvr_plan(std::string vhost);
|
virtual std::string get_dvr_plan(std::string vhost);
|
||||||
/**
|
/**
|
||||||
* get the duration of dvr flv, for segment plan.
|
* get the duration of dvr flv.
|
||||||
*/
|
*/
|
||||||
virtual int get_dvr_duration(std::string vhost);
|
virtual int get_dvr_duration(std::string vhost);
|
||||||
/**
|
/**
|
||||||
* whether wait keyframe to reap segment, for segment plan.
|
* whether wait keyframe to reap segment.
|
||||||
*/
|
*/
|
||||||
virtual bool get_dvr_wait_keyframe(std::string vhost);
|
virtual bool get_dvr_wait_keyframe(std::string vhost);
|
||||||
/**
|
/**
|
||||||
|
* whether autostart for dvr. wait api to start dvr if false.
|
||||||
|
*/
|
||||||
|
virtual bool get_dvr_autostart(std::string vhost);
|
||||||
|
/**
|
||||||
* get the time_jitter algorithm for dvr.
|
* get the time_jitter algorithm for dvr.
|
||||||
*/
|
*/
|
||||||
virtual int get_dvr_time_jitter(std::string vhost);
|
virtual int get_dvr_time_jitter(std::string vhost);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,16 +41,34 @@ class SrsOnMetaDataPacket;
|
||||||
class SrsSharedPtrMessage;
|
class SrsSharedPtrMessage;
|
||||||
class SrsFileWriter;
|
class SrsFileWriter;
|
||||||
class SrsFlvEncoder;
|
class SrsFlvEncoder;
|
||||||
|
class SrsDvrPlan;
|
||||||
|
|
||||||
#include <srs_app_source.hpp>
|
#include <srs_app_source.hpp>
|
||||||
#include <srs_app_reload.hpp>
|
#include <srs_app_reload.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a piece of flv segment.
|
* a piece of flv segment.
|
||||||
|
* when open segment, support start at 0 or not.
|
||||||
*/
|
*/
|
||||||
class SrsFlvSegment
|
class SrsFlvSegment : public ISrsReloadHandler
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
|
SrsSource* source;
|
||||||
|
SrsRequest* req;
|
||||||
|
SrsDvrPlan* plan;
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* the underlayer dvr stream.
|
||||||
|
* if close, the flv is reap and closed.
|
||||||
|
* if open, new flv file is crote.
|
||||||
|
*/
|
||||||
|
SrsFlvEncoder* enc;
|
||||||
|
SrsRtmpJitter* jitter;
|
||||||
|
SrsRtmpJitterAlgorithm jitter_algorithm;
|
||||||
|
SrsFileWriter* fs;
|
||||||
|
private:
|
||||||
|
std::string tmp_flv_file;
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* current segment flv file path.
|
* current segment flv file path.
|
||||||
*/
|
*/
|
||||||
|
@ -81,10 +99,56 @@ public:
|
||||||
*/
|
*/
|
||||||
int64_t stream_previous_pkt_time;
|
int64_t stream_previous_pkt_time;
|
||||||
public:
|
public:
|
||||||
SrsFlvSegment();
|
SrsFlvSegment(SrsDvrPlan* p);
|
||||||
virtual ~SrsFlvSegment();
|
virtual ~SrsFlvSegment();
|
||||||
public:
|
public:
|
||||||
virtual void reset();
|
/**
|
||||||
|
* initialize the segment.
|
||||||
|
*/
|
||||||
|
virtual int initialize(SrsSource* s, SrsRequest* r);
|
||||||
|
/**
|
||||||
|
* whether segment is overflow.
|
||||||
|
*/
|
||||||
|
virtual bool is_overflow(int64_t max_duration);
|
||||||
|
/**
|
||||||
|
* open new segment file, timestamp start at 0 for fresh flv file.
|
||||||
|
* @remark ignore when already open.
|
||||||
|
*/
|
||||||
|
virtual int open();
|
||||||
|
/**
|
||||||
|
* close current segment.
|
||||||
|
* @remark ignore when already closed.
|
||||||
|
*/
|
||||||
|
virtual int close();
|
||||||
|
/**
|
||||||
|
* write the metadata to segment.
|
||||||
|
*/
|
||||||
|
virtual int write_metadata(SrsOnMetaDataPacket* metadata);
|
||||||
|
/**
|
||||||
|
* @param __audio, directly ptr, copy it if need to save it.
|
||||||
|
*/
|
||||||
|
virtual int write_audio(SrsSharedPtrMessage* __audio);
|
||||||
|
/**
|
||||||
|
* @param __video, directly ptr, copy it if need to save it.
|
||||||
|
*/
|
||||||
|
virtual int write_video(SrsSharedPtrMessage* __video);
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* generate the flv segment path.
|
||||||
|
*/
|
||||||
|
virtual std::string generate_path();
|
||||||
|
/**
|
||||||
|
* create flv jitter. load jitter when flv exists.
|
||||||
|
* @param loads_from_flv whether loads the jitter from exists flv file.
|
||||||
|
*/
|
||||||
|
virtual int create_jitter(bool loads_from_flv);
|
||||||
|
/**
|
||||||
|
* when update the duration of segment by rtmp msg.
|
||||||
|
*/
|
||||||
|
virtual int on_update_duration(SrsSharedPtrMessage* msg);
|
||||||
|
// interface ISrsReloadHandler
|
||||||
|
public:
|
||||||
|
virtual int on_reload_vhost_dvr(std::string vhost);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,32 +158,25 @@ public:
|
||||||
* 2. reap flv: when to reap the flv and start new piece.
|
* 2. reap flv: when to reap the flv and start new piece.
|
||||||
*/
|
*/
|
||||||
// TODO: FIXME: the plan is too fat, refine me.
|
// TODO: FIXME: the plan is too fat, refine me.
|
||||||
class SrsDvrPlan : public ISrsReloadHandler
|
class SrsDvrPlan
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
/**
|
friend class SrsFlvSegment;
|
||||||
* the underlayer dvr stream.
|
|
||||||
* if close, the flv is reap and closed.
|
|
||||||
* if open, new flv file is crote.
|
|
||||||
*/
|
|
||||||
SrsFlvEncoder* enc;
|
|
||||||
SrsSource* _source;
|
|
||||||
SrsRtmpJitter* jitter;
|
|
||||||
SrsRtmpJitterAlgorithm jitter_algorithm;
|
|
||||||
protected:
|
protected:
|
||||||
|
SrsSource* source;
|
||||||
|
SrsRequest* req;
|
||||||
SrsFlvSegment* segment;
|
SrsFlvSegment* segment;
|
||||||
SrsRequest* _req;
|
|
||||||
bool dvr_enabled;
|
bool dvr_enabled;
|
||||||
SrsFileWriter* fs;
|
|
||||||
private:
|
|
||||||
std::string tmp_flv_file;
|
|
||||||
public:
|
public:
|
||||||
SrsDvrPlan();
|
SrsDvrPlan();
|
||||||
virtual ~SrsDvrPlan();
|
virtual ~SrsDvrPlan();
|
||||||
public:
|
public:
|
||||||
virtual int initialize(SrsSource* source, SrsRequest* req);
|
virtual int initialize(SrsSource* s, SrsRequest* r);
|
||||||
virtual int on_publish();
|
virtual int on_publish() = 0;
|
||||||
virtual void on_unpublish() = 0;
|
virtual void on_unpublish() = 0;
|
||||||
|
/**
|
||||||
|
* when got metadata.
|
||||||
|
*/
|
||||||
virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
|
virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
|
||||||
/**
|
/**
|
||||||
* @param __audio, directly ptr, copy it if need to save it.
|
* @param __audio, directly ptr, copy it if need to save it.
|
||||||
|
@ -129,15 +186,7 @@ public:
|
||||||
* @param __video, directly ptr, copy it if need to save it.
|
* @param __video, directly ptr, copy it if need to save it.
|
||||||
*/
|
*/
|
||||||
virtual int on_video(SrsSharedPtrMessage* __video);
|
virtual int on_video(SrsSharedPtrMessage* __video);
|
||||||
// interface ISrsReloadHandler
|
|
||||||
public:
|
|
||||||
virtual int on_reload_vhost_dvr(std::string vhost);
|
|
||||||
protected:
|
protected:
|
||||||
virtual int flv_open(std::string stream, std::string path);
|
|
||||||
virtual int flv_close();
|
|
||||||
virtual int open_new_segment();
|
|
||||||
virtual int update_duration(SrsSharedPtrMessage* msg);
|
|
||||||
virtual int write_flv_header();
|
|
||||||
virtual int on_dvr_request_sh();
|
virtual int on_dvr_request_sh();
|
||||||
virtual int on_video_keyframe();
|
virtual int on_video_keyframe();
|
||||||
virtual int64_t filter_timestamp(int64_t timestamp);
|
virtual int64_t filter_timestamp(int64_t timestamp);
|
||||||
|
@ -154,6 +203,7 @@ public:
|
||||||
SrsDvrSessionPlan();
|
SrsDvrSessionPlan();
|
||||||
virtual ~SrsDvrSessionPlan();
|
virtual ~SrsDvrSessionPlan();
|
||||||
public:
|
public:
|
||||||
|
virtual int on_publish();
|
||||||
virtual void on_unpublish();
|
virtual void on_unpublish();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -193,11 +243,11 @@ private:
|
||||||
class SrsDvr
|
class SrsDvr
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsSource* _source;
|
SrsSource* source;
|
||||||
private:
|
private:
|
||||||
SrsDvrPlan* plan;
|
SrsDvrPlan* plan;
|
||||||
public:
|
public:
|
||||||
SrsDvr(SrsSource* source);
|
SrsDvr(SrsSource* s);
|
||||||
virtual ~SrsDvr();
|
virtual ~SrsDvr();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -205,12 +255,12 @@ public:
|
||||||
* when system initialize(encoder publish at first time, or reload),
|
* when system initialize(encoder publish at first time, or reload),
|
||||||
* initialize the dvr will reinitialize the plan, the whole dvr framework.
|
* initialize the dvr will reinitialize the plan, the whole dvr framework.
|
||||||
*/
|
*/
|
||||||
virtual int initialize(SrsRequest* req);
|
virtual int initialize(SrsRequest* r);
|
||||||
/**
|
/**
|
||||||
* publish stream event,
|
* publish stream event,
|
||||||
* when encoder start to publish RTMP stream.
|
* when encoder start to publish RTMP stream.
|
||||||
*/
|
*/
|
||||||
virtual int on_publish(SrsRequest* req);
|
virtual int on_publish(SrsRequest* r);
|
||||||
/**
|
/**
|
||||||
* the unpublish event.,
|
* the unpublish event.,
|
||||||
* when encoder stop(unpublish) to publish RTMP stream.
|
* when encoder stop(unpublish) to publish RTMP stream.
|
||||||
|
@ -219,7 +269,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* get some information from metadata, it's optinal.
|
* get some information from metadata, it's optinal.
|
||||||
*/
|
*/
|
||||||
virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
|
virtual int on_meta_data(SrsOnMetaDataPacket* m);
|
||||||
/**
|
/**
|
||||||
* mux the audio packets to dvr.
|
* mux the audio packets to dvr.
|
||||||
* @param __audio, directly ptr, copy it if need to save it.
|
* @param __audio, directly ptr, copy it if need to save it.
|
||||||
|
|
|
@ -106,7 +106,8 @@ int SrsGoApiV1::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
<< __SRS_JFIELD_STR("authors", "the primary authors and contributors") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("authors", "the primary authors and contributors") << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("requests", "the request itself, for http debug") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("requests", "the request itself, for http debug") << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("vhosts", "dumps vhost to json") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("vhosts", "dumps vhost to json") << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("streams", "dumps streams to json")
|
<< __SRS_JFIELD_STR("streams", "dumps streams to json") << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_STR("dvrs", "query or control the dvr plan")
|
||||||
<< __SRS_JOBJECT_END
|
<< __SRS_JOBJECT_END
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue