mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	support hls_fragment and hls_window
This commit is contained in:
		
							parent
							
								
									04cfe20279
								
							
						
					
					
						commit
						00ec634d56
					
				
					 5 changed files with 76 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -62,8 +62,8 @@ m3u8 url: http://127.0.0.1:1935/live/livestream.m3u8
 | 
			
		|||
* nginx v1.5.0: 139524 lines <br/>
 | 
			
		||||
 | 
			
		||||
### History
 | 
			
		||||
* v0.5, 2013-11-24, support HLS(m3u8).
 | 
			
		||||
* v0.5, 2013-11-24, support write ts file.
 | 
			
		||||
* v0.5, 2013-11-24, support HLS(m3u8), fragment and window.
 | 
			
		||||
* v0.5, 2013-11-24, support record to ts file for HLS.
 | 
			
		||||
* v0.5, 2013-11-21, add ts_info tool to demux ts file.
 | 
			
		||||
* v0.5, 2013-11-16, add rtmp players(OSMF/jwplayer5/jwplayer6).
 | 
			
		||||
* v0.4, 2013-11-10, v0.4 released. 12500 lines.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -595,6 +595,28 @@ SrsConfDirective* SrsConfig::get_hls_path(std::string vhost)
 | 
			
		|||
	return conf->get("hls_path");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsConfDirective* SrsConfig::get_hls_fragment(std::string vhost)
 | 
			
		||||
{
 | 
			
		||||
	SrsConfDirective* conf = get_vhost(vhost);
 | 
			
		||||
 | 
			
		||||
	if (!conf) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return conf->get("hls_fragment");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsConfDirective* SrsConfig::get_hls_window(std::string vhost)
 | 
			
		||||
{
 | 
			
		||||
	SrsConfDirective* conf = get_vhost(vhost);
 | 
			
		||||
 | 
			
		||||
	if (!conf) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return conf->get("hls_window");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsConfDirective* SrsConfig::get_refer(std::string vhost)
 | 
			
		||||
{
 | 
			
		||||
	SrsConfDirective* conf = get_vhost(vhost);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		|||
#define RTMP_VHOST_DEFAULT "__defaultVhost__"
 | 
			
		||||
 | 
			
		||||
#define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html"
 | 
			
		||||
#define SRS_CONF_DEFAULT_HLS_FRAGMENT 10
 | 
			
		||||
#define SRS_CONF_DEFAULT_HLS_WINDOW 60
 | 
			
		||||
 | 
			
		||||
class SrsFileBuffer
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -111,6 +113,8 @@ public:
 | 
			
		|||
	virtual SrsConfDirective* get_gop_cache(std::string vhost);
 | 
			
		||||
	virtual SrsConfDirective* get_hls(std::string vhost);
 | 
			
		||||
	virtual SrsConfDirective* get_hls_path(std::string vhost);
 | 
			
		||||
	virtual SrsConfDirective* get_hls_fragment(std::string vhost);
 | 
			
		||||
	virtual SrsConfDirective* get_hls_window(std::string vhost);
 | 
			
		||||
	virtual SrsConfDirective* get_refer(std::string vhost);
 | 
			
		||||
	virtual SrsConfDirective* get_refer_play(std::string vhost);
 | 
			
		||||
	virtual SrsConfDirective* get_refer_publish(std::string vhost);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -370,6 +370,7 @@ SrsHLS::SrsHLS()
 | 
			
		|||
	jitter = new SrsRtmpJitter();
 | 
			
		||||
	file_index = 0;
 | 
			
		||||
	m3u8_dts = stream_dts = 0;
 | 
			
		||||
	hls_fragment = hls_window = 0;
 | 
			
		||||
	
 | 
			
		||||
	audio_buffer = new SrsCodecBuffer();
 | 
			
		||||
	video_buffer = new SrsCodecBuffer();
 | 
			
		||||
| 
						 | 
				
			
			@ -411,6 +412,23 @@ int SrsHLS::on_publish(std::string _vhost, std::string _app, std::string _stream
 | 
			
		|||
	stream = _stream;
 | 
			
		||||
	app = _app;
 | 
			
		||||
	
 | 
			
		||||
	// TODO: subscribe the reload event.
 | 
			
		||||
	
 | 
			
		||||
	SrsConfDirective* conf = NULL;
 | 
			
		||||
	if ((conf = config->get_hls_fragment(vhost)) != NULL && !conf->arg0().empty()) {
 | 
			
		||||
		hls_fragment = ::atoi(conf->arg0().c_str());
 | 
			
		||||
	}
 | 
			
		||||
	if (hls_fragment <= 0) {
 | 
			
		||||
		hls_fragment = SRS_CONF_DEFAULT_HLS_FRAGMENT;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if ((conf = config->get_hls_window(vhost)) != NULL && !conf->arg0().empty()) {
 | 
			
		||||
		hls_window = ::atoi(conf->arg0().c_str());
 | 
			
		||||
	}
 | 
			
		||||
	if (hls_window <= 0) {
 | 
			
		||||
		hls_window = SRS_CONF_DEFAULT_HLS_WINDOW;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if ((ret = reopen()) != ERROR_SUCCESS) {
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -555,9 +573,7 @@ int SrsHLS::on_video(SrsSharedPtrMessage* video)
 | 
			
		|||
	// reopen the muxer for a gop
 | 
			
		||||
	if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) {
 | 
			
		||||
		int64_t diff = stream_dts - m3u8_dts;
 | 
			
		||||
		// 10s.
 | 
			
		||||
		// TODO: config it.
 | 
			
		||||
		if (diff / 90000 >= 10) {
 | 
			
		||||
		if (diff / 90000 >= hls_fragment) {
 | 
			
		||||
			if ((ret = reopen()) != ERROR_SUCCESS) {
 | 
			
		||||
				return ret;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -603,12 +619,39 @@ int SrsHLS::reopen()
 | 
			
		|||
		segments.push_back(current);
 | 
			
		||||
		current = NULL;
 | 
			
		||||
		
 | 
			
		||||
		// the segments to remove
 | 
			
		||||
		std::vector<SrsM3u8Segment*> segment_to_remove;
 | 
			
		||||
		
 | 
			
		||||
		// shrink the segments.
 | 
			
		||||
		double duration = 0;
 | 
			
		||||
		std::vector<SrsM3u8Segment*>::reverse_iterator it;
 | 
			
		||||
		for (it = segments.rbegin(); it != segments.rend(); ++it) {
 | 
			
		||||
			SrsM3u8Segment* segment = *it;
 | 
			
		||||
			duration += segment->duration;
 | 
			
		||||
			
 | 
			
		||||
			if ((int)duration > hls_window) {
 | 
			
		||||
				segment_to_remove.push_back(segment);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!segment_to_remove.empty()) {
 | 
			
		||||
			segments.erase(segments.begin(), segments.begin() + segment_to_remove.size());
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// refresh the m3u8, donot contains the removed ts
 | 
			
		||||
		if ((ret = refresh_m3u8()) != ERROR_SUCCESS) {
 | 
			
		||||
			return ret;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// remove the ts file.
 | 
			
		||||
		for (it = segment_to_remove.rbegin(); it != segment_to_remove.rend(); ++it) {
 | 
			
		||||
			SrsM3u8Segment* segment = *it;
 | 
			
		||||
			unlink(segment->full_path.c_str());
 | 
			
		||||
			srs_freep(segment);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// new segment.
 | 
			
		||||
	current = new SrsM3u8Segment();
 | 
			
		||||
	current->sequence_no = file_index;
 | 
			
		||||
	m3u8_dts = current->segment_start_dts = stream_dts;
 | 
			
		||||
	
 | 
			
		||||
	// generate filename.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,6 +74,8 @@ private:
 | 
			
		|||
	std::string stream;
 | 
			
		||||
	std::string app;
 | 
			
		||||
	std::string hls_path;
 | 
			
		||||
	int hls_fragment;
 | 
			
		||||
	int hls_window;
 | 
			
		||||
private:
 | 
			
		||||
	int file_index;
 | 
			
		||||
	std::string m3u8;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue