正在显示
7 个修改的文件
包含
102 行增加
和
20 行删除
@@ -344,6 +344,7 @@ Remark: | @@ -344,6 +344,7 @@ Remark: | ||
344 | 344 | ||
345 | ### SRS 2.0 history | 345 | ### SRS 2.0 history |
346 | 346 | ||
347 | +* v2.0, 2015-05-30, fix [#420](https://github.com/simple-rtmp-server/srs/issues/420) remove ts for hls ram mode. | ||
347 | * v2.0, 2015-05-30, fix [#209](https://github.com/simple-rtmp-server/srs/issues/209) cleanup hls when stop and timeout. 2.0.173. | 348 | * v2.0, 2015-05-30, fix [#209](https://github.com/simple-rtmp-server/srs/issues/209) cleanup hls when stop and timeout. 2.0.173. |
348 | * v2.0, 2015-05-29, fix [#409](https://github.com/simple-rtmp-server/srs/issues/409) support pure video hls. 2.0.172. | 349 | * v2.0, 2015-05-29, fix [#409](https://github.com/simple-rtmp-server/srs/issues/409) support pure video hls. 2.0.172. |
349 | * v2.0, 2015-05-28, support [srs-dolphin][srs-dolphin], the multiple-process SRS. | 350 | * v2.0, 2015-05-28, support [srs-dolphin][srs-dolphin], the multiple-process SRS. |
@@ -787,12 +787,19 @@ int SrsHlsMuxer::segment_close(string log_desc) | @@ -787,12 +787,19 @@ int SrsHlsMuxer::segment_close(string log_desc) | ||
787 | for (int i = 0; i < (int)segment_to_remove.size(); i++) { | 787 | for (int i = 0; i < (int)segment_to_remove.size(); i++) { |
788 | SrsHlsSegment* segment = segment_to_remove[i]; | 788 | SrsHlsSegment* segment = segment_to_remove[i]; |
789 | 789 | ||
790 | - if (hls_cleanup) { | 790 | + if (hls_cleanup && should_write_file) { |
791 | if (unlink(segment->full_path.c_str()) < 0) { | 791 | if (unlink(segment->full_path.c_str()) < 0) { |
792 | srs_warn("cleanup unlink path failed, file=%s.", segment->full_path.c_str()); | 792 | srs_warn("cleanup unlink path failed, file=%s.", segment->full_path.c_str()); |
793 | } | 793 | } |
794 | } | 794 | } |
795 | 795 | ||
796 | + if (should_write_cache) { | ||
797 | + if ((ret = handler->on_remove_ts(req, segment->uri)) != ERROR_SUCCESS) { | ||
798 | + srs_warn("remove the ts from ram hls failed. ret=%d", ret); | ||
799 | + return ret; | ||
800 | + } | ||
801 | + } | ||
802 | + | ||
796 | srs_freep(segment); | 803 | srs_freep(segment); |
797 | } | 804 | } |
798 | segment_to_remove.clear(); | 805 | segment_to_remove.clear(); |
@@ -76,6 +76,11 @@ public: | @@ -76,6 +76,11 @@ public: | ||
76 | */ | 76 | */ |
77 | virtual int on_update_ts(SrsRequest* r, std::string uri, std::string ts) = 0; | 77 | virtual int on_update_ts(SrsRequest* r, std::string uri, std::string ts) = 0; |
78 | /** | 78 | /** |
79 | + * when remove the specified ts file, | ||
80 | + * for the hls to remove the expired ts not in hls window. | ||
81 | + */ | ||
82 | + virtual int on_remove_ts(SrsRequest* r, std::string uri) = 0; | ||
83 | + /** | ||
79 | * when unpublish stream | 84 | * when unpublish stream |
80 | */ | 85 | */ |
81 | virtual int on_hls_unpublish(SrsRequest* req) = 0; | 86 | virtual int on_hls_unpublish(SrsRequest* req) = 0; |
@@ -1878,6 +1878,7 @@ int SrsHlsTsStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) | @@ -1878,6 +1878,7 @@ int SrsHlsTsStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) | ||
1878 | 1878 | ||
1879 | SrsHlsEntry::SrsHlsEntry() | 1879 | SrsHlsEntry::SrsHlsEntry() |
1880 | { | 1880 | { |
1881 | + tmpl = NULL; | ||
1881 | } | 1882 | } |
1882 | 1883 | ||
1883 | SrsHttpServer::SrsHttpServer(SrsServer* svr) | 1884 | SrsHttpServer::SrsHttpServer(SrsServer* svr) |
@@ -1948,6 +1949,7 @@ int SrsHttpServer::initialize() | @@ -1948,6 +1949,7 @@ int SrsHttpServer::initialize() | ||
1948 | return ret; | 1949 | return ret; |
1949 | } | 1950 | } |
1950 | 1951 | ||
1952 | +// TODO: FIXME: rename for HTTP FLV mount. | ||
1951 | int SrsHttpServer::http_mount(SrsSource* s, SrsRequest* r) | 1953 | int SrsHttpServer::http_mount(SrsSource* s, SrsRequest* r) |
1952 | { | 1954 | { |
1953 | int ret = ERROR_SUCCESS; | 1955 | int ret = ERROR_SUCCESS; |
@@ -2063,6 +2065,7 @@ int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8) | @@ -2063,6 +2065,7 @@ int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8) | ||
2063 | } | 2065 | } |
2064 | 2066 | ||
2065 | SrsHlsEntry* tmpl = thls[r->vhost]; | 2067 | SrsHlsEntry* tmpl = thls[r->vhost]; |
2068 | + srs_assert(tmpl); | ||
2066 | 2069 | ||
2067 | entry = new SrsHlsEntry(); | 2070 | entry = new SrsHlsEntry(); |
2068 | mount = tmpl->mount; | 2071 | mount = tmpl->mount; |
@@ -2075,6 +2078,7 @@ int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8) | @@ -2075,6 +2078,7 @@ int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8) | ||
2075 | // remove the default vhost mount | 2078 | // remove the default vhost mount |
2076 | mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); | 2079 | mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); |
2077 | 2080 | ||
2081 | + entry->tmpl = tmpl; | ||
2078 | entry->mount = mount; | 2082 | entry->mount = mount; |
2079 | shls[sid] = entry; | 2083 | shls[sid] = entry; |
2080 | 2084 | ||
@@ -2109,32 +2113,18 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts) | @@ -2109,32 +2113,18 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts) | ||
2109 | 2113 | ||
2110 | std::string sid = r->get_stream_url(); | 2114 | std::string sid = r->get_stream_url(); |
2111 | 2115 | ||
2112 | - // when no hls mounted, ignore. | 2116 | + // when no hls mounted, init with empty m3u8. |
2113 | if (shls.find(sid) == shls.end()) { | 2117 | if (shls.find(sid) == shls.end()) { |
2118 | + if ((ret = hls_update_m3u8(r, "")) != ERROR_SUCCESS) { | ||
2114 | return ret; | 2119 | return ret; |
2115 | } | 2120 | } |
2121 | + } | ||
2116 | 2122 | ||
2117 | SrsHlsEntry* entry = shls[sid]; | 2123 | SrsHlsEntry* entry = shls[sid]; |
2118 | srs_assert(entry); | 2124 | srs_assert(entry); |
2125 | + srs_assert(entry->tmpl); | ||
2119 | 2126 | ||
2120 | - std::string mount = entry->mount; | ||
2121 | - | ||
2122 | - // the ts is relative from the m3u8, the same start dir. | ||
2123 | - size_t pos = string::npos; | ||
2124 | - if ((pos = mount.rfind("/")) != string::npos) { | ||
2125 | - mount = mount.substr(0, pos); | ||
2126 | - } | ||
2127 | - | ||
2128 | - // replace the vhost variable | ||
2129 | - mount = srs_string_replace(mount, "[vhost]", r->vhost); | ||
2130 | - mount = srs_string_replace(mount, "[app]", r->app); | ||
2131 | - | ||
2132 | - // remove the default vhost mount | ||
2133 | - mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); | ||
2134 | - | ||
2135 | - // mount with ts. | ||
2136 | - mount += "/"; | ||
2137 | - mount += uri; | 2127 | + std::string mount = hls_mount_generate(r, uri, entry->tmpl->mount); |
2138 | 2128 | ||
2139 | if (entry->streams.find(mount) == entry->streams.end()) { | 2129 | if (entry->streams.find(mount) == entry->streams.end()) { |
2140 | ISrsHttpHandler* he = new SrsHlsTsStream(); | 2130 | ISrsHttpHandler* he = new SrsHlsTsStream(); |
@@ -2156,6 +2146,40 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts) | @@ -2156,6 +2146,40 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts) | ||
2156 | return ret; | 2146 | return ret; |
2157 | } | 2147 | } |
2158 | 2148 | ||
2149 | + | ||
2150 | +int SrsHttpServer::hls_remove_ts(SrsRequest* r, string uri) | ||
2151 | +{ | ||
2152 | + int ret = ERROR_SUCCESS; | ||
2153 | + | ||
2154 | + std::string sid = r->get_stream_url(); | ||
2155 | + | ||
2156 | + // when no hls mounted, ignore. | ||
2157 | + if (shls.find(sid) == shls.end()) { | ||
2158 | + return ret; | ||
2159 | + } | ||
2160 | + | ||
2161 | + SrsHlsEntry* entry = shls[sid]; | ||
2162 | + srs_assert(entry); | ||
2163 | + srs_assert(entry->tmpl); | ||
2164 | + | ||
2165 | + std::string mount = hls_mount_generate(r, uri, entry->tmpl->mount); | ||
2166 | + | ||
2167 | + // ignore when no ts mounted. | ||
2168 | + if (entry->streams.find(mount) == entry->streams.end()) { | ||
2169 | + return ret; | ||
2170 | + } | ||
2171 | + | ||
2172 | + // update the ts stream. | ||
2173 | + SrsHlsTsStream* hts = dynamic_cast<SrsHlsTsStream*>(entry->streams[mount]); | ||
2174 | + if (hts) { | ||
2175 | + hts->set_ts(""); | ||
2176 | + // TODO: FIXME: unmount and remove the http handler. | ||
2177 | + } | ||
2178 | + srs_trace("hls remove ts ok, mount=%s", mount.c_str()); | ||
2179 | + | ||
2180 | + return ret; | ||
2181 | +} | ||
2182 | + | ||
2159 | void SrsHttpServer::unmount_hls(SrsRequest* r) | 2183 | void SrsHttpServer::unmount_hls(SrsRequest* r) |
2160 | { | 2184 | { |
2161 | std::string sid = r->get_stream_url(); | 2185 | std::string sid = r->get_stream_url(); |
@@ -2423,6 +2447,30 @@ int SrsHttpServer::initialize_hls_streaming() | @@ -2423,6 +2447,30 @@ int SrsHttpServer::initialize_hls_streaming() | ||
2423 | return ret; | 2447 | return ret; |
2424 | } | 2448 | } |
2425 | 2449 | ||
2450 | +string SrsHttpServer::hls_mount_generate(SrsRequest* r, string uri, string tmpl) | ||
2451 | +{ | ||
2452 | + std::string mount = tmpl; | ||
2453 | + | ||
2454 | + // the ts is relative from the m3u8, the same start dir. | ||
2455 | + size_t pos = string::npos; | ||
2456 | + if ((pos = mount.rfind("/")) != string::npos) { | ||
2457 | + mount = mount.substr(0, pos); | ||
2458 | + } | ||
2459 | + | ||
2460 | + // replace the vhost variable | ||
2461 | + mount = srs_string_replace(mount, "[vhost]", r->vhost); | ||
2462 | + mount = srs_string_replace(mount, "[app]", r->app); | ||
2463 | + | ||
2464 | + // remove the default vhost mount | ||
2465 | + mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); | ||
2466 | + | ||
2467 | + // mount with ts. | ||
2468 | + mount += "/"; | ||
2469 | + mount += uri; | ||
2470 | + | ||
2471 | + return mount; | ||
2472 | +} | ||
2473 | + | ||
2426 | #endif | 2474 | #endif |
2427 | 2475 | ||
2428 | #ifdef SRS_AUTO_HTTP_CORE | 2476 | #ifdef SRS_AUTO_HTTP_CORE |
@@ -650,12 +650,16 @@ public: | @@ -650,12 +650,16 @@ public: | ||
650 | /** | 650 | /** |
651 | * the srs hls entry. | 651 | * the srs hls entry. |
652 | */ | 652 | */ |
653 | +// TODO: FIXME: use hte hls template and entry. | ||
653 | struct SrsHlsEntry | 654 | struct SrsHlsEntry |
654 | { | 655 | { |
655 | // for template, the mount contains variables. | 656 | // for template, the mount contains variables. |
656 | // for concrete stream, the mount is url to access. | 657 | // for concrete stream, the mount is url to access. |
657 | std::string mount; | 658 | std::string mount; |
658 | 659 | ||
660 | + // the template to create the entry | ||
661 | + SrsHlsEntry* tmpl; | ||
662 | + | ||
659 | // key: the m3u8/ts file path. | 663 | // key: the m3u8/ts file path. |
660 | // value: the http handler. | 664 | // value: the http handler. |
661 | std::map<std::string, ISrsHttpHandler*> streams; | 665 | std::map<std::string, ISrsHttpHandler*> streams; |
@@ -696,6 +700,7 @@ public: | @@ -696,6 +700,7 @@ public: | ||
696 | virtual int mount_hls(SrsRequest* r); | 700 | virtual int mount_hls(SrsRequest* r); |
697 | virtual int hls_update_m3u8(SrsRequest* r, std::string m3u8); | 701 | virtual int hls_update_m3u8(SrsRequest* r, std::string m3u8); |
698 | virtual int hls_update_ts(SrsRequest* r, std::string uri, std::string ts); | 702 | virtual int hls_update_ts(SrsRequest* r, std::string uri, std::string ts); |
703 | + virtual int hls_remove_ts(SrsRequest* r, std::string uri); | ||
699 | virtual void unmount_hls(SrsRequest* r); | 704 | virtual void unmount_hls(SrsRequest* r); |
700 | // interface ISrsReloadHandler. | 705 | // interface ISrsReloadHandler. |
701 | public: | 706 | public: |
@@ -709,6 +714,7 @@ private: | @@ -709,6 +714,7 @@ private: | ||
709 | virtual int initialize_static_file(); | 714 | virtual int initialize_static_file(); |
710 | virtual int initialize_flv_streaming(); | 715 | virtual int initialize_flv_streaming(); |
711 | virtual int initialize_hls_streaming(); | 716 | virtual int initialize_hls_streaming(); |
717 | + virtual std::string hls_mount_generate(SrsRequest* r, std::string uri, std::string tmpl); | ||
712 | }; | 718 | }; |
713 | 719 | ||
714 | #endif | 720 | #endif |
@@ -1411,6 +1411,20 @@ int SrsServer::on_update_ts(SrsRequest* r, string uri, string ts) | @@ -1411,6 +1411,20 @@ int SrsServer::on_update_ts(SrsRequest* r, string uri, string ts) | ||
1411 | return ret; | 1411 | return ret; |
1412 | } | 1412 | } |
1413 | 1413 | ||
1414 | + | ||
1415 | +int SrsServer::on_remove_ts(SrsRequest* r, string uri) | ||
1416 | +{ | ||
1417 | + int ret = ERROR_SUCCESS; | ||
1418 | + | ||
1419 | +#ifdef SRS_AUTO_HTTP_SERVER | ||
1420 | + if ((ret = http_stream_mux->hls_remove_ts(r, uri)) != ERROR_SUCCESS) { | ||
1421 | + return ret; | ||
1422 | + } | ||
1423 | +#endif | ||
1424 | + | ||
1425 | + return ret; | ||
1426 | +} | ||
1427 | + | ||
1414 | int SrsServer::on_hls_unpublish(SrsRequest* r) | 1428 | int SrsServer::on_hls_unpublish(SrsRequest* r) |
1415 | { | 1429 | { |
1416 | int ret = ERROR_SUCCESS; | 1430 | int ret = ERROR_SUCCESS; |
@@ -375,6 +375,7 @@ public: | @@ -375,6 +375,7 @@ public: | ||
375 | virtual int on_hls_publish(SrsRequest* r); | 375 | virtual int on_hls_publish(SrsRequest* r); |
376 | virtual int on_update_m3u8(SrsRequest* r, std::string m3u8); | 376 | virtual int on_update_m3u8(SrsRequest* r, std::string m3u8); |
377 | virtual int on_update_ts(SrsRequest* r, std::string uri, std::string ts); | 377 | virtual int on_update_ts(SrsRequest* r, std::string uri, std::string ts); |
378 | + virtual int on_remove_ts(SrsRequest* r, std::string uri); | ||
378 | virtual int on_hls_unpublish(SrsRequest* r); | 379 | virtual int on_hls_unpublish(SrsRequest* r); |
379 | }; | 380 | }; |
380 | 381 |
-
请 注册 或 登录 后发表评论