mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Kickoff publisher when stream is idle, which means no players. v6.0.31, v5.0.144 (#3105)
For some use scenario, the publisher is invited when player want to view the stream: 1. Publisher connect to system, but does not publish any stream to SRS yet. 2. Player connect to system and start to request the stream. 3. System notifies publisher to publish stream to SRS. 4. Player play the stream from SRS. Please notice that `system` means your business system, not SRS. This is what we called `on-demand-live-streaming`, so when the last player stop to view the stream, what happends? 1. System needs to notify publisher to stop publish. 2. Or, SRS disconnect the publisher when idle(the last player stops playing). This PR is for the solution 2, so that the cleanup is very simple, your system does not need to notify publisher to stop publish, because SRS has already disconnected the publihser. --------- Co-authored-by: winlin <winlin@vip.126.com> Co-authored-by: chundonglinlin <chundonglinlin@163.com>
This commit is contained in:
parent
dc7be76bb1
commit
8fde0366fb
14 changed files with 125 additions and 19 deletions
|
|
@ -1877,7 +1877,7 @@ srs_error_t SrsLiveSourceManager::notify(int event, srs_utime_t interval, srs_ut
|
|||
// @see https://github.com/ossrs/srs/issues/714
|
||||
#if 0
|
||||
// When source expired, remove it.
|
||||
if (source->expired()) {
|
||||
if (source->stream_is_dead()) {
|
||||
int cid = source->source_id();
|
||||
if (cid == -1 && source->pre_source_id() > 0) {
|
||||
cid = source->pre_source_id();
|
||||
|
|
@ -1926,7 +1926,8 @@ SrsLiveSource::SrsLiveSource()
|
|||
mix_queue = new SrsMixQueue();
|
||||
|
||||
_can_publish = true;
|
||||
die_at = 0;
|
||||
stream_die_at_ = 0;
|
||||
publisher_idle_at_ = 0;
|
||||
|
||||
handler = NULL;
|
||||
bridge_ = NULL;
|
||||
|
|
@ -1983,10 +1984,10 @@ srs_error_t SrsLiveSource::cycle()
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
bool SrsLiveSource::expired()
|
||||
bool SrsLiveSource::stream_is_dead()
|
||||
{
|
||||
// unknown state?
|
||||
if (die_at == 0) {
|
||||
if (stream_die_at_ == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2001,13 +2002,26 @@ bool SrsLiveSource::expired()
|
|||
}
|
||||
|
||||
srs_utime_t now = srs_get_system_time();
|
||||
if (now > die_at + SRS_SOURCE_CLEANUP) {
|
||||
if (now > stream_die_at_ + SRS_SOURCE_CLEANUP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SrsLiveSource::publisher_is_idle_for(srs_utime_t timeout)
|
||||
{
|
||||
if (!publisher_idle_at_ || !timeout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
srs_utime_t now = srs_get_system_time();
|
||||
if (now > publisher_idle_at_ + timeout) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
srs_error_t SrsLiveSource::initialize(SrsRequest* r, ISrsLiveSourceHandler* h)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
|
@ -2634,6 +2648,11 @@ srs_error_t SrsLiveSource::on_publish()
|
|||
|
||||
SrsStatistic* stat = SrsStatistic::instance();
|
||||
stat->on_stream_publish(req, _source_id.c_str());
|
||||
|
||||
// When no players, the publisher is idle now.
|
||||
if (consumers.empty()) {
|
||||
publisher_idle_at_ = srs_get_system_time();
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -2680,7 +2699,7 @@ void SrsLiveSource::on_unpublish()
|
|||
|
||||
// no consumer, stream is die.
|
||||
if (consumers.empty()) {
|
||||
die_at = srs_get_system_time();
|
||||
stream_die_at_ = srs_get_system_time();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2690,7 +2709,11 @@ srs_error_t SrsLiveSource::create_consumer(SrsLiveConsumer*& consumer)
|
|||
|
||||
consumer = new SrsLiveConsumer(this);
|
||||
consumers.push_back(consumer);
|
||||
|
||||
|
||||
// There should be one consumer, so reset the timeout.
|
||||
stream_die_at_ = 0;
|
||||
publisher_idle_at_ = 0;
|
||||
|
||||
// for edge, when play edge stream, check the state
|
||||
if (_srs_config->get_vhost_is_edge(req->vhost)) {
|
||||
// notice edge to start for the first client.
|
||||
|
|
@ -2752,10 +2775,18 @@ void SrsLiveSource::on_consumer_destroy(SrsLiveConsumer* consumer)
|
|||
if (it != consumers.end()) {
|
||||
it = consumers.erase(it);
|
||||
}
|
||||
|
||||
|
||||
if (consumers.empty()) {
|
||||
play_edge->on_all_client_stop();
|
||||
die_at = srs_get_system_time();
|
||||
|
||||
// For edge server, the stream die when the last player quit, because the edge stream is created by player
|
||||
// activities, so it should die when all players quit.
|
||||
if (_srs_config->get_vhost_is_edge(req->vhost)) {
|
||||
stream_die_at_ = srs_get_system_time();
|
||||
}
|
||||
|
||||
// When no players, the publisher is idle now.
|
||||
publisher_idle_at_ = srs_get_system_time();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue