Skip to content

Commit

Permalink
Added delay cleanup config support
Browse files Browse the repository at this point in the history
  • Loading branch information
mapengfei53 committed Apr 11, 2022
1 parent 6634740 commit 34ad906
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 19 deletions.
5 changes: 5 additions & 0 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,11 @@ vhost hls.srs.com {
# whether cleanup the old expired ts files.
# default: on
hls_cleanup on;
# whether delay cleanup the old expired ts files.
# when hls_cleanup is on, delay cleanup the old expired ts files in this timeout in seconds.
# @remark 0 to disable delay cleanup for publisher.
# default: 0
hls_delay_cleanup 0;
# If there is no incoming packets, dispose HLS in this timeout in seconds,
# which removes all HLS files including m3u8 and ts files.
# @remark 0 to disable dispose for publisher.
Expand Down
51 changes: 39 additions & 12 deletions trunk/src/app/srs_app_fragment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,22 +212,49 @@ void SrsFragmentWindow::shrink(srs_utime_t window)
}
}

void SrsFragmentWindow::clear_expired(bool delete_files)
void SrsFragmentWindow::clear_expired(bool delete_files, srs_utime_t delay_time)
{
srs_error_t err = srs_success;

std::vector<SrsFragment*>::iterator it;

for (it = expired_fragments.begin(); it != expired_fragments.end(); ++it) {
SrsFragment* fragment = *it;
if (delete_files && (err = fragment->unlink_file()) != srs_success) {
srs_warn("Unlink ts failed, %s", srs_error_desc(err).c_str());
srs_freep(err);

if (!delete_files || delay_time == 0) {
std::vector<SrsFragment*>::iterator it;

for (it = expired_fragments.begin(); it != expired_fragments.end(); ++it) {
SrsFragment* fragment = *it;
if (delete_files && (err = fragment->unlink_file()) != srs_success) {
srs_warn("Unlink ts failed, %s", srs_error_desc(err).c_str());
srs_freep(err);
}
srs_freep(fragment);
}

expired_fragments.clear();
} else {
srs_utime_t duration = 0;

int remove_index = -1;

for (int i = (int)expired_fragments.size() - 1; i >= 0; i--) {
SrsFragment* fragment = expired_fragments[i];
duration += fragment->duration();

if (duration > delay_time) {
remove_index = i;
break;
}
}

for (int i = 0; i < remove_index && !expired_fragments.empty(); i++) {
SrsFragment* fragment = *expired_fragments.begin();
expired_fragments.erase(expired_fragments.begin());

if ((err = fragment->unlink_file()) != srs_success) {
srs_warn("Unlink ts failed, %s", srs_error_desc(err).c_str());
srs_freep(err);
}
srs_freep(fragment);
}
srs_freep(fragment);
}

expired_fragments.clear();
}

srs_utime_t SrsFragmentWindow::max_duration()
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/app/srs_app_fragment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class SrsFragmentWindow
// Shrink the window, push the expired fragment to a queue.
virtual void shrink(srs_utime_t window);
// Clear the expired fragments.
virtual void clear_expired(bool delete_files);
virtual void clear_expired(bool delete_files, srs_utime_t delay_time);
// Get the max duration in srs_utime_t of all fragments.
virtual srs_utime_t max_duration();
public:
Expand Down
17 changes: 12 additions & 5 deletions trunk/src/app/srs_app_hls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ SrsHlsMuxer::SrsHlsMuxer()
current = NULL;
hls_keys = false;
hls_fragments_per_key = 0;
hls_delay_cleanup = 0;
async = new SrsAsyncCallWorker();
context = new SrsTsContext();
segments = new SrsFragmentWindow();
Expand Down Expand Up @@ -288,7 +289,8 @@ srs_error_t SrsHlsMuxer::on_unpublish()
srs_error_t SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
string path, string m3u8_file, string ts_file, srs_utime_t fragment, srs_utime_t window,
bool ts_floor, double aof_ratio, bool cleanup, bool wait_keyframe, bool keys,
int fragments_per_key, string key_file ,string key_file_path, string key_url)
int fragments_per_key, string key_file ,string key_file_path, string key_url,
srs_utime_t delay_cleanup)
{
srs_error_t err = srs_success;

Expand All @@ -313,6 +315,8 @@ srs_error_t SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
hls_key_file = key_file;
hls_key_file_path = key_file_path;
hls_key_url = key_url;

hls_delay_cleanup = delay_cleanup;

// generate the m3u8 dir and path.
m3u8_url = srs_path_build_stream(m3u8_file, req->vhost, req->app, req->stream);
Expand Down Expand Up @@ -659,7 +663,7 @@ srs_error_t SrsHlsMuxer::do_segment_close()
err = refresh_m3u8();

// remove the ts file.
segments->clear_expired(hls_cleanup);
segments->clear_expired(hls_cleanup, hls_delay_cleanup);

// check ret of refresh m3u8
if (err != srs_success) {
Expand Down Expand Up @@ -902,6 +906,9 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req)
string hls_key_file = _srs_config->get_hls_key_file(vhost);
string hls_key_file_path = _srs_config->get_hls_key_file_path(vhost);
string hls_key_url = _srs_config->get_hls_key_url(vhost);

// the time to delay cleanup ts files.
srs_utime_t hls_delay_cleanup = _srs_config->get_hls_delay_cleanup(vhost);

// TODO: FIXME: support load exists m3u8, to continue publish stream.
// for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase.
Expand All @@ -912,7 +919,7 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req)

if ((err = muxer->update_config(req, entry_prefix, path, m3u8_file, ts_file, hls_fragment,
hls_window, ts_floor, hls_aof_ratio, cleanup, wait_keyframe,hls_keys,hls_fragments_per_key,
hls_key_file, hls_key_file_path, hls_key_url)) != srs_success ) {
hls_key_file, hls_key_file_path, hls_key_url, hls_delay_cleanup)) != srs_success ) {
return srs_error_wrap(err, "hls: update config");
}

Expand All @@ -923,9 +930,9 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req)
// This config item is used in SrsHls, we just log its value here.
bool hls_dts_directly = _srs_config->get_vhost_hls_dts_directly(req->vhost);

srs_trace("hls: win=%dms, frag=%dms, prefix=%s, path=%s, m3u8=%s, ts=%s, aof=%.2f, floor=%d, clean=%d, waitk=%d, dispose=%dms, dts_directly=%d",
srs_trace("hls: win=%dms, frag=%dms, prefix=%s, path=%s, m3u8=%s, ts=%s, aof=%.2f, floor=%d, clean=%d, waitk=%d, dispose=%dms, dts_directly=%d, delay_cleanup=%d",
srsu2msi(hls_window), srsu2msi(hls_fragment), entry_prefix.c_str(), path.c_str(), m3u8_file.c_str(), ts_file.c_str(),
hls_aof_ratio, ts_floor, cleanup, wait_keyframe, srsu2msi(hls_dispose), hls_dts_directly);
hls_aof_ratio, ts_floor, cleanup, wait_keyframe, srsu2msi(hls_dispose), hls_dts_directly, srsu2msi(hls_delay_cleanup));

return err;
}
Expand Down
4 changes: 3 additions & 1 deletion trunk/src/app/srs_app_hls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class SrsHlsMuxer
// TODO: FIXME: Use TBN 1000.
srs_utime_t hls_fragment;
srs_utime_t hls_window;
srs_utime_t hls_delay_cleanup;
SrsAsyncCallWorker* async;
private:
// Whether use floor algorithm for timestamp.
Expand Down Expand Up @@ -177,7 +178,8 @@ class SrsHlsMuxer
std::string path, std::string m3u8_file, std::string ts_file,
srs_utime_t fragment, srs_utime_t window, bool ts_floor, double aof_ratio,
bool cleanup, bool wait_keyframe, bool keys, int fragments_per_key,
std::string key_file, std::string key_file_path, std::string key_url);
std::string key_file, std::string key_file_path, std::string key_url,
srs_utime_t delay_cleanup);
// Open a new segment(a new ts file)
virtual srs_error_t segment_open();
virtual srs_error_t on_sequence_header();
Expand Down

0 comments on commit 34ad906

Please sign in to comment.