mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	support config the audio overflow ratio.
This commit is contained in:
		
							parent
							
								
									e319da3329
								
							
						
					
					
						commit
						0319e85f99
					
				
					 5 changed files with 43 additions and 16 deletions
				
			
		| 
						 | 
					@ -498,6 +498,12 @@ vhost with-hls.srs.com {
 | 
				
			||||||
        # @see https://github.com/winlinvip/simple-rtmp-server/issues/304#issuecomment-74000081
 | 
					        # @see https://github.com/winlinvip/simple-rtmp-server/issues/304#issuecomment-74000081
 | 
				
			||||||
        # default: 1.5
 | 
					        # default: 1.5
 | 
				
			||||||
        hls_td_ratio    1.5;
 | 
					        hls_td_ratio    1.5;
 | 
				
			||||||
 | 
					        # the audio overflow ratio.
 | 
				
			||||||
 | 
					        # for pure audio, the duration to reap the segment.
 | 
				
			||||||
 | 
					        # for example, the hls_fragment is 10s, hsl_aof_ratio is 2.0,
 | 
				
			||||||
 | 
					        # the segemnt will reap to 20s for pure audio.
 | 
				
			||||||
 | 
					        # default: 2.0
 | 
				
			||||||
 | 
					        hls_aof_ratio   2.0;
 | 
				
			||||||
        # the hls window in seconds, the number of ts in m3u8.
 | 
					        # the hls window in seconds, the number of ts in m3u8.
 | 
				
			||||||
        # default: 60
 | 
					        # default: 60
 | 
				
			||||||
        hls_window      60;
 | 
					        hls_window      60;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1481,7 +1481,7 @@ int SrsConfig::check_config()
 | 
				
			||||||
                for (int j = 0; j < (int)conf->directives.size(); j++) {
 | 
					                for (int j = 0; j < (int)conf->directives.size(); j++) {
 | 
				
			||||||
                    string m = conf->at(j)->name.c_str();
 | 
					                    string m = conf->at(j)->name.c_str();
 | 
				
			||||||
                    if (m != "enabled" && m != "hls_entry_prefix" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error"
 | 
					                    if (m != "enabled" && m != "hls_entry_prefix" && m != "hls_path" && m != "hls_fragment" && m != "hls_window" && m != "hls_on_error"
 | 
				
			||||||
                        && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_acodec" && m != "hls_vcodec"
 | 
					                        && m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_aof_ratio" && m != "hls_acodec" && m != "hls_vcodec"
 | 
				
			||||||
                    ) {
 | 
					                    ) {
 | 
				
			||||||
                        ret = ERROR_SYSTEM_CONFIG_INVALID;
 | 
					                        ret = ERROR_SYSTEM_CONFIG_INVALID;
 | 
				
			||||||
                        srs_error("unsupported vhost hls directive %s, ret=%d", m.c_str(), ret);
 | 
					                        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)
 | 
				
			||||||
    if (!conf) {
 | 
					    if (!conf) {
 | 
				
			||||||
        return SRS_CONF_DEFAULT_HLS_TD_RATIO;
 | 
					        return SRS_CONF_DEFAULT_HLS_TD_RATIO;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return ::atof(conf->arg0().c_str());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double SrsConfig::get_hls_aof_ratio(string vhost)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SrsConfDirective* hls = get_hls(vhost);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!hls) {
 | 
				
			||||||
 | 
					        return SRS_CONF_DEFAULT_HLS_AOF_RATIO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    SrsConfDirective* conf = hls->get("hls_aof_ratio");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!conf) {
 | 
				
			||||||
 | 
					        return SRS_CONF_DEFAULT_HLS_AOF_RATIO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    return ::atof(conf->arg0().c_str());
 | 
					    return ::atof(conf->arg0().c_str());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,7 @@ 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_PATH "./objs/nginx/html"
 | 
				
			||||||
#define SRS_CONF_DEFAULT_HLS_FRAGMENT 10
 | 
					#define SRS_CONF_DEFAULT_HLS_FRAGMENT 10
 | 
				
			||||||
#define SRS_CONF_DEFAULT_HLS_TD_RATIO 1.5
 | 
					#define SRS_CONF_DEFAULT_HLS_TD_RATIO 1.5
 | 
				
			||||||
 | 
					#define SRS_CONF_DEFAULT_HLS_AOF_RATIO 2.0
 | 
				
			||||||
#define SRS_CONF_DEFAULT_HLS_WINDOW 60
 | 
					#define SRS_CONF_DEFAULT_HLS_WINDOW 60
 | 
				
			||||||
#define SRS_CONF_DEFAULT_HLS_ON_ERROR_IGNORE "ignore"
 | 
					#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_DISCONNECT "disconnect"
 | 
				
			||||||
| 
						 | 
					@ -875,14 +876,16 @@ public:
 | 
				
			||||||
    virtual std::string         get_hls_path(std::string vhost);
 | 
					    virtual std::string         get_hls_path(std::string vhost);
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    * get the hls fragment time, in seconds.
 | 
					    * get the hls fragment time, in seconds.
 | 
				
			||||||
    * a fragment is a ts file.
 | 
					 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
    virtual double              get_hls_fragment(std::string vhost);
 | 
					    virtual double              get_hls_fragment(std::string vhost);
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    * get the hls td(target duration) ratio.
 | 
					    * get the hls td(target duration) ratio.
 | 
				
			||||||
    * a fragment is a ts file.
 | 
					 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
    virtual double              get_hls_td_ratio(std::string vhost);
 | 
					    virtual double              get_hls_td_ratio(std::string vhost);
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * get the hls aof(audio overflow) ratio.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual double              get_hls_aof_ratio(std::string vhost);
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    * get the hls window time, in seconds.
 | 
					    * get the hls window time, in seconds.
 | 
				
			||||||
    * a window is a set of ts, the ts collection in m3u8.
 | 
					    * a window is a set of ts, the ts collection in m3u8.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,6 +168,7 @@ SrsHlsMuxer::SrsHlsMuxer()
 | 
				
			||||||
    req = NULL;
 | 
					    req = NULL;
 | 
				
			||||||
    handler = NULL;
 | 
					    handler = NULL;
 | 
				
			||||||
    hls_fragment = hls_window = 0;
 | 
					    hls_fragment = hls_window = 0;
 | 
				
			||||||
 | 
					    hls_aof_ratio = 1.0;
 | 
				
			||||||
    target_duration = 0;
 | 
					    target_duration = 0;
 | 
				
			||||||
    _sequence_no = 0;
 | 
					    _sequence_no = 0;
 | 
				
			||||||
    current = NULL;
 | 
					    current = NULL;
 | 
				
			||||||
| 
						 | 
					@ -203,7 +204,7 @@ int SrsHlsMuxer::sequence_no()
 | 
				
			||||||
    return _sequence_no;
 | 
					    return _sequence_no;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, string path, int fragment, int window)
 | 
					int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, string path, int fragment, int window, double aof_ratio)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret = ERROR_SUCCESS;
 | 
					    int ret = ERROR_SUCCESS;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -213,11 +214,12 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, string path,
 | 
				
			||||||
    hls_entry_prefix = entry_prefix;
 | 
					    hls_entry_prefix = entry_prefix;
 | 
				
			||||||
    hls_path = path;
 | 
					    hls_path = path;
 | 
				
			||||||
    hls_fragment = fragment;
 | 
					    hls_fragment = fragment;
 | 
				
			||||||
 | 
					    hls_aof_ratio = aof_ratio;
 | 
				
			||||||
    hls_window = window;
 | 
					    hls_window = window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // we always keep the target duration increasing.
 | 
					    // we always keep the target duration increasing.
 | 
				
			||||||
    int max_td = srs_max(target_duration, (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost)));
 | 
					    int max_td = srs_max(target_duration, (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost)));
 | 
				
			||||||
    srs_info("hls update target duration %d=>%d", target_duration, max_td);
 | 
					    srs_info("hls update target duration %d=>%d, aof=%.2f", target_duration, max_td, aof_ratio);
 | 
				
			||||||
    target_duration = max_td;
 | 
					    target_duration = max_td;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string storage = _srs_config->get_hls_storage(r->vhost);
 | 
					    std::string storage = _srs_config->get_hls_storage(r->vhost);
 | 
				
			||||||
| 
						 | 
					@ -345,7 +347,7 @@ bool SrsHlsMuxer::is_segment_overflow()
 | 
				
			||||||
bool SrsHlsMuxer::is_segment_absolutely_overflow()
 | 
					bool SrsHlsMuxer::is_segment_absolutely_overflow()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    srs_assert(current);
 | 
					    srs_assert(current);
 | 
				
			||||||
    return current->duration >= 2 * hls_fragment;
 | 
					    return current->duration >= hls_aof_ratio * hls_fragment;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int SrsHlsMuxer::update_acodec(SrsCodecAudio ac)
 | 
					int SrsHlsMuxer::update_acodec(SrsCodecAudio ac)
 | 
				
			||||||
| 
						 | 
					@ -676,12 +678,14 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment
 | 
				
			||||||
    std::string entry_prefix = _srs_config->get_hls_entry_prefix(vhost);
 | 
					    std::string entry_prefix = _srs_config->get_hls_entry_prefix(vhost);
 | 
				
			||||||
    // get the hls path config
 | 
					    // get the hls path config
 | 
				
			||||||
    std::string hls_path = _srs_config->get_hls_path(vhost);
 | 
					    std::string hls_path = _srs_config->get_hls_path(vhost);
 | 
				
			||||||
 | 
					    // the audio overflow, for pure audio to reap segment.
 | 
				
			||||||
 | 
					    double hls_aof_ratio = _srs_config->get_hls_aof_ratio(vhost);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // TODO: FIXME: support load exists m3u8, to continue publish stream.
 | 
					    // TODO: FIXME: support load exists m3u8, to continue publish stream.
 | 
				
			||||||
    // for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase.
 | 
					    // for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase.
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // open muxer
 | 
					    // open muxer
 | 
				
			||||||
    if ((ret = muxer->update_config(req, entry_prefix, hls_path, hls_fragment, hls_window)) != ERROR_SUCCESS) {
 | 
					    if ((ret = muxer->update_config(req, entry_prefix, hls_path, hls_fragment, hls_window, hls_aof_ratio)) != ERROR_SUCCESS) {
 | 
				
			||||||
        srs_error("m3u8 muxer update config failed. ret=%d", ret);
 | 
					        srs_error("m3u8 muxer update config failed. ret=%d", ret);
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -737,17 +741,13 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // cache->audio will be free in flush_audio
 | 
					 | 
				
			||||||
    // so we must check whether it's null ptr.
 | 
					 | 
				
			||||||
    if (!cache->audio) {
 | 
					 | 
				
			||||||
        return ret;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // TODO: config it.
 | 
					    // TODO: config it.
 | 
				
			||||||
    // in ms, audio delay to flush the audios.
 | 
					    // in ms, audio delay to flush the audios.
 | 
				
			||||||
    int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY;
 | 
					    int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY;
 | 
				
			||||||
    // flush if audio delay exceed
 | 
					    // flush if audio delay exceed
 | 
				
			||||||
    if (pts - cache->audio->start_pts > audio_delay * 90) {
 | 
					    // cache->audio will be free in flush_audio
 | 
				
			||||||
 | 
					    // so we must check whether it's null ptr.
 | 
				
			||||||
 | 
					    if (cache->audio && pts - cache->audio->start_pts > audio_delay * 90) {
 | 
				
			||||||
        if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) {
 | 
					        if ((ret = muxer->flush_audio(cache)) != ERROR_SUCCESS) {
 | 
				
			||||||
            return ret;
 | 
					            return ret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -761,7 +761,7 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
 | 
				
			||||||
    // @see https://github.com/winlinvip/simple-rtmp-server/issues/151
 | 
					    // @see https://github.com/winlinvip/simple-rtmp-server/issues/151
 | 
				
			||||||
    // we use absolutely overflow of segment to make jwplayer/ffplay happy
 | 
					    // we use absolutely overflow of segment to make jwplayer/ffplay happy
 | 
				
			||||||
    // @see https://github.com/winlinvip/simple-rtmp-server/issues/151#issuecomment-71155184
 | 
					    // @see https://github.com/winlinvip/simple-rtmp-server/issues/151#issuecomment-71155184
 | 
				
			||||||
    if (muxer->is_segment_absolutely_overflow()) {
 | 
					    if (cache->audio && muxer->is_segment_absolutely_overflow()) {
 | 
				
			||||||
        if ((ret = reap_segment("audio", muxer, cache->audio->pts)) != ERROR_SUCCESS) {
 | 
					        if ((ret = reap_segment("audio", muxer, cache->audio->pts)) != ERROR_SUCCESS) {
 | 
				
			||||||
            return ret;
 | 
					            return ret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,6 +169,7 @@ private:
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    std::string hls_entry_prefix;
 | 
					    std::string hls_entry_prefix;
 | 
				
			||||||
    std::string hls_path;
 | 
					    std::string hls_path;
 | 
				
			||||||
 | 
					    double hls_aof_ratio;
 | 
				
			||||||
    int hls_fragment;
 | 
					    int hls_fragment;
 | 
				
			||||||
    int hls_window;
 | 
					    int hls_window;
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
| 
						 | 
					@ -208,7 +209,7 @@ public:
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    * when publish, update the config for muxer.
 | 
					    * when publish, update the config for muxer.
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
    virtual int update_config(SrsRequest* r, std::string entry_prefix, std::string path, int fragment, int window);
 | 
					    virtual int update_config(SrsRequest* r, std::string entry_prefix, std::string path, int fragment, int window, double aof_ratio);
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    * open a new segment(a new ts file),
 | 
					    * open a new segment(a new ts file),
 | 
				
			||||||
    * @param segment_start_dts use to calc the segment duration,
 | 
					    * @param segment_start_dts use to calc the segment duration,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue