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; |
-
请 注册 或 登录 后发表评论