winlin

fix #420, remove ts for hls ram mode.

... ... @@ -344,6 +344,7 @@ Remark:
### SRS 2.0 history
* v2.0, 2015-05-30, fix [#420](https://github.com/simple-rtmp-server/srs/issues/420) remove ts for hls ram mode.
* 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.
* v2.0, 2015-05-29, fix [#409](https://github.com/simple-rtmp-server/srs/issues/409) support pure video hls. 2.0.172.
* 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)
for (int i = 0; i < (int)segment_to_remove.size(); i++) {
SrsHlsSegment* segment = segment_to_remove[i];
if (hls_cleanup) {
if (hls_cleanup && should_write_file) {
if (unlink(segment->full_path.c_str()) < 0) {
srs_warn("cleanup unlink path failed, file=%s.", segment->full_path.c_str());
}
}
if (should_write_cache) {
if ((ret = handler->on_remove_ts(req, segment->uri)) != ERROR_SUCCESS) {
srs_warn("remove the ts from ram hls failed. ret=%d", ret);
return ret;
}
}
srs_freep(segment);
}
segment_to_remove.clear();
... ...
... ... @@ -64,20 +64,25 @@ public:
virtual ~ISrsHlsHandler();
public:
/**
* when publish stream
*/
* when publish stream
*/
virtual int on_hls_publish(SrsRequest* req) = 0;
/**
* when update the m3u8 file.
*/
* when update the m3u8 file.
*/
virtual int on_update_m3u8(SrsRequest* r, std::string m3u8) = 0;
/**
* when reap new ts file.
*/
* when reap new ts file.
*/
virtual int on_update_ts(SrsRequest* r, std::string uri, std::string ts) = 0;
/**
* when unpublish stream
*/
* when remove the specified ts file,
* for the hls to remove the expired ts not in hls window.
*/
virtual int on_remove_ts(SrsRequest* r, std::string uri) = 0;
/**
* when unpublish stream
*/
virtual int on_hls_unpublish(SrsRequest* req) = 0;
};
... ...
... ... @@ -1878,6 +1878,7 @@ int SrsHlsTsStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
SrsHlsEntry::SrsHlsEntry()
{
tmpl = NULL;
}
SrsHttpServer::SrsHttpServer(SrsServer* svr)
... ... @@ -1948,6 +1949,7 @@ int SrsHttpServer::initialize()
return ret;
}
// TODO: FIXME: rename for HTTP FLV mount.
int SrsHttpServer::http_mount(SrsSource* s, SrsRequest* r)
{
int ret = ERROR_SUCCESS;
... ... @@ -2063,6 +2065,7 @@ int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8)
}
SrsHlsEntry* tmpl = thls[r->vhost];
srs_assert(tmpl);
entry = new SrsHlsEntry();
mount = tmpl->mount;
... ... @@ -2075,6 +2078,7 @@ int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8)
// remove the default vhost mount
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
entry->tmpl = tmpl;
entry->mount = mount;
shls[sid] = entry;
... ... @@ -2109,32 +2113,18 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
std::string sid = r->get_stream_url();
// when no hls mounted, ignore.
// when no hls mounted, init with empty m3u8.
if (shls.find(sid) == shls.end()) {
return ret;
if ((ret = hls_update_m3u8(r, "")) != ERROR_SUCCESS) {
return ret;
}
}
SrsHlsEntry* entry = shls[sid];
srs_assert(entry);
srs_assert(entry->tmpl);
std::string mount = entry->mount;
// the ts is relative from the m3u8, the same start dir.
size_t pos = string::npos;
if ((pos = mount.rfind("/")) != string::npos) {
mount = mount.substr(0, pos);
}
// replace the vhost variable
mount = srs_string_replace(mount, "[vhost]", r->vhost);
mount = srs_string_replace(mount, "[app]", r->app);
// remove the default vhost mount
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
// mount with ts.
mount += "/";
mount += uri;
std::string mount = hls_mount_generate(r, uri, entry->tmpl->mount);
if (entry->streams.find(mount) == entry->streams.end()) {
ISrsHttpHandler* he = new SrsHlsTsStream();
... ... @@ -2156,6 +2146,40 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
return ret;
}
int SrsHttpServer::hls_remove_ts(SrsRequest* r, string uri)
{
int ret = ERROR_SUCCESS;
std::string sid = r->get_stream_url();
// when no hls mounted, ignore.
if (shls.find(sid) == shls.end()) {
return ret;
}
SrsHlsEntry* entry = shls[sid];
srs_assert(entry);
srs_assert(entry->tmpl);
std::string mount = hls_mount_generate(r, uri, entry->tmpl->mount);
// ignore when no ts mounted.
if (entry->streams.find(mount) == entry->streams.end()) {
return ret;
}
// update the ts stream.
SrsHlsTsStream* hts = dynamic_cast<SrsHlsTsStream*>(entry->streams[mount]);
if (hts) {
hts->set_ts("");
// TODO: FIXME: unmount and remove the http handler.
}
srs_trace("hls remove ts ok, mount=%s", mount.c_str());
return ret;
}
void SrsHttpServer::unmount_hls(SrsRequest* r)
{
std::string sid = r->get_stream_url();
... ... @@ -2423,6 +2447,30 @@ int SrsHttpServer::initialize_hls_streaming()
return ret;
}
string SrsHttpServer::hls_mount_generate(SrsRequest* r, string uri, string tmpl)
{
std::string mount = tmpl;
// the ts is relative from the m3u8, the same start dir.
size_t pos = string::npos;
if ((pos = mount.rfind("/")) != string::npos) {
mount = mount.substr(0, pos);
}
// replace the vhost variable
mount = srs_string_replace(mount, "[vhost]", r->vhost);
mount = srs_string_replace(mount, "[app]", r->app);
// remove the default vhost mount
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
// mount with ts.
mount += "/";
mount += uri;
return mount;
}
#endif
#ifdef SRS_AUTO_HTTP_CORE
... ...
... ... @@ -650,11 +650,15 @@ public:
/**
* the srs hls entry.
*/
// TODO: FIXME: use hte hls template and entry.
struct SrsHlsEntry
{
// for template, the mount contains variables.
// for concrete stream, the mount is url to access.
std::string mount;
// the template to create the entry
SrsHlsEntry* tmpl;
// key: the m3u8/ts file path.
// value: the http handler.
... ... @@ -696,6 +700,7 @@ public:
virtual int mount_hls(SrsRequest* r);
virtual int hls_update_m3u8(SrsRequest* r, std::string m3u8);
virtual int hls_update_ts(SrsRequest* r, std::string uri, std::string ts);
virtual int hls_remove_ts(SrsRequest* r, std::string uri);
virtual void unmount_hls(SrsRequest* r);
// interface ISrsReloadHandler.
public:
... ... @@ -709,6 +714,7 @@ private:
virtual int initialize_static_file();
virtual int initialize_flv_streaming();
virtual int initialize_hls_streaming();
virtual std::string hls_mount_generate(SrsRequest* r, std::string uri, std::string tmpl);
};
#endif
... ...
... ... @@ -1411,6 +1411,20 @@ int SrsServer::on_update_ts(SrsRequest* r, string uri, string ts)
return ret;
}
int SrsServer::on_remove_ts(SrsRequest* r, string uri)
{
int ret = ERROR_SUCCESS;
#ifdef SRS_AUTO_HTTP_SERVER
if ((ret = http_stream_mux->hls_remove_ts(r, uri)) != ERROR_SUCCESS) {
return ret;
}
#endif
return ret;
}
int SrsServer::on_hls_unpublish(SrsRequest* r)
{
int ret = ERROR_SUCCESS;
... ...
... ... @@ -375,6 +375,7 @@ public:
virtual int on_hls_publish(SrsRequest* r);
virtual int on_update_m3u8(SrsRequest* r, std::string m3u8);
virtual int on_update_ts(SrsRequest* r, std::string uri, std::string ts);
virtual int on_remove_ts(SrsRequest* r, std::string uri);
virtual int on_hls_unpublish(SrsRequest* r);
};
... ...