winlin

fix #264, support disconnect publish connect when hls error. 1.0.11

@@ -295,6 +295,12 @@ vhost with-hls.srs.com { @@ -295,6 +295,12 @@ vhost with-hls.srs.com {
295 # the hls window in seconds, the number of ts in m3u8. 295 # the hls window in seconds, the number of ts in m3u8.
296 # default: 60 296 # default: 60
297 hls_window 60; 297 hls_window 60;
  298 + # the error strategy. canbe:
  299 + # ignore, when error ignore and disable hls.
  300 + # disconnect, when error disconnect the publish connection.
  301 + # @see https://github.com/winlinvip/simple-rtmp-server/issues/264
  302 + # default: ignore
  303 + hls_on_error ignore;
298 } 304 }
299 } 305 }
300 # the vhost with hls disabled. 306 # the vhost with hls disabled.
@@ -797,6 +797,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) @@ -797,6 +797,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root)
797 srs_trace("vhost %s reload forward success.", vhost.c_str()); 797 srs_trace("vhost %s reload forward success.", vhost.c_str());
798 } 798 }
799 // hls, only one per vhost 799 // hls, only one per vhost
  800 + // @remark, the hls_on_error directly support reload.
800 if (!srs_directive_equals(new_vhost->get("hls"), old_vhost->get("hls"))) { 801 if (!srs_directive_equals(new_vhost->get("hls"), old_vhost->get("hls"))) {
801 for (it = subscribes.begin(); it != subscribes.end(); ++it) { 802 for (it = subscribes.begin(); it != subscribes.end(); ++it) {
802 ISrsReloadHandler* subscribe = *it; 803 ISrsReloadHandler* subscribe = *it;
@@ -1356,7 +1357,7 @@ int SrsConfig::check_config() @@ -1356,7 +1357,7 @@ int SrsConfig::check_config()
1356 } else if (n == "hls") { 1357 } else if (n == "hls") {
1357 for (int j = 0; j < (int)conf->directives.size(); j++) { 1358 for (int j = 0; j < (int)conf->directives.size(); j++) {
1358 string m = conf->at(j)->name.c_str(); 1359 string m = conf->at(j)->name.c_str();
1359 - if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window") { 1360 + if (m != "enabled" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error") {
1360 ret = ERROR_SYSTEM_CONFIG_INVALID; 1361 ret = ERROR_SYSTEM_CONFIG_INVALID;
1361 srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); 1362 srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret);
1362 return ret; 1363 return ret;
@@ -2910,6 +2911,23 @@ double SrsConfig::get_hls_window(string vhost) @@ -2910,6 +2911,23 @@ double SrsConfig::get_hls_window(string vhost)
2910 return ::atof(conf->arg0().c_str()); 2911 return ::atof(conf->arg0().c_str());
2911 } 2912 }
2912 2913
  2914 +string SrsConfig::get_hls_on_error(string vhost)
  2915 +{
  2916 + SrsConfDirective* hls = get_hls(vhost);
  2917 +
  2918 + if (!hls) {
  2919 + return SRS_CONF_DEFAULT_HLS_ON_ERROR;
  2920 + }
  2921 +
  2922 + SrsConfDirective* conf = hls->get("hls_on_error");
  2923 +
  2924 + if (!conf) {
  2925 + return SRS_CONF_DEFAULT_HLS_ON_ERROR;
  2926 + }
  2927 +
  2928 + return conf->arg0();
  2929 +}
  2930 +
2913 SrsConfDirective* SrsConfig::get_dvr(string vhost) 2931 SrsConfDirective* SrsConfig::get_dvr(string vhost)
2914 { 2932 {
2915 SrsConfDirective* conf = get_vhost(vhost); 2933 SrsConfDirective* conf = get_vhost(vhost);
@@ -48,6 +48,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -48,6 +48,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48 #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html" 48 #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html"
49 #define SRS_CONF_DEFAULT_HLS_FRAGMENT 10 49 #define SRS_CONF_DEFAULT_HLS_FRAGMENT 10
50 #define SRS_CONF_DEFAULT_HLS_WINDOW 60 50 #define SRS_CONF_DEFAULT_HLS_WINDOW 60
  51 +#define SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE "ignore"
  52 +#define SRS_CONF_DEFAULT_HLS_ON_ERROR_DISCONNECT "disconnect"
  53 +#define SRS_CONF_DEFAULT_HLS_ON_ERROR SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE
51 #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html" 54 #define SRS_CONF_DEFAULT_DVR_PATH "./objs/nginx/html"
52 #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session" 55 #define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session"
53 #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment" 56 #define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment"
@@ -826,6 +829,13 @@ public: @@ -826,6 +829,13 @@ public:
826 * @remark SRS will delete the ts exceed the window. 829 * @remark SRS will delete the ts exceed the window.
827 */ 830 */
828 virtual double get_hls_window(std::string vhost); 831 virtual double get_hls_window(std::string vhost);
  832 + /**
  833 + * get the hls hls_on_error config.
  834 + * the ignore will ignore error and disable hls.
  835 + * the disconnect will disconnect publish connection.
  836 + * @see https://github.com/winlinvip/simple-rtmp-server/issues/264
  837 + */
  838 + virtual std::string get_hls_on_error(std::string vhost);
829 // dvr section 839 // dvr section
830 private: 840 private:
831 /** 841 /**
@@ -1435,10 +1435,11 @@ int SrsHls::on_audio(SrsSharedPtrMessage* audio) @@ -1435,10 +1435,11 @@ int SrsHls::on_audio(SrsSharedPtrMessage* audio)
1435 if (!hls_enabled) { 1435 if (!hls_enabled) {
1436 return ret; 1436 return ret;
1437 } 1437 }
  1438 +return 1;
1438 1439
1439 sample->clear(); 1440 sample->clear();
1440 if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) { 1441 if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) {
1441 - srs_error("codec demux audio failed. ret=%d", ret); 1442 + srs_error("hls codec demux audio failed. ret=%d", ret);
1442 return ret; 1443 return ret;
1443 } 1444 }
1444 1445
@@ -1482,7 +1483,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* video) @@ -1482,7 +1483,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* video)
1482 1483
1483 sample->clear(); 1484 sample->clear();
1484 if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) { 1485 if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) {
1485 - srs_error("codec demux video failed. ret=%d", ret); 1486 + srs_error("hls codec demux video failed. ret=%d", ret);
1486 return ret; 1487 return ret;
1487 } 1488 }
1488 1489
@@ -1056,13 +1056,21 @@ int SrsSource::on_audio(SrsMessage* __audio) @@ -1056,13 +1056,21 @@ int SrsSource::on_audio(SrsMessage* __audio)
1056 1056
1057 #ifdef SRS_AUTO_HLS 1057 #ifdef SRS_AUTO_HLS
1058 if ((ret = hls->on_audio(msg.copy())) != ERROR_SUCCESS) { 1058 if ((ret = hls->on_audio(msg.copy())) != ERROR_SUCCESS) {
1059 - srs_warn("hls process audio message failed, ignore and disable hls. ret=%d", ret);  
1060 -  
1061 - // unpublish, ignore ret.  
1062 - hls->on_unpublish();  
1063 -  
1064 - // ignore.  
1065 - ret = ERROR_SUCCESS; 1059 + // apply the error strategy for hls.
  1060 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/264
  1061 + std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost);
  1062 + if (hls_error_strategy == SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE) {
  1063 + srs_warn("hls process audio message failed, ignore and disable hls. ret=%d", ret);
  1064 +
  1065 + // unpublish, ignore ret.
  1066 + hls->on_unpublish();
  1067 +
  1068 + // ignore.
  1069 + ret = ERROR_SUCCESS;
  1070 + } else {
  1071 + srs_warn("hls disconnect publisher for audio error. ret=%d", ret);
  1072 + return ret;
  1073 + }
1066 } 1074 }
1067 #endif 1075 #endif
1068 1076
@@ -1113,7 +1121,7 @@ int SrsSource::on_audio(SrsMessage* __audio) @@ -1113,7 +1121,7 @@ int SrsSource::on_audio(SrsMessage* __audio)
1113 SrsAvcAacCodec codec; 1121 SrsAvcAacCodec codec;
1114 SrsCodecSample sample; 1122 SrsCodecSample sample;
1115 if ((ret = codec.audio_aac_demux(msg.payload, msg.size, &sample)) != ERROR_SUCCESS) { 1123 if ((ret = codec.audio_aac_demux(msg.payload, msg.size, &sample)) != ERROR_SUCCESS) {
1116 - srs_error("codec demux audio failed. ret=%d", ret); 1124 + srs_error("source codec demux audio failed. ret=%d", ret);
1117 return ret; 1125 return ret;
1118 } 1126 }
1119 1127
@@ -1165,13 +1173,21 @@ int SrsSource::on_video(SrsMessage* __video) @@ -1165,13 +1173,21 @@ int SrsSource::on_video(SrsMessage* __video)
1165 1173
1166 #ifdef SRS_AUTO_HLS 1174 #ifdef SRS_AUTO_HLS
1167 if ((ret = hls->on_video(msg.copy())) != ERROR_SUCCESS) { 1175 if ((ret = hls->on_video(msg.copy())) != ERROR_SUCCESS) {
1168 - srs_warn("hls process video message failed, ignore and disable hls. ret=%d", ret);  
1169 -  
1170 - // unpublish, ignore ret.  
1171 - hls->on_unpublish();  
1172 -  
1173 - // ignore.  
1174 - ret = ERROR_SUCCESS; 1176 + // apply the error strategy for hls.
  1177 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/264
  1178 + std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost);
  1179 + if (hls_error_strategy == SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE) {
  1180 + srs_warn("hls process video message failed, ignore and disable hls. ret=%d", ret);
  1181 +
  1182 + // unpublish, ignore ret.
  1183 + hls->on_unpublish();
  1184 +
  1185 + // ignore.
  1186 + ret = ERROR_SUCCESS;
  1187 + } else {
  1188 + srs_warn("hls disconnect publisher for video error. ret=%d", ret);
  1189 + return ret;
  1190 + }
1175 } 1191 }
1176 #endif 1192 #endif
1177 1193
@@ -1222,7 +1238,7 @@ int SrsSource::on_video(SrsMessage* __video) @@ -1222,7 +1238,7 @@ int SrsSource::on_video(SrsMessage* __video)
1222 SrsAvcAacCodec codec; 1238 SrsAvcAacCodec codec;
1223 SrsCodecSample sample; 1239 SrsCodecSample sample;
1224 if ((ret = codec.video_avc_demux(msg.payload, msg.size, &sample)) != ERROR_SUCCESS) { 1240 if ((ret = codec.video_avc_demux(msg.payload, msg.size, &sample)) != ERROR_SUCCESS) {
1225 - srs_error("codec demux video failed. ret=%d", ret); 1241 + srs_error("source codec demux video failed. ret=%d", ret);
1226 return ret; 1242 return ret;
1227 } 1243 }
1228 1244
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 1 32 #define VERSION_MAJOR 1
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 10 34 +#define VERSION_REVISION 11
35 // server info. 35 // server info.
36 #define RTMP_SIG_SRS_KEY "SRS" 36 #define RTMP_SIG_SRS_KEY "SRS"
37 #define RTMP_SIG_SRS_ROLE "origin/edge server" 37 #define RTMP_SIG_SRS_ROLE "origin/edge server"