正在显示
5 个修改的文件
包含
43 行增加
和
16 行删除
| @@ -498,6 +498,12 @@ vhost with-hls.srs.com { | @@ -498,6 +498,12 @@ vhost with-hls.srs.com { | ||
| 498 | # @see https://github.com/winlinvip/simple-rtmp-server/issues/304#issuecomment-74000081 | 498 | # @see https://github.com/winlinvip/simple-rtmp-server/issues/304#issuecomment-74000081 |
| 499 | # default: 1.5 | 499 | # default: 1.5 |
| 500 | hls_td_ratio 1.5; | 500 | hls_td_ratio 1.5; |
| 501 | + # the audio overflow ratio. | ||
| 502 | + # for pure audio, the duration to reap the segment. | ||
| 503 | + # for example, the hls_fragment is 10s, hsl_aof_ratio is 2.0, | ||
| 504 | + # the segemnt will reap to 20s for pure audio. | ||
| 505 | + # default: 2.0 | ||
| 506 | + hls_aof_ratio 2.0; | ||
| 501 | # the hls window in seconds, the number of ts in m3u8. | 507 | # the hls window in seconds, the number of ts in m3u8. |
| 502 | # default: 60 | 508 | # default: 60 |
| 503 | hls_window 60; | 509 | hls_window 60; |
| @@ -1481,7 +1481,7 @@ int SrsConfig::check_config() | @@ -1481,7 +1481,7 @@ int SrsConfig::check_config() | ||
| 1481 | for (int j = 0; j < (int)conf->directives.size(); j++) { | 1481 | for (int j = 0; j < (int)conf->directives.size(); j++) { |
| 1482 | string m = conf->at(j)->name.c_str(); | 1482 | string m = conf->at(j)->name.c_str(); |
| 1483 | if (m != "enabled" && m != "hls_entry_prefix" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error" | 1483 | if (m != "enabled" && m != "hls_entry_prefix" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error" |
| 1484 | - && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_acodec" && m != "hls_vcodec" | 1484 | + && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_aof_ratio" && m != "hls_acodec" && m != "hls_vcodec" |
| 1485 | ) { | 1485 | ) { |
| 1486 | ret = ERROR_SYSTEM_CONFIG_INVALID; | 1486 | ret = ERROR_SYSTEM_CONFIG_INVALID; |
| 1487 | srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); | 1487 | srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret); |
| @@ -3206,6 +3206,23 @@ double SrsConfig::get_hls_td_ratio(string vhost) | @@ -3206,6 +3206,23 @@ double SrsConfig::get_hls_td_ratio(string vhost) | ||
| 3206 | return ::atof(conf->arg0().c_str()); | 3206 | return ::atof(conf->arg0().c_str()); |
| 3207 | } | 3207 | } |
| 3208 | 3208 | ||
| 3209 | +double SrsConfig::get_hls_aof_ratio(string vhost) | ||
| 3210 | +{ | ||
| 3211 | + SrsConfDirective* hls = get_hls(vhost); | ||
| 3212 | + | ||
| 3213 | + if (!hls) { | ||
| 3214 | + return SRS_CONF_DEFAULT_HLS_AOF_RATIO; | ||
| 3215 | + } | ||
| 3216 | + | ||
| 3217 | + SrsConfDirective* conf = hls->get("hls_aof_ratio"); | ||
| 3218 | + | ||
| 3219 | + if (!conf) { | ||
| 3220 | + return SRS_CONF_DEFAULT_HLS_AOF_RATIO; | ||
| 3221 | + } | ||
| 3222 | + | ||
| 3223 | + return ::atof(conf->arg0().c_str()); | ||
| 3224 | +} | ||
| 3225 | + | ||
| 3209 | double SrsConfig::get_hls_window(string vhost) | 3226 | double SrsConfig::get_hls_window(string vhost) |
| 3210 | { | 3227 | { |
| 3211 | SrsConfDirective* hls = get_hls(vhost); | 3228 | SrsConfDirective* hls = get_hls(vhost); |
| @@ -48,6 +48,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -48,6 +48,7 @@ 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_TD_RATIO 1.5 | 50 | #define SRS_CONF_DEFAULT_HLS_TD_RATIO 1.5 |
| 51 | +#define SRS_CONF_DEFAULT_HLS_AOF_RATIO 2.0 | ||
| 51 | #define SRS_CONF_DEFAULT_HLS_WINDOW 60 | 52 | #define SRS_CONF_DEFAULT_HLS_WINDOW 60 |
| 52 | #define SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE "ignore" | 53 | #define SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE "ignore" |
| 53 | #define SRS_CONF_DEFAULT_HLS_ON_ERROR_DISCONNECT "disconnect" | 54 | #define SRS_CONF_DEFAULT_HLS_ON_ERROR_DISCONNECT "disconnect" |
| @@ -875,15 +876,17 @@ public: | @@ -875,15 +876,17 @@ public: | ||
| 875 | virtual std::string get_hls_path(std::string vhost); | 876 | virtual std::string get_hls_path(std::string vhost); |
| 876 | /** | 877 | /** |
| 877 | * get the hls fragment time, in seconds. | 878 | * get the hls fragment time, in seconds. |
| 878 | - * a fragment is a ts file. | ||
| 879 | */ | 879 | */ |
| 880 | virtual double get_hls_fragment(std::string vhost); | 880 | virtual double get_hls_fragment(std::string vhost); |
| 881 | /** | 881 | /** |
| 882 | * get the hls td(target duration) ratio. | 882 | * get the hls td(target duration) ratio. |
| 883 | - * a fragment is a ts file. | ||
| 884 | */ | 883 | */ |
| 885 | virtual double get_hls_td_ratio(std::string vhost); | 884 | virtual double get_hls_td_ratio(std::string vhost); |
| 886 | /** | 885 | /** |
| 886 | + * get the hls aof(audio overflow) ratio. | ||
| 887 | + */ | ||
| 888 | + virtual double get_hls_aof_ratio(std::string vhost); | ||
| 889 | + /** | ||
| 887 | * get the hls window time, in seconds. | 890 | * get the hls window time, in seconds. |
| 888 | * a window is a set of ts, the ts collection in m3u8. | 891 | * a window is a set of ts, the ts collection in m3u8. |
| 889 | * @remark SRS will delete the ts exceed the window. | 892 | * @remark SRS will delete the ts exceed the window. |
| @@ -168,6 +168,7 @@ SrsHlsMuxer::SrsHlsMuxer() | @@ -168,6 +168,7 @@ SrsHlsMuxer::SrsHlsMuxer() | ||
| 168 | req = NULL; | 168 | req = NULL; |
| 169 | handler = NULL; | 169 | handler = NULL; |
| 170 | hls_fragment = hls_window = 0; | 170 | hls_fragment = hls_window = 0; |
| 171 | + hls_aof_ratio = 1.0; | ||
| 171 | target_duration = 0; | 172 | target_duration = 0; |
| 172 | _sequence_no = 0; | 173 | _sequence_no = 0; |
| 173 | current = NULL; | 174 | current = NULL; |
| @@ -203,7 +204,7 @@ int SrsHlsMuxer::sequence_no() | @@ -203,7 +204,7 @@ int SrsHlsMuxer::sequence_no() | ||
| 203 | return _sequence_no; | 204 | return _sequence_no; |
| 204 | } | 205 | } |
| 205 | 206 | ||
| 206 | -int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, string path, int fragment, int window) | 207 | +int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, string path, int fragment, int window, double aof_ratio) |
| 207 | { | 208 | { |
| 208 | int ret = ERROR_SUCCESS; | 209 | int ret = ERROR_SUCCESS; |
| 209 | 210 | ||
| @@ -213,11 +214,12 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, string path, | @@ -213,11 +214,12 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, string path, | ||
| 213 | hls_entry_prefix = entry_prefix; | 214 | hls_entry_prefix = entry_prefix; |
| 214 | hls_path = path; | 215 | hls_path = path; |
| 215 | hls_fragment = fragment; | 216 | hls_fragment = fragment; |
| 217 | + hls_aof_ratio = aof_ratio; | ||
| 216 | hls_window = window; | 218 | hls_window = window; |
| 217 | 219 | ||
| 218 | // we always keep the target duration increasing. | 220 | // we always keep the target duration increasing. |
| 219 | int max_td = srs_max(target_duration, (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost))); | 221 | int max_td = srs_max(target_duration, (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost))); |
| 220 | - srs_info("hls update target duration %d=>%d", target_duration, max_td); | 222 | + srs_info("hls update target duration %d=>%d, aof=%.2f", target_duration, max_td, aof_ratio); |
| 221 | target_duration = max_td; | 223 | target_duration = max_td; |
| 222 | 224 | ||
| 223 | std::string storage = _srs_config->get_hls_storage(r->vhost); | 225 | std::string storage = _srs_config->get_hls_storage(r->vhost); |
| @@ -345,7 +347,7 @@ bool SrsHlsMuxer::is_segment_overflow() | @@ -345,7 +347,7 @@ bool SrsHlsMuxer::is_segment_overflow() | ||
| 345 | bool SrsHlsMuxer::is_segment_absolutely_overflow() | 347 | bool SrsHlsMuxer::is_segment_absolutely_overflow() |
| 346 | { | 348 | { |
| 347 | srs_assert(current); | 349 | srs_assert(current); |
| 348 | - return current->duration >= 2 * hls_fragment; | 350 | + return current->duration >= hls_aof_ratio * hls_fragment; |
| 349 | } | 351 | } |
| 350 | 352 | ||
| 351 | int SrsHlsMuxer::update_acodec(SrsCodecAudio ac) | 353 | int SrsHlsMuxer::update_acodec(SrsCodecAudio ac) |
| @@ -676,12 +678,14 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment | @@ -676,12 +678,14 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment | ||
| 676 | std::string entry_prefix = _srs_config->get_hls_entry_prefix(vhost); | 678 | std::string entry_prefix = _srs_config->get_hls_entry_prefix(vhost); |
| 677 | // get the hls path config | 679 | // get the hls path config |
| 678 | std::string hls_path = _srs_config->get_hls_path(vhost); | 680 | std::string hls_path = _srs_config->get_hls_path(vhost); |
| 681 | + // the audio overflow, for pure audio to reap segment. | ||
| 682 | + double hls_aof_ratio = _srs_config->get_hls_aof_ratio(vhost); | ||
| 679 | 683 | ||
| 680 | // TODO: FIXME: support load exists m3u8, to continue publish stream. | 684 | // TODO: FIXME: support load exists m3u8, to continue publish stream. |
| 681 | // for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase. | 685 | // for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase. |
| 682 | 686 | ||
| 683 | // open muxer | 687 | // open muxer |
| 684 | - if ((ret = muxer->update_config(req, entry_prefix, hls_path, hls_fragment, hls_window)) != ERROR_SUCCESS) { | 688 | + if ((ret = muxer->update_config(req, entry_prefix, hls_path, hls_fragment, hls_window, hls_aof_ratio)) != ERROR_SUCCESS) { |
| 685 | srs_error("m3u8 muxer update config failed. ret=%d", ret); | 689 | srs_error("m3u8 muxer update config failed. ret=%d", ret); |
| 686 | return ret; | 690 | return ret; |
| 687 | } | 691 | } |
| @@ -737,17 +741,13 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -737,17 +741,13 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
| 737 | } | 741 | } |
| 738 | } | 742 | } |
| 739 | 743 | ||
| 740 | - // cache->audio will be free in flush_audio | ||
| 741 | - // so we must check whether it's null ptr. | ||
| 742 | - if (!cache->audio) { | ||
| 743 | - return ret; | ||
| 744 | - } | ||
| 745 | - | ||
| 746 | // TODO: config it. | 744 | // TODO: config it. |
| 747 | // in ms, audio delay to flush the audios. | 745 | // in ms, audio delay to flush the audios. |
| 748 | int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY; | 746 | int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY; |
| 749 | // flush if audio delay exceed | 747 | // flush if audio delay exceed |
| 750 | - if (pts - cache->audio->start_pts > audio_delay * 90) { | 748 | + // cache->audio will be free in flush_audio |
| 749 | + // so we must check whether it's null ptr. | ||
| 750 | + if (cache->audio && pts - cache->audio->start_pts > audio_delay * 90) { | ||
| 751 | if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) { | 751 | if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) { |
| 752 | return ret; | 752 | return ret; |
| 753 | } | 753 | } |
| @@ -761,7 +761,7 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -761,7 +761,7 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
| 761 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/151 | 761 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/151 |
| 762 | // we use absolutely overflow of segment to make jwplayer/ffplay happy | 762 | // we use absolutely overflow of segment to make jwplayer/ffplay happy |
| 763 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/151#issuecomment-71155184 | 763 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/151#issuecomment-71155184 |
| 764 | - if (muxer->is_segment_absolutely_overflow()) { | 764 | + if (cache->audio && muxer->is_segment_absolutely_overflow()) { |
| 765 | if ((ret = reap_segment("audio", muxer, cache->audio->pts)) != ERROR_SUCCESS) { | 765 | if ((ret = reap_segment("audio", muxer, cache->audio->pts)) != ERROR_SUCCESS) { |
| 766 | return ret; | 766 | return ret; |
| 767 | } | 767 | } |
| @@ -169,6 +169,7 @@ private: | @@ -169,6 +169,7 @@ private: | ||
| 169 | private: | 169 | private: |
| 170 | std::string hls_entry_prefix; | 170 | std::string hls_entry_prefix; |
| 171 | std::string hls_path; | 171 | std::string hls_path; |
| 172 | + double hls_aof_ratio; | ||
| 172 | int hls_fragment; | 173 | int hls_fragment; |
| 173 | int hls_window; | 174 | int hls_window; |
| 174 | private: | 175 | private: |
| @@ -208,7 +209,7 @@ public: | @@ -208,7 +209,7 @@ public: | ||
| 208 | /** | 209 | /** |
| 209 | * when publish, update the config for muxer. | 210 | * when publish, update the config for muxer. |
| 210 | */ | 211 | */ |
| 211 | - virtual int update_config(SrsRequest* r, std::string entry_prefix, std::string path, int fragment, int window); | 212 | + virtual int update_config(SrsRequest* r, std::string entry_prefix, std::string path, int fragment, int window, double aof_ratio); |
| 212 | /** | 213 | /** |
| 213 | * open a new segment(a new ts file), | 214 | * open a new segment(a new ts file), |
| 214 | * @param segment_start_dts use to calc the segment duration, | 215 | * @param segment_start_dts use to calc the segment duration, |
-
请 注册 或 登录 后发表评论