save and load sequence_no,load total duration,erase last #EXT-X-ENDLIST in total.m3u8 if srs restart
正在显示
2 个修改的文件
包含
97 行增加
和
9 行删除
| @@ -392,6 +392,9 @@ int SrsHlsMuxer::initialize() | @@ -392,6 +392,9 @@ int SrsHlsMuxer::initialize() | ||
| 392 | return ret; | 392 | return ret; |
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | +#define LINE_EXT_X_ENDLIST "#EXT-X-ENDLIST\n" | ||
| 396 | +#define LENGTH_OF_LINE_EXT_X_ENDLIST (sizeof(LINE_EXT_X_ENDLIST)-1) | ||
| 397 | + | ||
| 395 | int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | 398 | int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, |
| 396 | string path, string m3u8_file, string total_m3u8_file, string total_file, string ts_file, double fragment, double window, | 399 | string path, string m3u8_file, string total_m3u8_file, string total_file, string ts_file, double fragment, double window, |
| 397 | bool ts_floor, double aof_ratio, bool cleanup, bool wait_keyframe | 400 | bool ts_floor, double aof_ratio, bool cleanup, bool wait_keyframe |
| @@ -427,6 +430,74 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | @@ -427,6 +430,74 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | ||
| 427 | total_url = srs_path_build_stream(total_file, req->vhost, req->app, req->stream); | 430 | total_url = srs_path_build_stream(total_file, req->vhost, req->app, req->stream); |
| 428 | total = path + "/" + total_url; | 431 | total = path + "/" + total_url; |
| 429 | 432 | ||
| 433 | + if (save_m3u8_total) { | ||
| 434 | + //read last seq_no if exist | ||
| 435 | + { | ||
| 436 | + next_seq_no_file = total_m3u8 + "_seq_no"; | ||
| 437 | + SrsFileReader fr; | ||
| 438 | + // open seq file | ||
| 439 | + if ((ret = fr.open(next_seq_no_file)) == ERROR_SUCCESS) { | ||
| 440 | + int64_t size = fr.filesize(); | ||
| 441 | + fr.lseek(0); | ||
| 442 | + | ||
| 443 | + char * buf = new char[size + 1]; | ||
| 444 | + if (buf) { | ||
| 445 | + ssize_t readsize = 0; | ||
| 446 | + fr.read(buf, size, &readsize); | ||
| 447 | + if (readsize == size) { | ||
| 448 | + buf[size] = 0; | ||
| 449 | + _sequence_no = atoi(buf); | ||
| 450 | + } | ||
| 451 | + delete[] buf; | ||
| 452 | + } | ||
| 453 | + } | ||
| 454 | + } | ||
| 455 | + //read last total duration if exist | ||
| 456 | + if (!total_url.empty()) { | ||
| 457 | + SrsFileReader fr; | ||
| 458 | + // open seq file | ||
| 459 | + if ((ret = fr.open(total)) == ERROR_SUCCESS) { | ||
| 460 | + int64_t size = fr.filesize(); | ||
| 461 | + fr.lseek(0); | ||
| 462 | + | ||
| 463 | + char * buf = new char[size + 1]; | ||
| 464 | + if (buf) { | ||
| 465 | + ssize_t readsize = 0; | ||
| 466 | + fr.read(buf, size, &readsize); | ||
| 467 | + if (readsize == size) { | ||
| 468 | + buf[size] = 0; | ||
| 469 | + total_duraion = atof(buf); | ||
| 470 | + } | ||
| 471 | + delete[] buf; | ||
| 472 | + } | ||
| 473 | + } | ||
| 474 | + } | ||
| 475 | + //judge if last total.m3u8 end with #EXT-X-ENDLIST | ||
| 476 | + { | ||
| 477 | + SrsFileReader fr; | ||
| 478 | + | ||
| 479 | + if ((ret = fr.open(total_m3u8)) == ERROR_SUCCESS) { | ||
| 480 | + int64_t size = fr.filesize(); | ||
| 481 | + if (size > (int64_t)LENGTH_OF_LINE_EXT_X_ENDLIST) { | ||
| 482 | + fr.lseek(size - LENGTH_OF_LINE_EXT_X_ENDLIST); | ||
| 483 | + | ||
| 484 | + char * buf = new char[LENGTH_OF_LINE_EXT_X_ENDLIST + 1]; | ||
| 485 | + if (buf) { | ||
| 486 | + ssize_t readsize = 0; | ||
| 487 | + fr.read(buf, LENGTH_OF_LINE_EXT_X_ENDLIST, &readsize); | ||
| 488 | + if (readsize == LENGTH_OF_LINE_EXT_X_ENDLIST) { | ||
| 489 | + buf[LENGTH_OF_LINE_EXT_X_ENDLIST] = 0; | ||
| 490 | + if (!strcmp(buf, LINE_EXT_X_ENDLIST)) { | ||
| 491 | + m3u8_total_endlist_saved = true; | ||
| 492 | + } | ||
| 493 | + } | ||
| 494 | + delete[] buf; | ||
| 495 | + } | ||
| 496 | + } | ||
| 497 | + } | ||
| 498 | + } | ||
| 499 | + } | ||
| 500 | + | ||
| 430 | // when update config, reset the history target duration. | 501 | // when update config, reset the history target duration. |
| 431 | max_td = (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost)); | 502 | max_td = (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost)); |
| 432 | 503 | ||
| @@ -836,14 +907,14 @@ int SrsHlsMuxer::segment_close(string log_desc) | @@ -836,14 +907,14 @@ int SrsHlsMuxer::segment_close(string log_desc) | ||
| 836 | 907 | ||
| 837 | srs_trace("---log_desc:%s",log_desc.c_str()); | 908 | srs_trace("---log_desc:%s",log_desc.c_str()); |
| 838 | if(log_desc == "unpublish"){ | 909 | if(log_desc == "unpublish"){ |
| 839 | - ss << "#EXT-X-ENDLIST" << SRS_CONSTS_LF; | 910 | + ss << LINE_EXT_X_ENDLIST; |
| 840 | m3u8_total_endlist_saved = true; | 911 | m3u8_total_endlist_saved = true; |
| 841 | } | 912 | } |
| 842 | 913 | ||
| 843 | if(erase_last_endlist){ | 914 | if(erase_last_endlist){ |
| 844 | int64_t cur_pos = total_m3u8_writer.tellg(); | 915 | int64_t cur_pos = total_m3u8_writer.tellg(); |
| 845 | 916 | ||
| 846 | - cur_pos -= sizeof("#EXT-X-ENDLIST");// sizeof("#EXT-X-ENDLIST") = strlen("#EXT-X-ENDLIST") + 1 = strlen("#EXT-X-ENDLIST") + strlen("\n") | 917 | + cur_pos -= LENGTH_OF_LINE_EXT_X_ENDLIST; |
| 847 | 918 | ||
| 848 | total_m3u8_writer.lseek(cur_pos); | 919 | total_m3u8_writer.lseek(cur_pos); |
| 849 | } | 920 | } |
| @@ -900,15 +971,14 @@ int SrsHlsMuxer::segment_close(string log_desc) | @@ -900,15 +971,14 @@ int SrsHlsMuxer::segment_close(string log_desc) | ||
| 900 | current->duration, current->segment_start_dts); | 971 | current->duration, current->segment_start_dts); |
| 901 | return ret; | 972 | return ret; |
| 902 | } | 973 | } |
| 903 | - std::stringstream ss; | ||
| 904 | - ss << "#EXT-X-ENDLIST" << SRS_CONSTS_LF; | ||
| 905 | - m3u8_total_endlist_saved = true; | ||
| 906 | - std::string m3u8 = ss.str(); | ||
| 907 | - if ((ret = total_m3u8_writer.write((char*) m3u8.c_str(), | ||
| 908 | - (int) m3u8.length(), NULL)) != ERROR_SUCCESS) { | 974 | + |
| 975 | + if ((ret = total_m3u8_writer.write( (void *)LINE_EXT_X_ENDLIST, | ||
| 976 | + LENGTH_OF_LINE_EXT_X_ENDLIST , NULL)) != ERROR_SUCCESS) { | ||
| 909 | srs_error("write m3u8 failed. ret=%d", ret); | 977 | srs_error("write m3u8 failed. ret=%d", ret); |
| 910 | return ret; | 978 | return ret; |
| 911 | } | 979 | } |
| 980 | + | ||
| 981 | + m3u8_total_endlist_saved = true; | ||
| 912 | } | 982 | } |
| 913 | 983 | ||
| 914 | srs_trace("%s drop ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64"", | 984 | srs_trace("%s drop ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64"", |
| @@ -926,6 +996,22 @@ int SrsHlsMuxer::segment_close(string log_desc) | @@ -926,6 +996,22 @@ int SrsHlsMuxer::segment_close(string log_desc) | ||
| 926 | srs_freep(current); | 996 | srs_freep(current); |
| 927 | } | 997 | } |
| 928 | 998 | ||
| 999 | + if(save_m3u8_total){ | ||
| 1000 | + SrsFileWriter seq_no_writer; | ||
| 1001 | + std::stringstream ss_seq_no; | ||
| 1002 | + | ||
| 1003 | + ret = seq_no_writer.open(next_seq_no_file); | ||
| 1004 | + if (ret == ERROR_SUCCESS) { | ||
| 1005 | + ss_seq_no << _sequence_no; | ||
| 1006 | + | ||
| 1007 | + if ((ret = seq_no_writer.write((char*) ss_seq_no.str().c_str(), | ||
| 1008 | + (int) ss_seq_no.str().length(), NULL)) != ERROR_SUCCESS) { | ||
| 1009 | + srs_error("write next_seq_no_file:%s failed. ret=%d", | ||
| 1010 | + (char* ) next_seq_no_file.c_str(), ret); | ||
| 1011 | + } | ||
| 1012 | + } | ||
| 1013 | + } | ||
| 1014 | + | ||
| 929 | // the segments to remove | 1015 | // the segments to remove |
| 930 | std::vector<SrsHlsSegment*> segment_to_remove; | 1016 | std::vector<SrsHlsSegment*> segment_to_remove; |
| 931 | 1017 | ||
| @@ -1125,7 +1211,7 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment | @@ -1125,7 +1211,7 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment | ||
| 1125 | 1211 | ||
| 1126 | // TODO: FIXME: support load exists m3u8, to continue publish stream. | 1212 | // TODO: FIXME: support load exists m3u8, to continue publish stream. |
| 1127 | // for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase. | 1213 | // for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase. |
| 1128 | - | 1214 | + |
| 1129 | // open muxer | 1215 | // open muxer |
| 1130 | if ((ret = muxer->update_config(req, entry_prefix, | 1216 | if ((ret = muxer->update_config(req, entry_prefix, |
| 1131 | path, m3u8_file, total_m3u8_file, total_file, ts_file, hls_fragment, hls_window, ts_floor, hls_aof_ratio, | 1217 | path, m3u8_file, total_m3u8_file, total_file, ts_file, hls_fragment, hls_window, ts_floor, hls_aof_ratio, |
| @@ -213,6 +213,8 @@ private: | @@ -213,6 +213,8 @@ private: | ||
| 213 | bool m3u8_total_endlist_saved; | 213 | bool m3u8_total_endlist_saved; |
| 214 | //total duration for all segments | 214 | //total duration for all segments |
| 215 | double total_duraion; | 215 | double total_duraion; |
| 216 | + //the file to save last saved seq no | ||
| 217 | + std::string next_seq_no_file; | ||
| 216 | private: | 218 | private: |
| 217 | // TODO: FIXME: remove it. | 219 | // TODO: FIXME: remove it. |
| 218 | bool should_write_cache; | 220 | bool should_write_cache; |
-
请 注册 或 登录 后发表评论