diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index b409002df..918ead4be 100755 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -329,6 +329,12 @@ vhost with-hls.srs.com { # the hls window in seconds, the number of ts in m3u8. # default: 60 hls_window 60; + # the error strategy. canbe: + # ignore, when error ignore and disable hls. + # disconnect, when error disconnect the publish connection. + # @see https://github.com/winlinvip/simple-rtmp-server/issues/264 + # default: ignore + hls_on_error ignore; } } # the vhost with hls disabled. diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 4750ba5ba..0af6643d8 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -798,6 +798,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) srs_trace("vhost %s reload forward success.", vhost.c_str()); } // hls, only one per vhost + // @remark, the hls_on_error directly support reload. if (!srs_directive_equals(new_vhost->get("hls"), old_vhost->get("hls"))) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { ISrsReloadHandler* subscribe = *it; @@ -1412,7 +1413,7 @@ int SrsConfig::check_config() } else if (n == "hls") { for (int j = 0; j < (int)conf->directives.size(); j++) { string m = conf->at(j)->name.c_str(); - if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window") { + if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error") { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); return ret; @@ -3064,6 +3065,23 @@ double SrsConfig::get_hls_window(string vhost) return ::atof(conf->arg0().c_str()); } +string SrsConfig::get_hls_on_error(string vhost) +{ + SrsConfDirective* hls = get_hls(vhost); + + if (!hls) { + return SRS_CONF_DEFAULT_HLS_ON_ERROR; + } + + SrsConfDirective* conf = hls->get("hls_on_error"); + + if (!conf) { + return SRS_CONF_DEFAULT_HLS_ON_ERROR; + } + + return conf->arg0(); +} + SrsConfDirective* SrsConfig::get_dvr(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 5abc3c126..088910d7c 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -48,6 +48,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html" #define SRS_CONF_DEFAULT_HLS_FRAGMENT 10 #define SRS_CONF_DEFAULT_HLS_WINDOW 60 +#define SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE "ignore" +#define SRS_CONF_DEFAULT_HLS_ON_ERROR_DISCONNECT "disconnect" +#define SRS_CONF_DEFAULT_HLS_ON_ERROR SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html" #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session" #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment" @@ -847,6 +850,13 @@ public: * @remark SRS will delete the ts exceed the window. */ virtual double get_hls_window(std::string vhost); + /** + * get the hls hls_on_error config. + * the ignore will ignore error and disable hls. + * the disconnect will disconnect publish connection. + * @see https://github.com/winlinvip/simple-rtmp-server/issues/264 + */ + virtual std::string get_hls_on_error(std::string vhost); // dvr section private: /** diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index 889f751a7..5acb3cfc1 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -1439,7 +1439,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* __audio) sample->clear(); if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) { - srs_error("codec demux audio failed. ret=%d", ret); + srs_error("hls codec demux audio failed. ret=%d", ret); return ret; } @@ -1484,7 +1484,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* __video) sample->clear(); if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) { - srs_error("codec demux video failed. ret=%d", ret); + srs_error("hls codec demux video failed. ret=%d", ret); return ret; } diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 5b9d8cece..bbc4625ed 100644 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1239,14 +1239,22 @@ int SrsSource::on_audio(SrsCommonMessage* __audio) srs_verbose("initialize shared ptr audio success."); #ifdef SRS_AUTO_HLS - if ((ret = hls->on_audio(&msg)) != ERROR_SUCCESS) { - srs_warn("hls process audio message failed, ignore and disable hls. ret=%d", ret); - - // unpublish, ignore ret. - hls->on_unpublish(); - - // ignore. - ret = ERROR_SUCCESS; + if ((ret = hls->on_audio(msg.copy())) != ERROR_SUCCESS) { + // apply the error strategy for hls. + // @see https://github.com/winlinvip/simple-rtmp-server/issues/264 + std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost); + if (hls_error_strategy == SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE) { + srs_warn("hls process audio message failed, ignore and disable hls. ret=%d", ret); + + // unpublish, ignore ret. + hls->on_unpublish(); + + // ignore. + ret = ERROR_SUCCESS; + } else { + srs_warn("hls disconnect publisher for audio error. ret=%d", ret); + return ret; + } } #endif @@ -1298,7 +1306,7 @@ int SrsSource::on_audio(SrsCommonMessage* __audio) SrsAvcAacCodec codec; SrsCodecSample sample; if ((ret = codec.audio_aac_demux(msg.payload, msg.size, &sample)) != ERROR_SUCCESS) { - srs_error("codec demux audio failed. ret=%d", ret); + srs_error("source codec demux audio failed. ret=%d", ret); return ret; } @@ -1349,14 +1357,22 @@ int SrsSource::on_video(SrsCommonMessage* __video) srs_verbose("initialize shared ptr video success."); #ifdef SRS_AUTO_HLS - if ((ret = hls->on_video(&msg)) != ERROR_SUCCESS) { - srs_warn("hls process video message failed, ignore and disable hls. ret=%d", ret); - - // unpublish, ignore ret. - hls->on_unpublish(); - - // ignore. - ret = ERROR_SUCCESS; + if ((ret = hls->on_video(msg.copy())) != ERROR_SUCCESS) { + // apply the error strategy for hls. + // @see https://github.com/winlinvip/simple-rtmp-server/issues/264 + std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost); + if (hls_error_strategy == SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE) { + srs_warn("hls process video message failed, ignore and disable hls. ret=%d", ret); + + // unpublish, ignore ret. + hls->on_unpublish(); + + // ignore. + ret = ERROR_SUCCESS; + } else { + srs_warn("hls disconnect publisher for video error. ret=%d", ret); + return ret; + } } #endif @@ -1406,7 +1422,7 @@ int SrsSource::on_video(SrsCommonMessage* __video) SrsAvcAacCodec codec; SrsCodecSample sample; if ((ret = codec.video_avc_demux(msg.payload, msg.size, &sample)) != ERROR_SUCCESS) { - srs_error("codec demux video failed. ret=%d", ret); + srs_error("source codec demux video failed. ret=%d", ret); return ret; } diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 39f9547f3..cf8539c21 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 73 +#define VERSION_REVISION 74 // server info. #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_ROLE "origin/edge server"