winlin

fix #420, remove ts for hls ram mode.

@@ -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