diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index b7dd0a52a..16f3804d3 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -526,6 +526,13 @@ vhost with-hls.srs.com { # in a word, the hls_path is for vhost. # default: ./objs/nginx/html hls_path ./objs/nginx/html; + # the hls entry prefix, which is base url of ts url. + # if specified, the ts path in m3u8 will be like: + # http://your-server/live/livestream-0.ts + # http://your-server/live/livestream-1.ts + # ... + # optional, default to empty string. + hls_entry_prefix http://your-server/; # the hls mount for hls_storage ram, # which use srs embeded http server to delivery HLS, # where the mount specifies the HTTP url to mount. diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index faff46002..a66a77258 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -1480,7 +1480,7 @@ int SrsConfig::check_config() } else if (n == "hls") { for (int j = 0; j < (int)conf->directives.size(); j++) { string m = conf->at(j)->name.c_str(); - if (m != "enabled" && 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" ) { ret = ERROR_SYSTEM_CONFIG_INVALID; @@ -3138,6 +3138,33 @@ bool SrsConfig::get_hls_enabled(string vhost) return false; } +string SrsConfig::get_hls_entry_prefix(string vhost) +{ + SrsConfDirective* hls = get_hls(vhost); + + if (!hls) { + return ""; + } + + SrsConfDirective* conf = hls->get("hls_entry_prefix"); + + if (!conf) { + return ""; + } + + std::string prefix = conf->arg0(); + if (prefix.empty()) { + return ""; + } + + const char last = prefix[prefix.length() - 1]; + if (last != '/') { + return prefix.append("/"); + } + + return prefix; +} + string SrsConfig::get_hls_path(string vhost) { SrsConfDirective* hls = get_hls(vhost); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index ea16cc5f7..68b4b9bd4 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -866,6 +866,10 @@ public: */ virtual bool get_hls_enabled(std::string vhost); /** + * get the HLS m3u8 list ts segment entry prefix info. + */ + virtual std::string get_hls_entry_prefix(std::string vhost); + /** * get the HLS ts/m3u8 file store path. */ virtual std::string get_hls_path(std::string vhost); diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index 8d6dbc75f..4e24df273 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -203,13 +203,14 @@ int SrsHlsMuxer::sequence_no() return _sequence_no; } -int SrsHlsMuxer::update_config(SrsRequest* r, string path, int fragment, int window) +int SrsHlsMuxer::update_config(SrsRequest* r, string hls_entry_prefix, string path, int fragment, int window) { int ret = ERROR_SUCCESS; srs_freep(req); req = r->copy(); + entry_prefix = hls_entry_prefix; hls_path = path; hls_fragment = fragment; hls_window = window; @@ -301,7 +302,8 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) current->full_path += filename; // TODO: support base url, and so on. - current->uri = filename; + current->uri += entry_prefix; + current->uri += filename; std::string tmp_file = current->full_path + ".tmp"; if ((ret = current->muxer->open(tmp_file.c_str())) != ERROR_SUCCESS) { @@ -668,6 +670,8 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment int hls_fragment = (int)_srs_config->get_hls_fragment(vhost); int hls_window = (int)_srs_config->get_hls_window(vhost); + // get the hls m3u8 ts list entry prefix config + std::string entry_prefix = _srs_config->get_hls_entry_prefix(vhost); // get the hls path config std::string hls_path = _srs_config->get_hls_path(vhost); @@ -675,7 +679,7 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment // for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase. // open muxer - if ((ret = muxer->update_config(req, hls_path, hls_fragment, hls_window)) != ERROR_SUCCESS) { + if ((ret = muxer->update_config(req, entry_prefix, hls_path, hls_fragment, hls_window)) != ERROR_SUCCESS) { srs_error("m3u8 muxer update config failed. ret=%d", ret); return ret; } diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp index 62660b3a7..be90b791d 100644 --- a/trunk/src/app/srs_app_hls.hpp +++ b/trunk/src/app/srs_app_hls.hpp @@ -167,6 +167,7 @@ class SrsHlsMuxer private: SrsRequest* req; private: + std::string entry_prefix; std::string hls_path; int hls_fragment; int hls_window; @@ -207,7 +208,7 @@ public: /** * when publish, update the config for muxer. */ - virtual int update_config(SrsRequest* r, std::string path, int fragment, int window); + virtual int update_config(SrsRequest* r, std::string hls_entry_prefix, std::string path, int fragment, int window); /** * open a new segment(a new ts file), * @param segment_start_dts use to calc the segment duration,