diff --git a/README.md b/README.md index f293c61f0..c4c4fc3ba 100755 --- a/README.md +++ b/README.md @@ -562,6 +562,7 @@ Supported operating systems and hardware: ### SRS 2.0 history +* v2.0, 2015-03-30, for [#366](https://github.com/winlinvip/simple-rtmp-server/issues/366), config hls to disable cleanup of ts. 2.0.154. * v2.0, 2015-03-31, support server cycle handler. 2.0.153. * v2.0, 2015-03-31, support on_hls for http hooks. 2.0.152. * v2.0, 2015-03-31, enhanced hls, support deviation for duration. 2.0.151. diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index b06472438..5cb812e13 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -594,7 +594,10 @@ vhost with-hls.srs.com { # h264, vn # default: h264 hls_vcodec h264; - + # whether cleanup the old ts files. + # default: on + hls_cleanup on; + # on_hls, never config in here, should config in http_hooks. # for the hls http callback, @see http_hooks.on_hls of vhost hooks.callback.srs.com # @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DeliveryHLS#http-callback diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 3c7b8c276..85725d1cc 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -1482,7 +1482,7 @@ int SrsConfig::check_config() string m = conf->at(j)->name.c_str(); if (m != "enabled" && m != "hls_entry_prefix" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error" && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_aof_ratio" && m != "hls_acodec" && m != "hls_vcodec" - && m != "hls_m3u8_file" && m != "hls_ts_file" && m != "hls_ts_floor" + && m != "hls_m3u8_file" && m != "hls_ts_file" && m != "hls_ts_floor" && m != "hls_cleanup" ) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); @@ -3388,6 +3388,23 @@ string SrsConfig::get_hls_vcodec(string vhost) return conf->arg0(); } +bool SrsConfig::get_hls_cleanup(string vhost) +{ + SrsConfDirective* hls = get_hls(vhost); + + if (!hls) { + return SRS_CONF_DEFAULT_HLS_CLEANUP; + } + + SrsConfDirective* conf = hls->get("hls_cleanup"); + + if (!conf && conf->arg0() != "off") { + return SRS_CONF_DEFAULT_HLS_CLEANUP; + } + + return false; +} + SrsConfDirective *SrsConfig::get_hds(const string &vhost) { SrsConfDirective* conf = get_vhost(vhost); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index a1b11a848..569060a8e 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -61,6 +61,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRS_CONF_DEFAULT_HLS_MOUNT "[vhost]/[app]/[stream].m3u8" #define SRS_CONF_DEFAULT_HLS_ACODEC "aac" #define SRS_CONF_DEFAULT_HLS_VCODEC "h264" +#define SRS_CONF_DEFAULT_HLS_CLEANUP true #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html/[app]/[stream].[timestamp].flv" #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session" #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment" @@ -935,6 +936,10 @@ public: * get the HLS default video codec. */ virtual std::string get_hls_vcodec(std::string vhost); + /** + * whether cleanup the old ts files. + */ + virtual bool get_hls_cleanup(std::string vhost); // hds section private: diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index 3570cd9b0..e3caaa2be 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -224,6 +224,7 @@ SrsHlsMuxer::SrsHlsMuxer() hls_fragment = hls_window = 0; hls_aof_ratio = 1.0; hls_fragment_deviation = 0; + hls_cleanup = true; previous_floor_ts = 0; accept_floor_ts = 0; hls_ts_floor = false; @@ -250,19 +251,6 @@ SrsHlsMuxer::~SrsHlsMuxer() srs_freep(async); } -int SrsHlsMuxer::initialize(ISrsHlsHandler* h) -{ - int ret = ERROR_SUCCESS; - - handler = h; - - if ((ret = async->start()) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - int SrsHlsMuxer::sequence_no() { return _sequence_no; @@ -283,9 +271,22 @@ double SrsHlsMuxer::deviation() return hls_fragment_deviation; } +int SrsHlsMuxer::initialize(ISrsHlsHandler* h) +{ + int ret = ERROR_SUCCESS; + + handler = h; + + if ((ret = async->start()) != ERROR_SUCCESS) { + return ret; + } + + return ret; +} + int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, string path, string m3u8_file, string ts_file, double fragment, double window, - bool ts_floor, double aof_ratio + bool ts_floor, double aof_ratio, bool cleanup ) { int ret = ERROR_SUCCESS; @@ -298,6 +299,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, hls_fragment = fragment; hls_aof_ratio = aof_ratio; hls_ts_floor = ts_floor; + hls_cleanup = cleanup; previous_floor_ts = 0; accept_floor_ts = 0; hls_window = window; @@ -651,7 +653,11 @@ int SrsHlsMuxer::segment_close(string log_desc) // remove the ts file. for (int i = 0; i < (int)segment_to_remove.size(); i++) { SrsHlsSegment* segment = segment_to_remove[i]; - unlink(segment->full_path.c_str()); + + if (hls_cleanup) { + unlink(segment->full_path.c_str()); + } + srs_freep(segment); } segment_to_remove.clear(); @@ -796,6 +802,7 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment std::string path = _srs_config->get_hls_path(vhost); std::string m3u8_file = _srs_config->get_hls_m3u8_file(vhost); std::string ts_file = _srs_config->get_hls_ts_file(vhost); + bool cleanup = _srs_config->get_hls_cleanup(vhost); // the audio overflow, for pure audio to reap segment. double hls_aof_ratio = _srs_config->get_hls_aof_ratio(vhost); // whether use floor(timestamp/hls_fragment) for variable timestamp @@ -806,7 +813,8 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment // open muxer if ((ret = muxer->update_config(req, entry_prefix, - path, m3u8_file, ts_file, hls_fragment, hls_window, ts_floor, hls_aof_ratio)) != ERROR_SUCCESS + path, m3u8_file, ts_file, hls_fragment, hls_window, ts_floor, hls_aof_ratio, + cleanup)) != ERROR_SUCCESS ) { srs_error("m3u8 muxer update config failed. ret=%d", ret); return ret; diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp index c28b4e0bd..5bb54280a 100644 --- a/trunk/src/app/srs_app_hls.hpp +++ b/trunk/src/app/srs_app_hls.hpp @@ -188,6 +188,7 @@ private: std::string hls_entry_prefix; std::string hls_path; std::string hls_ts_file; + bool hls_cleanup; std::string m3u8_dir; double hls_aof_ratio; double hls_fragment; @@ -245,7 +246,8 @@ public: */ virtual int update_config(SrsRequest* r, std::string entry_prefix, std::string path, std::string m3u8_file, std::string ts_file, - double fragment, double window, bool ts_floor, double aof_ratio); + double fragment, double window, bool ts_floor, double aof_ratio, + bool cleanup); /** * open a new segment(a new ts file), * @param segment_start_dts use to calc the segment duration, diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index fd3c06908..bdb662aa7 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR 2 #define VERSION_MINOR 0 -#define VERSION_REVISION 153 +#define VERSION_REVISION 154 // server info. #define RTMP_SIG_SRS_KEY "SRS"