diff --git a/README.md b/README.md
index d66e35146..31b8e31f2 100755
--- a/README.md
+++ b/README.md
@@ -146,6 +146,7 @@ For previous versions, please read:
## V3 changes
+* v3.0, 2020-01-15, For [#1509][bug #1509], release coroutine when source is idle. 3.0.98
* v3.0, 2020-01-10, [3.0 alpha8(3.0.97)][r3.0a8] released. 121555 lines.
* v3.0, 2020-01-09, For [#1042][bug #1042], improve test coverage for service. 3.0.97
* v3.0, 2020-01-08, Merge [#1554][bug #1554], support logrotate copytruncate. 3.0.96
@@ -1592,6 +1593,7 @@ Winlin
[bug #1544]: https://github.com/ossrs/srs/issues/1544
[bug #1255]: https://github.com/ossrs/srs/issues/1255
[bug #1543]: https://github.com/ossrs/srs/issues/1543
+[bug #1509]: https://github.com/ossrs/srs/issues/1509
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
[exo #828]: https://github.com/google/ExoPlayer/pull/828
diff --git a/trunk/src/app/srs_app_dvr.cpp b/trunk/src/app/srs_app_dvr.cpp
index d29d22a23..507956aed 100644
--- a/trunk/src/app/srs_app_dvr.cpp
+++ b/trunk/src/app/srs_app_dvr.cpp
@@ -609,13 +609,25 @@ srs_error_t SrsDvrPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, SrsReque
return srs_error_wrap(err, "segmenter");
}
+ return err;
+}
+
+srs_error_t SrsDvrPlan::on_publish()
+{
+ srs_error_t err = srs_success;
+
if ((err = async->start()) != srs_success) {
return srs_error_wrap(err, "async");
}
-
+
return err;
}
+void SrsDvrPlan::on_unpublish()
+{
+ async->stop();
+}
+
srs_error_t SrsDvrPlan::on_meta_data(SrsSharedPtrMessage* shared_metadata)
{
srs_error_t err = srs_success;
@@ -699,6 +711,10 @@ SrsDvrSessionPlan::~SrsDvrSessionPlan()
srs_error_t SrsDvrSessionPlan::on_publish()
{
srs_error_t err = srs_success;
+
+ if ((err = SrsDvrPlan::on_publish()) != srs_success) {
+ return err;
+ }
// support multiple publish.
if (dvr_enabled) {
@@ -724,6 +740,8 @@ srs_error_t SrsDvrSessionPlan::on_publish()
void SrsDvrSessionPlan::on_unpublish()
{
+ SrsDvrPlan::on_unpublish();
+
// support multiple publish.
if (!dvr_enabled) {
return;
@@ -766,6 +784,10 @@ srs_error_t SrsDvrSegmentPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, S
srs_error_t SrsDvrSegmentPlan::on_publish()
{
srs_error_t err = srs_success;
+
+ if ((err = SrsDvrPlan::on_publish()) != srs_success) {
+ return err;
+ }
// support multiple publish.
if (dvr_enabled) {
@@ -791,6 +813,7 @@ srs_error_t SrsDvrSegmentPlan::on_publish()
void SrsDvrSegmentPlan::on_unpublish()
{
+ SrsDvrPlan::on_unpublish();
}
srs_error_t SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format)
diff --git a/trunk/src/app/srs_app_dvr.hpp b/trunk/src/app/srs_app_dvr.hpp
index 62ea1cb1e..716d45e0e 100644
--- a/trunk/src/app/srs_app_dvr.hpp
+++ b/trunk/src/app/srs_app_dvr.hpp
@@ -185,8 +185,8 @@ public:
virtual ~SrsDvrPlan();
public:
virtual srs_error_t initialize(SrsOriginHub* h, SrsDvrSegmenter* s, SrsRequest* r);
- virtual srs_error_t on_publish() = 0;
- virtual void on_unpublish() = 0;
+ virtual srs_error_t on_publish();
+ virtual void on_unpublish();
virtual srs_error_t on_meta_data(SrsSharedPtrMessage* shared_metadata);
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format);
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp
index 0f18f74a5..72ec535ca 100644
--- a/trunk/src/app/srs_app_hls.cpp
+++ b/trunk/src/app/srs_app_hls.cpp
@@ -268,16 +268,27 @@ int SrsHlsMuxer::deviation()
}
srs_error_t SrsHlsMuxer::initialize()
+{
+ return srs_success;
+}
+
+srs_error_t SrsHlsMuxer::on_publish(SrsRequest* req)
{
srs_error_t err = srs_success;
-
+
if ((err = async->start()) != srs_success) {
return srs_error_wrap(err, "async start");
}
-
+
return err;
}
+srs_error_t SrsHlsMuxer::on_unpublish()
+{
+ async->stop();
+ return srs_success;
+}
+
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,
@@ -899,8 +910,11 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req)
// TODO: FIXME: support load exists m3u8, to continue publish stream.
// for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase.
+
+ if ((err = muxer->on_publish(req)) != srs_success) {
+ return srs_error_wrap(err, "muxer publish");
+ }
- // open muxer
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 ) {
@@ -924,6 +938,10 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req)
srs_error_t SrsHlsController::on_unpublish()
{
srs_error_t err = srs_success;
+
+ if ((err = muxer->on_unpublish()) != srs_success) {
+ return srs_error_wrap(err, "muxer unpublish");
+ }
if ((err = muxer->flush_audio(tsmc)) != srs_success) {
return srs_error_wrap(err, "hls: flush audio");
diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp
index 194c183fb..1dd72eba5 100644
--- a/trunk/src/app/srs_app_hls.hpp
+++ b/trunk/src/app/srs_app_hls.hpp
@@ -185,6 +185,9 @@ public:
public:
// Initialize the hls muxer.
virtual srs_error_t initialize();
+ // When publish or unpublish stream.
+ virtual srs_error_t on_publish(SrsRequest* req);
+ virtual srs_error_t on_unpublish();
// When publish, update the config for muxer.
virtual srs_error_t update_config(SrsRequest* r, std::string entry_prefix,
std::string path, std::string m3u8_file, std::string ts_file,
diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp
index 5a80e8f8e..b6aa58342 100644
--- a/trunk/src/core/srs_core.hpp
+++ b/trunk/src/core/srs_core.hpp
@@ -27,7 +27,7 @@
// The version config.
#define VERSION_MAJOR 3
#define VERSION_MINOR 0
-#define VERSION_REVISION 97
+#define VERSION_REVISION 98
// The macros generated by configure script.
#include