正在显示
7 个修改的文件
包含
74 行增加
和
20 行删除
@@ -13,6 +13,8 @@ vhost __defaultVhost__ { | @@ -13,6 +13,8 @@ vhost __defaultVhost__ { | ||
13 | gop_cache on; | 13 | gop_cache on; |
14 | hls on; | 14 | hls on; |
15 | hls_path ./objs/nginx/html; | 15 | hls_path ./objs/nginx/html; |
16 | + hls_fragment 10; | ||
17 | + hls_window 60; | ||
16 | } | 18 | } |
17 | # the vhost disabled. | 19 | # the vhost disabled. |
18 | vhost removed.vhost.com { | 20 | vhost removed.vhost.com { |
@@ -39,6 +41,12 @@ vhost no-hls.vhost.com { | @@ -39,6 +41,12 @@ vhost no-hls.vhost.com { | ||
39 | # in a word, the hls_path is for vhost. | 41 | # in a word, the hls_path is for vhost. |
40 | # default: ./objs/nginx/html | 42 | # default: ./objs/nginx/html |
41 | hls_path /data/nginx/html; | 43 | hls_path /data/nginx/html; |
44 | + # the hls fragment in seconds, the duration of a piece of ts. | ||
45 | + # default: 10 | ||
46 | + hls_fragment 10; | ||
47 | + # the hls window in seconds, the number of ts in m3u8. | ||
48 | + # default: 60 | ||
49 | + hls_window 60; | ||
42 | } | 50 | } |
43 | # the vhost with hls disabled. | 51 | # the vhost with hls disabled. |
44 | vhost no-hls.vhost.com { | 52 | vhost no-hls.vhost.com { |
@@ -332,7 +332,7 @@ int SrsClient::publish(SrsSource* source, bool is_fmle) | @@ -332,7 +332,7 @@ int SrsClient::publish(SrsSource* source, bool is_fmle) | ||
332 | SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER); | 332 | SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER); |
333 | 333 | ||
334 | // notify the hls to prepare when publish start. | 334 | // notify the hls to prepare when publish start. |
335 | - if ((ret = source->on_publish(req->vhost, req->stream)) != ERROR_SUCCESS) { | 335 | + if ((ret = source->on_publish(req->vhost, req->app, req->stream)) != ERROR_SUCCESS) { |
336 | srs_error("hls on_publish failed. ret=%d", ret); | 336 | srs_error("hls on_publish failed. ret=%d", ret); |
337 | return ret; | 337 | return ret; |
338 | } | 338 | } |
@@ -109,7 +109,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -109,7 +109,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
109 | 109 | ||
110 | #define ERROR_HLS_METADATA 600 | 110 | #define ERROR_HLS_METADATA 600 |
111 | #define ERROR_HLS_DECODE_ERROR 601 | 111 | #define ERROR_HLS_DECODE_ERROR 601 |
112 | -//#define ERROR_HLS_BUSY 602 | 112 | +#define ERROR_HLS_CREATE_DIR 602 |
113 | #define ERROR_HLS_OPEN_FAILED 603 | 113 | #define ERROR_HLS_OPEN_FAILED 603 |
114 | #define ERROR_HLS_WRITE_FAILED 604 | 114 | #define ERROR_HLS_WRITE_FAILED 604 |
115 | #define ERROR_HLS_AAC_FRAME_LENGTH 605 | 115 | #define ERROR_HLS_AAC_FRAME_LENGTH 605 |
@@ -403,12 +403,13 @@ SrsHLS::~SrsHLS() | @@ -403,12 +403,13 @@ SrsHLS::~SrsHLS() | ||
403 | srs_freep(video_frame); | 403 | srs_freep(video_frame); |
404 | } | 404 | } |
405 | 405 | ||
406 | -int SrsHLS::on_publish(std::string _vhost, std::string _stream) | 406 | +int SrsHLS::on_publish(std::string _vhost, std::string _app, std::string _stream) |
407 | { | 407 | { |
408 | int ret = ERROR_SUCCESS; | 408 | int ret = ERROR_SUCCESS; |
409 | 409 | ||
410 | vhost = _vhost; | 410 | vhost = _vhost; |
411 | stream = _stream; | 411 | stream = _stream; |
412 | + app = _app; | ||
412 | 413 | ||
413 | if ((ret = reopen()) != ERROR_SUCCESS) { | 414 | if ((ret = reopen()) != ERROR_SUCCESS) { |
414 | return ret; | 415 | return ret; |
@@ -555,6 +556,7 @@ int SrsHLS::on_video(SrsSharedPtrMessage* video) | @@ -555,6 +556,7 @@ int SrsHLS::on_video(SrsSharedPtrMessage* video) | ||
555 | if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { | 556 | if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { |
556 | int64_t diff = stream_dts - m3u8_dts; | 557 | int64_t diff = stream_dts - m3u8_dts; |
557 | // 10s. | 558 | // 10s. |
559 | + // TODO: config it. | ||
558 | if (diff / 90000 >= 10) { | 560 | if (diff / 90000 >= 10) { |
559 | if ((ret = reopen()) != ERROR_SUCCESS) { | 561 | if ((ret = reopen()) != ERROR_SUCCESS) { |
560 | return ret; | 562 | return ret; |
@@ -590,6 +592,11 @@ int SrsHLS::reopen() | @@ -590,6 +592,11 @@ int SrsHLS::reopen() | ||
590 | hls_path = conf->arg0(); | 592 | hls_path = conf->arg0(); |
591 | } | 593 | } |
592 | 594 | ||
595 | + // create dir for app. | ||
596 | + if ((ret = create_dir()) != ERROR_SUCCESS) { | ||
597 | + return ret; | ||
598 | + } | ||
599 | + | ||
593 | // start new segment. | 600 | // start new segment. |
594 | if (current) { | 601 | if (current) { |
595 | current->duration = (stream_dts - current->segment_start_dts) / 90000.0; | 602 | current->duration = (stream_dts - current->segment_start_dts) / 90000.0; |
@@ -610,6 +617,8 @@ int SrsHLS::reopen() | @@ -610,6 +617,8 @@ int SrsHLS::reopen() | ||
610 | 617 | ||
611 | current->full_path = hls_path; | 618 | current->full_path = hls_path; |
612 | current->full_path += "/"; | 619 | current->full_path += "/"; |
620 | + current->full_path += app; | ||
621 | + current->full_path += "/"; | ||
613 | current->full_path += filename; | 622 | current->full_path += filename; |
614 | 623 | ||
615 | // TODO: support base url, and so on. | 624 | // TODO: support base url, and so on. |
@@ -619,7 +628,7 @@ int SrsHLS::reopen() | @@ -619,7 +628,7 @@ int SrsHLS::reopen() | ||
619 | srs_error("open hls muxer failed. ret=%d", ret); | 628 | srs_error("open hls muxer failed. ret=%d", ret); |
620 | return ret; | 629 | return ret; |
621 | } | 630 | } |
622 | - srs_trace("open HLS muxer success. vhost=%s, path=%s", vhost.c_str(), current->full_path.c_str()); | 631 | + srs_info("open HLS muxer success. vhost=%s, path=%s", vhost.c_str(), current->full_path.c_str()); |
623 | 632 | ||
624 | return ret; | 633 | return ret; |
625 | } | 634 | } |
@@ -628,16 +637,33 @@ int SrsHLS::refresh_m3u8() | @@ -628,16 +637,33 @@ int SrsHLS::refresh_m3u8() | ||
628 | { | 637 | { |
629 | int ret = ERROR_SUCCESS; | 638 | int ret = ERROR_SUCCESS; |
630 | 639 | ||
640 | + std::string m3u8_file = hls_path; | ||
641 | + m3u8_file += "/"; | ||
642 | + m3u8_file += app; | ||
643 | + m3u8_file += "/"; | ||
644 | + m3u8_file += stream; | ||
645 | + m3u8_file += ".m3u8"; | ||
646 | + | ||
647 | + m3u8 = m3u8_file; | ||
648 | + m3u8_file += ".temp"; | ||
649 | + | ||
631 | int fd = -1; | 650 | int fd = -1; |
632 | - ret = _refresh_m3u8(fd); | 651 | + ret = _refresh_m3u8(fd, m3u8_file); |
633 | if (fd >= 0) { | 652 | if (fd >= 0) { |
634 | close(fd); | 653 | close(fd); |
654 | + if (rename(m3u8_file.c_str(), m3u8.c_str()) < 0) { | ||
655 | + ret = ERROR_HLS_WRITE_FAILED; | ||
656 | + srs_error("rename m3u8 file failed. ret=%d", ret); | ||
657 | + } | ||
635 | } | 658 | } |
636 | 659 | ||
660 | + // remove the temp file. | ||
661 | + unlink(m3u8_file.c_str()); | ||
662 | + | ||
637 | return ret; | 663 | return ret; |
638 | } | 664 | } |
639 | 665 | ||
640 | -int SrsHLS::_refresh_m3u8(int& fd) | 666 | +int SrsHLS::_refresh_m3u8(int& fd, std::string m3u8_file) |
641 | { | 667 | { |
642 | int ret = ERROR_SUCCESS; | 668 | int ret = ERROR_SUCCESS; |
643 | 669 | ||
@@ -646,19 +672,14 @@ int SrsHLS::_refresh_m3u8(int& fd) | @@ -646,19 +672,14 @@ int SrsHLS::_refresh_m3u8(int& fd) | ||
646 | return ret; | 672 | return ret; |
647 | } | 673 | } |
648 | 674 | ||
649 | - m3u8 = hls_path; | ||
650 | - m3u8 += "/"; | ||
651 | - m3u8 += stream; | ||
652 | - m3u8 += ".m3u8"; | ||
653 | - | ||
654 | int flags = O_CREAT|O_WRONLY|O_TRUNC; | 675 | int flags = O_CREAT|O_WRONLY|O_TRUNC; |
655 | mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH; | 676 | mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH; |
656 | - if ((fd = ::open(m3u8.c_str(), flags, mode)) < 0) { | 677 | + if ((fd = ::open(m3u8_file.c_str(), flags, mode)) < 0) { |
657 | ret = ERROR_HLS_OPEN_FAILED; | 678 | ret = ERROR_HLS_OPEN_FAILED; |
658 | - srs_error("open m3u8 file %s failed. ret=%d", m3u8.c_str(), ret); | 679 | + srs_error("open m3u8 file %s failed. ret=%d", m3u8_file.c_str(), ret); |
659 | return ret; | 680 | return ret; |
660 | } | 681 | } |
661 | - srs_info("open m3u8 file %s success.", m3u8.c_str()); | 682 | + srs_info("open m3u8 file %s success.", m3u8_file.c_str()); |
662 | 683 | ||
663 | // #EXTM3U\n#EXT-X-VERSION:3\n | 684 | // #EXTM3U\n#EXT-X-VERSION:3\n |
664 | char header[] = { | 685 | char header[] = { |
@@ -728,8 +749,31 @@ int SrsHLS::_refresh_m3u8(int& fd) | @@ -728,8 +749,31 @@ int SrsHLS::_refresh_m3u8(int& fd) | ||
728 | } | 749 | } |
729 | srs_verbose("write m3u8 segment uri success."); | 750 | srs_verbose("write m3u8 segment uri success."); |
730 | } | 751 | } |
731 | - srs_info("write m3u8 %s success.", m3u8.c_str()); | 752 | + srs_info("write m3u8 %s success.", m3u8_file.c_str()); |
753 | + | ||
754 | + return ret; | ||
755 | +} | ||
756 | + | ||
757 | +int SrsHLS::create_dir() | ||
758 | +{ | ||
759 | + int ret = ERROR_SUCCESS; | ||
760 | + | ||
761 | + std::string app_dir = hls_path; | ||
762 | + app_dir += "/"; | ||
763 | + app_dir += app; | ||
732 | 764 | ||
765 | + // TODO: cleanup the dir when startup. | ||
766 | + | ||
767 | + mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH; | ||
768 | + if (::mkdir(app_dir.c_str(), mode) < 0) { | ||
769 | + if (errno != EEXIST) { | ||
770 | + ret = ERROR_HLS_CREATE_DIR; | ||
771 | + srs_error("create app dir %s failed. ret=%d", app_dir.c_str(), ret); | ||
772 | + return ret; | ||
773 | + } | ||
774 | + } | ||
775 | + srs_info("create app dir %s success.", app_dir.c_str()); | ||
776 | + | ||
733 | return ret; | 777 | return ret; |
734 | } | 778 | } |
735 | 779 |
@@ -72,6 +72,7 @@ class SrsHLS | @@ -72,6 +72,7 @@ class SrsHLS | ||
72 | private: | 72 | private: |
73 | std::string vhost; | 73 | std::string vhost; |
74 | std::string stream; | 74 | std::string stream; |
75 | + std::string app; | ||
75 | std::string hls_path; | 76 | std::string hls_path; |
76 | private: | 77 | private: |
77 | int file_index; | 78 | int file_index; |
@@ -103,7 +104,7 @@ public: | @@ -103,7 +104,7 @@ public: | ||
103 | SrsHLS(); | 104 | SrsHLS(); |
104 | virtual ~SrsHLS(); | 105 | virtual ~SrsHLS(); |
105 | public: | 106 | public: |
106 | - virtual int on_publish(std::string _vhost, std::string _stream); | 107 | + virtual int on_publish(std::string _vhost, std::string _app, std::string _stream); |
107 | virtual void on_unpublish(); | 108 | virtual void on_unpublish(); |
108 | virtual int on_meta_data(SrsOnMetaDataPacket* metadata); | 109 | virtual int on_meta_data(SrsOnMetaDataPacket* metadata); |
109 | virtual int on_audio(SrsSharedPtrMessage* audio); | 110 | virtual int on_audio(SrsSharedPtrMessage* audio); |
@@ -111,7 +112,8 @@ public: | @@ -111,7 +112,8 @@ public: | ||
111 | private: | 112 | private: |
112 | virtual int reopen(); | 113 | virtual int reopen(); |
113 | virtual int refresh_m3u8(); | 114 | virtual int refresh_m3u8(); |
114 | - virtual int _refresh_m3u8(int& fd); | 115 | + virtual int _refresh_m3u8(int& fd, std::string m3u8_file); |
116 | + virtual int create_dir(); | ||
115 | }; | 117 | }; |
116 | 118 | ||
117 | class SrsTSMuxer | 119 | class SrsTSMuxer |
@@ -452,9 +452,9 @@ int SrsSource::on_video(SrsCommonMessage* video) | @@ -452,9 +452,9 @@ int SrsSource::on_video(SrsCommonMessage* video) | ||
452 | return ret; | 452 | return ret; |
453 | } | 453 | } |
454 | 454 | ||
455 | -int SrsSource::on_publish(std::string vhost, std::string stream) | 455 | +int SrsSource::on_publish(std::string vhost, std::string app, std::string stream) |
456 | { | 456 | { |
457 | - return hls->on_publish(vhost, stream); | 457 | + return hls->on_publish(vhost, app, stream); |
458 | } | 458 | } |
459 | 459 | ||
460 | void SrsSource::on_unpublish() | 460 | void SrsSource::on_unpublish() |
@@ -166,7 +166,7 @@ public: | @@ -166,7 +166,7 @@ public: | ||
166 | virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); | 166 | virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); |
167 | virtual int on_audio(SrsCommonMessage* audio); | 167 | virtual int on_audio(SrsCommonMessage* audio); |
168 | virtual int on_video(SrsCommonMessage* video); | 168 | virtual int on_video(SrsCommonMessage* video); |
169 | - virtual int on_publish(std::string vhost, std::string stream); | 169 | + virtual int on_publish(std::string vhost, std::string app, std::string stream); |
170 | virtual void on_unpublish(); | 170 | virtual void on_unpublish(); |
171 | public: | 171 | public: |
172 | virtual int create_consumer(SrsConsumer*& consumer); | 172 | virtual int create_consumer(SrsConsumer*& consumer); |
-
请 注册 或 登录 后发表评论