正在显示
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); |
@@ -3202,7 +3202,24 @@ double SrsConfig::get_hls_td_ratio(string vhost) | @@ -3202,7 +3202,24 @@ double SrsConfig::get_hls_td_ratio(string vhost) | ||
3202 | if (!conf) { | 3202 | if (!conf) { |
3203 | return SRS_CONF_DEFAULT_HLS_TD_RATIO; | 3203 | return SRS_CONF_DEFAULT_HLS_TD_RATIO; |
3204 | } | 3204 | } |
3205 | + | ||
3206 | + return ::atof(conf->arg0().c_str()); | ||
3207 | +} | ||
3205 | 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 | + | ||
3206 | return ::atof(conf->arg0().c_str()); | 3223 | return ::atof(conf->arg0().c_str()); |
3207 | } | 3224 | } |
3208 | 3225 |
@@ -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, |
-
请 注册 或 登录 后发表评论