正在显示
8 个修改的文件
包含
73 行增加
和
20 行删除
| @@ -44,6 +44,11 @@ max_connections 1000; | @@ -44,6 +44,11 @@ max_connections 1000; | ||
| 44 | # @remark: donot support reload. | 44 | # @remark: donot support reload. |
| 45 | # default: on | 45 | # default: on |
| 46 | daemon on; | 46 | daemon on; |
| 47 | +# whether use utc_time to generate the time struct, | ||
| 48 | +# if off, use localtime() to generate it, | ||
| 49 | +# if on, use gmtime() instead, which use UTC time. | ||
| 50 | +# default: off | ||
| 51 | +utc_time off; | ||
| 47 | 52 | ||
| 48 | ############################################################################################# | 53 | ############################################################################################# |
| 49 | # heartbeat/stats sections | 54 | # heartbeat/stats sections |
| @@ -1336,7 +1336,8 @@ int SrsConfig::check_config() | @@ -1336,7 +1336,8 @@ int SrsConfig::check_config() | ||
| 1336 | && n != "srs_log_tank" && n != "srs_log_level" && n != "srs_log_file" | 1336 | && n != "srs_log_tank" && n != "srs_log_level" && n != "srs_log_file" |
| 1337 | && n != "max_connections" && n != "daemon" && n != "heartbeat" | 1337 | && n != "max_connections" && n != "daemon" && n != "heartbeat" |
| 1338 | && n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms" | 1338 | && n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms" |
| 1339 | - && n != "http_stream" && n != "http_server" && n != "stream_caster") | 1339 | + && n != "http_stream" && n != "http_server" && n != "stream_caster" |
| 1340 | + && n != "utc_time") | ||
| 1340 | { | 1341 | { |
| 1341 | ret = ERROR_SYSTEM_CONFIG_INVALID; | 1342 | ret = ERROR_SYSTEM_CONFIG_INVALID; |
| 1342 | srs_error("unsupported directive %s, ret=%d", n.c_str(), ret); | 1343 | srs_error("unsupported directive %s, ret=%d", n.c_str(), ret); |
| @@ -1896,6 +1897,16 @@ int SrsConfig::get_pithy_print_ms() | @@ -1896,6 +1897,16 @@ int SrsConfig::get_pithy_print_ms() | ||
| 1896 | return ::atoi(pithy->arg0().c_str()); | 1897 | return ::atoi(pithy->arg0().c_str()); |
| 1897 | } | 1898 | } |
| 1898 | 1899 | ||
| 1900 | +bool SrsConfig::get_utc_time() | ||
| 1901 | +{ | ||
| 1902 | + SrsConfDirective* utc = root->get("utc_time"); | ||
| 1903 | + if (!utc || utc->arg0().empty()) { | ||
| 1904 | + return SRS_CONF_DEFAULT_UTC_TIME; | ||
| 1905 | + } | ||
| 1906 | + | ||
| 1907 | + return utc->arg0() == "on"; | ||
| 1908 | +} | ||
| 1909 | + | ||
| 1899 | vector<SrsConfDirective*> SrsConfig::get_stream_casters() | 1910 | vector<SrsConfDirective*> SrsConfig::get_stream_casters() |
| 1900 | { | 1911 | { |
| 1901 | srs_assert(root); | 1912 | srs_assert(root); |
| @@ -43,6 +43,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -43,6 +43,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 43 | #define SRS_CONF_DEFAULT_LOG_TANK_CONSOLE "console" | 43 | #define SRS_CONF_DEFAULT_LOG_TANK_CONSOLE "console" |
| 44 | #define SRS_CONF_DEFAULT_COFNIG_FILE "conf/srs.conf" | 44 | #define SRS_CONF_DEFAULT_COFNIG_FILE "conf/srs.conf" |
| 45 | #define SRS_CONF_DEFAULT_FF_LOG_DIR "./objs" | 45 | #define SRS_CONF_DEFAULT_FF_LOG_DIR "./objs" |
| 46 | +#define SRS_CONF_DEFAULT_UTC_TIME false | ||
| 46 | 47 | ||
| 47 | #define SRS_CONF_DEFAULT_MAX_CONNECTIONS 1000 | 48 | #define SRS_CONF_DEFAULT_MAX_CONNECTIONS 1000 |
| 48 | #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html" | 49 | #define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html" |
| @@ -435,6 +436,10 @@ public: | @@ -435,6 +436,10 @@ public: | ||
| 435 | * every this interval in ms. | 436 | * every this interval in ms. |
| 436 | */ | 437 | */ |
| 437 | virtual int get_pithy_print_ms(); | 438 | virtual int get_pithy_print_ms(); |
| 439 | + /** | ||
| 440 | + * whether use utc-time to format the time. | ||
| 441 | + */ | ||
| 442 | + virtual bool get_utc_time(); | ||
| 438 | // stream_caster section | 443 | // stream_caster section |
| 439 | public: | 444 | public: |
| 440 | /** | 445 | /** |
| @@ -311,12 +311,6 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | @@ -311,12 +311,6 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | ||
| 311 | // generate the m3u8 dir and path. | 311 | // generate the m3u8 dir and path. |
| 312 | m3u8 = path + "/" + m3u8_file; | 312 | m3u8 = path + "/" + m3u8_file; |
| 313 | m3u8 = srs_path_build_stream(m3u8, req->vhost, req->app, req->stream); | 313 | m3u8 = srs_path_build_stream(m3u8, req->vhost, req->app, req->stream); |
| 314 | - | ||
| 315 | - m3u8_dir = m3u8; | ||
| 316 | - size_t pos = string::npos; | ||
| 317 | - if ((pos = m3u8_dir.rfind("/")) != string::npos) { | ||
| 318 | - m3u8_dir = m3u8_dir.substr(0, pos); | ||
| 319 | - } | ||
| 320 | 314 | ||
| 321 | // we always keep the target duration increasing. | 315 | // we always keep the target duration increasing. |
| 322 | int max_td = srs_max(target_duration, (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost))); | 316 | int max_td = srs_max(target_duration, (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost))); |
| @@ -336,6 +330,14 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | @@ -336,6 +330,14 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | ||
| 336 | should_write_file = true; | 330 | should_write_file = true; |
| 337 | } | 331 | } |
| 338 | 332 | ||
| 333 | + // create m3u8 dir once. | ||
| 334 | + m3u8_dir = srs_path_dirname(m3u8); | ||
| 335 | + if (should_write_file && (ret = srs_create_dir_recursively(m3u8_dir)) != ERROR_SUCCESS) { | ||
| 336 | + srs_error("create app dir %s failed. ret=%d", m3u8_dir.c_str(), ret); | ||
| 337 | + return ret; | ||
| 338 | + } | ||
| 339 | + srs_info("create m3u8 dir %s ok", m3u8_dir.c_str()); | ||
| 340 | + | ||
| 339 | return ret; | 341 | return ret; |
| 340 | } | 342 | } |
| 341 | 343 | ||
| @@ -434,11 +436,12 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) | @@ -434,11 +436,12 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) | ||
| 434 | current->uri += ts_url; | 436 | current->uri += ts_url; |
| 435 | 437 | ||
| 436 | // create dir recursively for hls. | 438 | // create dir recursively for hls. |
| 437 | - if (should_write_file && (ret = srs_create_dir_recursively(m3u8_dir)) != ERROR_SUCCESS) { | ||
| 438 | - srs_error("create app dir %s failed. ret=%d", m3u8_dir.c_str(), ret); | 439 | + std::string ts_dir = srs_path_dirname(current->full_path); |
| 440 | + if (should_write_file && (ret = srs_create_dir_recursively(ts_dir)) != ERROR_SUCCESS) { | ||
| 441 | + srs_error("create app dir %s failed. ret=%d", ts_dir.c_str(), ret); | ||
| 439 | return ret; | 442 | return ret; |
| 440 | } | 443 | } |
| 441 | - srs_info("create app dir %s ok", m3u8_dir.c_str()); | 444 | + srs_info("create ts dir %s ok", ts_dir.c_str()); |
| 442 | 445 | ||
| 443 | // open temp ts file. | 446 | // open temp ts file. |
| 444 | std::string tmp_file = current->full_path + ".tmp"; | 447 | std::string tmp_file = current->full_path + ".tmp"; |
| @@ -274,8 +274,14 @@ bool SrsFastLog::generate_header(bool error, const char* tag, int context_id, co | @@ -274,8 +274,14 @@ bool SrsFastLog::generate_header(bool error, const char* tag, int context_id, co | ||
| 274 | 274 | ||
| 275 | // to calendar time | 275 | // to calendar time |
| 276 | struct tm* tm; | 276 | struct tm* tm; |
| 277 | - if ((tm = localtime(&tv.tv_sec)) == NULL) { | ||
| 278 | - return false; | 277 | + if (_srs_config->get_utc_time()) { |
| 278 | + if ((tm = gmtime(&tv.tv_sec)) == NULL) { | ||
| 279 | + return false; | ||
| 280 | + } | ||
| 281 | + } else { | ||
| 282 | + if ((tm = localtime(&tv.tv_sec)) == NULL) { | ||
| 283 | + return false; | ||
| 284 | + } | ||
| 279 | } | 285 | } |
| 280 | 286 | ||
| 281 | // write log header | 287 | // write log header |
| @@ -140,8 +140,14 @@ string srs_path_build_timestamp(string template_path) | @@ -140,8 +140,14 @@ string srs_path_build_timestamp(string template_path) | ||
| 140 | 140 | ||
| 141 | // to calendar time | 141 | // to calendar time |
| 142 | struct tm* tm; | 142 | struct tm* tm; |
| 143 | - if ((tm = localtime(&tv.tv_sec)) == NULL) { | ||
| 144 | - return path; | 143 | + if (_srs_config->get_utc_time()) { |
| 144 | + if ((tm = gmtime(&tv.tv_sec)) == NULL) { | ||
| 145 | + return path; | ||
| 146 | + } | ||
| 147 | + } else { | ||
| 148 | + if ((tm = localtime(&tv.tv_sec)) == NULL) { | ||
| 149 | + return path; | ||
| 150 | + } | ||
| 145 | } | 151 | } |
| 146 | 152 | ||
| 147 | // the buffer to format the date and time. | 153 | // the buffer to format the date and time. |
| @@ -154,32 +160,32 @@ string srs_path_build_timestamp(string template_path) | @@ -154,32 +160,32 @@ string srs_path_build_timestamp(string template_path) | ||
| 154 | } | 160 | } |
| 155 | // [2006], replace with current year. | 161 | // [2006], replace with current year. |
| 156 | if (true) { | 162 | if (true) { |
| 157 | - snprintf(buf, sizeof(buf), "%d", 1900 + tm->tm_year); | 163 | + snprintf(buf, sizeof(buf), "%04d", 1900 + tm->tm_year); |
| 158 | path = srs_string_replace(path, "[2006]", buf); | 164 | path = srs_string_replace(path, "[2006]", buf); |
| 159 | } | 165 | } |
| 160 | // [01], replace this const to current month. | 166 | // [01], replace this const to current month. |
| 161 | if (true) { | 167 | if (true) { |
| 162 | - snprintf(buf, sizeof(buf), "%d", 1 + tm->tm_mon); | 168 | + snprintf(buf, sizeof(buf), "%02d", 1 + tm->tm_mon); |
| 163 | path = srs_string_replace(path, "[01]", buf); | 169 | path = srs_string_replace(path, "[01]", buf); |
| 164 | } | 170 | } |
| 165 | // [02], replace this const to current date. | 171 | // [02], replace this const to current date. |
| 166 | if (true) { | 172 | if (true) { |
| 167 | - snprintf(buf, sizeof(buf), "%d", tm->tm_mday); | 173 | + snprintf(buf, sizeof(buf), "%02d", tm->tm_mday); |
| 168 | path = srs_string_replace(path, "[02]", buf); | 174 | path = srs_string_replace(path, "[02]", buf); |
| 169 | } | 175 | } |
| 170 | // [15], replace this const to current hour. | 176 | // [15], replace this const to current hour. |
| 171 | if (true) { | 177 | if (true) { |
| 172 | - snprintf(buf, sizeof(buf), "%d", tm->tm_hour); | 178 | + snprintf(buf, sizeof(buf), "%02d", tm->tm_hour); |
| 173 | path = srs_string_replace(path, "[15]", buf); | 179 | path = srs_string_replace(path, "[15]", buf); |
| 174 | } | 180 | } |
| 175 | // [04], repleace this const to current minute. | 181 | // [04], repleace this const to current minute. |
| 176 | if (true) { | 182 | if (true) { |
| 177 | - snprintf(buf, sizeof(buf), "%d", tm->tm_min); | 183 | + snprintf(buf, sizeof(buf), "%02d", tm->tm_min); |
| 178 | path = srs_string_replace(path, "[04]", buf); | 184 | path = srs_string_replace(path, "[04]", buf); |
| 179 | } | 185 | } |
| 180 | // [05], repleace this const to current second. | 186 | // [05], repleace this const to current second. |
| 181 | if (true) { | 187 | if (true) { |
| 182 | - snprintf(buf, sizeof(buf), "%d", tm->tm_sec); | 188 | + snprintf(buf, sizeof(buf), "%02d", tm->tm_sec); |
| 183 | path = srs_string_replace(path, "[05]", buf); | 189 | path = srs_string_replace(path, "[05]", buf); |
| 184 | } | 190 | } |
| 185 | // [999], repleace this const to current millisecond. | 191 | // [999], repleace this const to current millisecond. |
| @@ -294,6 +294,21 @@ bool srs_path_exists(std::string path) | @@ -294,6 +294,21 @@ bool srs_path_exists(std::string path) | ||
| 294 | return false; | 294 | return false; |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | +string srs_path_dirname(string path) | ||
| 298 | +{ | ||
| 299 | + std::string dirname = path; | ||
| 300 | + size_t pos = string::npos; | ||
| 301 | + | ||
| 302 | + if ((pos = dirname.rfind("/")) != string::npos) { | ||
| 303 | + if (pos == 0) { | ||
| 304 | + return "/"; | ||
| 305 | + } | ||
| 306 | + dirname = dirname.substr(0, pos); | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + return dirname; | ||
| 310 | +} | ||
| 311 | + | ||
| 297 | bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code) | 312 | bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code) |
| 298 | { | 313 | { |
| 299 | char* bytes = stream->data() + stream->pos(); | 314 | char* bytes = stream->data() + stream->pos(); |
| @@ -68,6 +68,8 @@ extern int srs_create_dir_recursively(std::string dir); | @@ -68,6 +68,8 @@ extern int srs_create_dir_recursively(std::string dir); | ||
| 68 | 68 | ||
| 69 | // whether path exists. | 69 | // whether path exists. |
| 70 | extern bool srs_path_exists(std::string path); | 70 | extern bool srs_path_exists(std::string path); |
| 71 | +// get the dirname of path | ||
| 72 | +extern std::string srs_path_dirname(std::string path); | ||
| 71 | 73 | ||
| 72 | /** | 74 | /** |
| 73 | * whether stream starts with the avc NALU in "AnnexB" | 75 | * whether stream starts with the avc NALU in "AnnexB" |
-
请 注册 或 登录 后发表评论