正在显示
10 个修改的文件
包含
79 行增加
和
17 行删除
| @@ -530,7 +530,8 @@ Supported operating systems and hardware: | @@ -530,7 +530,8 @@ Supported operating systems and hardware: | ||
| 530 | 530 | ||
| 531 | ### SRS 2.0 history | 531 | ### SRS 2.0 history |
| 532 | 532 | ||
| 533 | -* v2.0, 2015-02-19, refine pithy print to more easyer to use 2.0.121. | 533 | +* v2.0, 2015-02-19, refine dvr, append file when dvr file exists. 2.0.122. |
| 534 | +* v2.0, 2015-02-19, refine pithy print to more easyer to use. 2.0.121. | ||
| 534 | * v2.0, 2015-02-18, fix [#133](https://github.com/winlinvip/simple-rtmp-server/issues/133), support push rtsp to srs. 2.0.120. | 535 | * v2.0, 2015-02-18, fix [#133](https://github.com/winlinvip/simple-rtmp-server/issues/133), support push rtsp to srs. 2.0.120. |
| 535 | * v2.0, 2015-02-17, the join maybe failed, should use a variable to ensure thread terminated. 2.0.119. | 536 | * v2.0, 2015-02-17, the join maybe failed, should use a variable to ensure thread terminated. 2.0.119. |
| 536 | * v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), support config default acodec/vcodec. 2.0.118. | 537 | * v2.0, 2015-02-15, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), support config default acodec/vcodec. 2.0.118. |
| @@ -1227,4 +1227,5 @@ vhost removed.srs.com { | @@ -1227,4 +1227,5 @@ vhost removed.srs.com { | ||
| 1227 | # config for the pithy print, | 1227 | # config for the pithy print, |
| 1228 | # which always print constant message specified by interval, | 1228 | # which always print constant message specified by interval, |
| 1229 | # whatever the clients in concurrency. | 1229 | # whatever the clients in concurrency. |
| 1230 | +# default: 10000 | ||
| 1230 | pithy_print_ms 10000; | 1231 | pithy_print_ms 10000; |
| @@ -368,11 +368,27 @@ int SrsDvrPlan::flv_open(string stream, string path) | @@ -368,11 +368,27 @@ int SrsDvrPlan::flv_open(string stream, string path) | ||
| 368 | int ret = ERROR_SUCCESS; | 368 | int ret = ERROR_SUCCESS; |
| 369 | 369 | ||
| 370 | segment->reset(); | 370 | segment->reset(); |
| 371 | + | ||
| 372 | + if (srs_path_exists(path)) { | ||
| 373 | + // when path exists, always append to it. | ||
| 374 | + // so we must use the target flv path as output flv. | ||
| 375 | + tmp_flv_file = path; | ||
| 376 | + } else { | ||
| 377 | + // when path not exists, dvr to tmp file. | ||
| 378 | + tmp_flv_file = path + ".tmp"; | ||
| 379 | + } | ||
| 371 | 380 | ||
| 372 | - std::string tmp_file = path + ".tmp"; | ||
| 373 | - if ((ret = fs->open(tmp_file)) != ERROR_SUCCESS) { | ||
| 374 | - srs_error("open file stream for file %s failed. ret=%d", path.c_str(), ret); | ||
| 375 | - return ret; | 381 | + if (srs_path_exists(path)) { |
| 382 | + if ((ret = fs->open_append(tmp_flv_file)) != ERROR_SUCCESS) { | ||
| 383 | + srs_error("append file stream for file %s failed. ret=%d", path.c_str(), ret); | ||
| 384 | + return ret; | ||
| 385 | + } | ||
| 386 | + srs_warn("dvr: always append to when exists, file=%s.", path.c_str()); | ||
| 387 | + } else { | ||
| 388 | + if ((ret = fs->open(tmp_flv_file)) != ERROR_SUCCESS) { | ||
| 389 | + srs_error("open file stream for file %s failed. ret=%d", path.c_str(), ret); | ||
| 390 | + return ret; | ||
| 391 | + } | ||
| 376 | } | 392 | } |
| 377 | 393 | ||
| 378 | if ((ret = enc->initialize(fs)) != ERROR_SUCCESS) { | 394 | if ((ret = enc->initialize(fs)) != ERROR_SUCCESS) { |
| @@ -396,12 +412,14 @@ int SrsDvrPlan::flv_close() | @@ -396,12 +412,14 @@ int SrsDvrPlan::flv_close() | ||
| 396 | 412 | ||
| 397 | fs->close(); | 413 | fs->close(); |
| 398 | 414 | ||
| 399 | - std::string tmp_file = segment->path + ".tmp"; | ||
| 400 | - if (rename(tmp_file.c_str(), segment->path.c_str()) < 0) { | ||
| 401 | - ret = ERROR_SYSTEM_FILE_RENAME; | ||
| 402 | - srs_error("rename flv file failed, %s => %s. ret=%d", | ||
| 403 | - tmp_file.c_str(), segment->path.c_str(), ret); | ||
| 404 | - return ret; | 415 | + // when tmp flv file exists, reap it. |
| 416 | + if (tmp_flv_file != segment->path) { | ||
| 417 | + if (rename(tmp_flv_file.c_str(), segment->path.c_str()) < 0) { | ||
| 418 | + ret = ERROR_SYSTEM_FILE_RENAME; | ||
| 419 | + srs_error("rename flv file failed, %s => %s. ret=%d", | ||
| 420 | + tmp_flv_file.c_str(), segment->path.c_str(), ret); | ||
| 421 | + return ret; | ||
| 422 | + } | ||
| 405 | } | 423 | } |
| 406 | 424 | ||
| 407 | #ifdef SRS_AUTO_HTTP_CALLBACK | 425 | #ifdef SRS_AUTO_HTTP_CALLBACK |
| @@ -111,6 +111,8 @@ protected: | @@ -111,6 +111,8 @@ protected: | ||
| 111 | SrsRequest* _req; | 111 | SrsRequest* _req; |
| 112 | bool dvr_enabled; | 112 | bool dvr_enabled; |
| 113 | SrsFileWriter* fs; | 113 | SrsFileWriter* fs; |
| 114 | +private: | ||
| 115 | + std::string tmp_flv_file; | ||
| 114 | public: | 116 | public: |
| 115 | SrsDvrPlan(); | 117 | SrsDvrPlan(); |
| 116 | virtual ~SrsDvrPlan(); | 118 | virtual ~SrsDvrPlan(); |
| @@ -294,8 +294,7 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* | @@ -294,8 +294,7 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* | ||
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | // stat current dir, if exists, return error. | 296 | // stat current dir, if exists, return error. |
| 297 | - struct stat st; | ||
| 298 | - if (stat(fullpath.c_str(), &st) != 0) { | 297 | + if (!srs_path_exists(fullpath)) { |
| 299 | srs_warn("http miss file=%s, pattern=%s, upath=%s", | 298 | srs_warn("http miss file=%s, pattern=%s, upath=%s", |
| 300 | fullpath.c_str(), entry->pattern.c_str(), upath.c_str()); | 299 | fullpath.c_str(), entry->pattern.c_str(), upath.c_str()); |
| 301 | return SrsGoHttpNotFoundHandler().serve_http(w, r); | 300 | return SrsGoHttpNotFoundHandler().serve_http(w, r); |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | // current release version | 31 | // current release version |
| 32 | #define VERSION_MAJOR 2 | 32 | #define VERSION_MAJOR 2 |
| 33 | #define VERSION_MINOR 0 | 33 | #define VERSION_MINOR 0 |
| 34 | -#define VERSION_REVISION 121 | 34 | +#define VERSION_REVISION 122 |
| 35 | 35 | ||
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
| @@ -69,6 +69,30 @@ int SrsFileWriter::open(string file) | @@ -69,6 +69,30 @@ int SrsFileWriter::open(string file) | ||
| 69 | return ret; | 69 | return ret; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | +int SrsFileWriter::open_append(string file) | ||
| 73 | +{ | ||
| 74 | + int ret = ERROR_SUCCESS; | ||
| 75 | + | ||
| 76 | + if (fd > 0) { | ||
| 77 | + ret = ERROR_SYSTEM_FILE_ALREADY_OPENED; | ||
| 78 | + srs_error("file %s already opened. ret=%d", _file.c_str(), ret); | ||
| 79 | + return ret; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + int flags = O_APPEND|O_WRONLY; | ||
| 83 | + mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH; | ||
| 84 | + | ||
| 85 | + if ((fd = ::open(file.c_str(), flags, mode)) < 0) { | ||
| 86 | + ret = ERROR_SYSTEM_FILE_OPENE; | ||
| 87 | + srs_error("open file %s failed. ret=%d", file.c_str(), ret); | ||
| 88 | + return ret; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + _file = file; | ||
| 92 | + | ||
| 93 | + return ret; | ||
| 94 | +} | ||
| 95 | + | ||
| 72 | void SrsFileWriter::close() | 96 | void SrsFileWriter::close() |
| 73 | { | 97 | { |
| 74 | int ret = ERROR_SUCCESS; | 98 | int ret = ERROR_SUCCESS; |
| @@ -47,6 +47,10 @@ public: | @@ -47,6 +47,10 @@ public: | ||
| 47 | * open file writer, can open then close then open... | 47 | * open file writer, can open then close then open... |
| 48 | */ | 48 | */ |
| 49 | virtual int open(std::string file); | 49 | virtual int open(std::string file); |
| 50 | + /** | ||
| 51 | + * open file writer in append mode. | ||
| 52 | + */ | ||
| 53 | + virtual int open_append(std::string file); | ||
| 50 | virtual void close(); | 54 | virtual void close(); |
| 51 | public: | 55 | public: |
| 52 | virtual bool is_open(); | 56 | virtual bool is_open(); |
| @@ -230,10 +230,8 @@ int __srs_create_dir_recursively(string dir) | @@ -230,10 +230,8 @@ int __srs_create_dir_recursively(string dir) | ||
| 230 | { | 230 | { |
| 231 | int ret = ERROR_SUCCESS; | 231 | int ret = ERROR_SUCCESS; |
| 232 | 232 | ||
| 233 | - struct stat st; | ||
| 234 | - | ||
| 235 | // stat current dir, if exists, return error. | 233 | // stat current dir, if exists, return error. |
| 236 | - if (stat(dir.c_str(), &st) == 0) { | 234 | + if (srs_path_exists(dir)) { |
| 237 | return ERROR_SYSTEM_DIR_EXISTS; | 235 | return ERROR_SYSTEM_DIR_EXISTS; |
| 238 | } | 236 | } |
| 239 | 237 | ||
| @@ -279,6 +277,18 @@ int srs_create_dir_recursively(string dir) | @@ -279,6 +277,18 @@ int srs_create_dir_recursively(string dir) | ||
| 279 | return ret; | 277 | return ret; |
| 280 | } | 278 | } |
| 281 | 279 | ||
| 280 | +bool srs_path_exists(std::string path) | ||
| 281 | +{ | ||
| 282 | + struct stat st; | ||
| 283 | + | ||
| 284 | + // stat current dir, if exists, return error. | ||
| 285 | + if (stat(path.c_str(), &st) == 0) { | ||
| 286 | + return true; | ||
| 287 | + } | ||
| 288 | + | ||
| 289 | + return false; | ||
| 290 | +} | ||
| 291 | + | ||
| 282 | bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code) | 292 | bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code) |
| 283 | { | 293 | { |
| 284 | char* bytes = stream->data() + stream->pos(); | 294 | char* bytes = stream->data() + stream->pos(); |
| @@ -64,6 +64,9 @@ extern bool srs_string_ends_with(std::string str, std::string flag); | @@ -64,6 +64,9 @@ extern bool srs_string_ends_with(std::string str, std::string flag); | ||
| 64 | // create dir recursively | 64 | // create dir recursively |
| 65 | extern int srs_create_dir_recursively(std::string dir); | 65 | extern int srs_create_dir_recursively(std::string dir); |
| 66 | 66 | ||
| 67 | +// whether path exists. | ||
| 68 | +extern bool srs_path_exists(std::string path); | ||
| 69 | + | ||
| 67 | /** | 70 | /** |
| 68 | * whether stream starts with the avc NALU in "AnnexB" | 71 | * whether stream starts with the avc NALU in "AnnexB" |
| 69 | * from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. | 72 | * from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. |
-
请 注册 或 登录 后发表评论