fix #322, fix http-flv stream bug, support multiple streams. 2.0.133.

pull/133/head
winlin 10 years ago
parent 1277968d4a
commit f26e719800

@ -551,6 +551,7 @@ Supported operating systems and hardware:
### SRS 2.0 history ### SRS 2.0 history
* v2.0, 2015-03-06, for [#322](https://github.com/winlinvip/simple-rtmp-server/issues/322), fix http-flv stream bug, support multiple streams. 2.0.133.
* v2.0, 2015-03-06, refine http request parse. 2.0.132. * v2.0, 2015-03-06, refine http request parse. 2.0.132.
* v2.0, 2015-03-01, for [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), revert dvr http api. 2.0.128. * v2.0, 2015-03-01, for [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), revert dvr http api. 2.0.128.
* v2.0, 2015-02-24, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), fix hls bug, write pts/dts error. 2.0.124 * v2.0, 2015-02-24, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), fix hls bug, write pts/dts error. 2.0.124

@ -771,19 +771,35 @@ SrsHttpServer::~SrsHttpServer()
{ {
if (true) { if (true) {
std::map<std::string, SrsLiveEntry*>::iterator it; std::map<std::string, SrsLiveEntry*>::iterator it;
for (it = flvs.begin(); it != flvs.end(); ++it) { for (it = tflvs.begin(); it != tflvs.end(); ++it) {
SrsLiveEntry* entry = it->second; SrsLiveEntry* entry = it->second;
srs_freep(entry); srs_freep(entry);
} }
flvs.clear(); tflvs.clear();
}
if (true) {
std::map<std::string, SrsLiveEntry*>::iterator it;
for (it = sflvs.begin(); it != sflvs.end(); ++it) {
SrsLiveEntry* entry = it->second;
srs_freep(entry);
}
sflvs.clear();
} }
if (true) { if (true) {
std::map<std::string, SrsHlsEntry*>::iterator it; std::map<std::string, SrsHlsEntry*>::iterator it;
for (it = hls.begin(); it != hls.end(); ++it) { for (it = thls.begin(); it != thls.end(); ++it) {
SrsHlsEntry* entry = it->second; SrsHlsEntry* entry = it->second;
srs_freep(entry); srs_freep(entry);
} }
hls.clear(); thls.clear();
}
if (true) {
std::map<std::string, SrsHlsEntry*>::iterator it;
for (it = shls.begin(); it != shls.end(); ++it) {
SrsHlsEntry* entry = it->second;
srs_freep(entry);
}
shls.clear();
} }
} }
@ -814,56 +830,72 @@ int SrsHttpServer::mount(SrsSource* s, SrsRequest* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (flvs.find(r->vhost) == flvs.end()) { // the id to identify stream.
srs_info("ignore mount flv stream for disabled"); std::string sid = r->get_stream_url();
return ret; SrsLiveEntry* entry = NULL;
}
SrsLiveEntry* entry = flvs[r->vhost]; // create stream from template when not found.
if (sflvs.find(sid) == sflvs.end()) {
if (tflvs.find(r->vhost) == tflvs.end()) {
srs_info("ignore mount flv stream for disabled");
return ret;
}
// TODO: FIXME: supports reload. SrsLiveEntry* tmpl = tflvs[r->vhost];
if (entry->stream) {
entry->stream->entry->enabled = true;
return ret;
}
std::string mount = entry->mount; std::string mount = tmpl->mount;
// replace the vhost variable // replace the vhost variable
mount = srs_string_replace(mount, "[vhost]", r->vhost); mount = srs_string_replace(mount, "[vhost]", r->vhost);
mount = srs_string_replace(mount, "[app]", r->app); mount = srs_string_replace(mount, "[app]", r->app);
mount = srs_string_replace(mount, "[stream]", r->stream); mount = srs_string_replace(mount, "[stream]", r->stream);
// remove the default vhost mount // remove the default vhost mount
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
entry->cache = new SrsStreamCache(s, r); entry = new SrsLiveEntry();
entry->stream = new SrsLiveStream(s, r, entry->cache); entry->mount = mount;
// start http stream cache thread entry->cache = new SrsStreamCache(s, r);
if ((ret = entry->cache->start()) != ERROR_SUCCESS) { entry->stream = new SrsLiveStream(s, r, entry->cache);
srs_error("http: start stream cache failed. ret=%d", ret);
return ret; sflvs[sid] = entry;
// start http stream cache thread
if ((ret = entry->cache->start()) != ERROR_SUCCESS) {
srs_error("http: start stream cache failed. ret=%d", ret);
return ret;
}
// mount the http flv stream.
if ((ret = mux.handle(mount, entry->stream)) != ERROR_SUCCESS) {
srs_error("http: mount flv stream for vhost=%s failed. ret=%d", sid.c_str(), ret);
return ret;
}
srs_trace("http: mount flv stream for vhost=%s, mount=%s", sid.c_str(), mount.c_str());
} else {
entry = sflvs[sid];
} }
// mount the http flv stream. // TODO: FIXME: supports reload.
if ((ret = mux.handle(mount, entry->stream)) != ERROR_SUCCESS) { if (entry->stream) {
srs_error("http: mount flv stream for vhost=%s failed. ret=%d", r->vhost.c_str(), ret); entry->stream->entry->enabled = true;
return ret; return ret;
} }
srs_trace("http: mount flv stream for vhost=%s, mount=%s", r->vhost.c_str(), mount.c_str());
return ret; return ret;
} }
void SrsHttpServer::unmount(SrsSource* s, SrsRequest* r) void SrsHttpServer::unmount(SrsSource* s, SrsRequest* r)
{ {
if (flvs.find(r->vhost) == flvs.end()) { std::string sid = r->get_stream_url();
if (sflvs.find(sid) == sflvs.end()) {
srs_info("ignore unmount flv stream for disabled"); srs_info("ignore unmount flv stream for disabled");
return; return;
} }
SrsLiveEntry* entry = flvs[r->vhost]; SrsLiveEntry* entry = sflvs[sid];
entry->stream->entry->enabled = false; entry->stream->entry->enabled = false;
} }
@ -871,12 +903,14 @@ int SrsHttpServer::mount_hls(SrsRequest* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (hls.find(r->vhost) == hls.end()) { std::string sid = r->get_stream_url();
if (shls.find(sid) == shls.end()) {
srs_info("ignore mount hls stream for disabled"); srs_info("ignore mount hls stream for disabled");
return ret; return ret;
} }
SrsHlsEntry* entry = hls[r->vhost]; SrsHlsEntry* entry = shls[sid];
// TODO: FIXME: supports reload. // TODO: FIXME: supports reload.
std::map<std::string, ISrsHttpHandler*>::iterator it; std::map<std::string, ISrsHttpHandler*>::iterator it;
@ -892,32 +926,36 @@ int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// when no hls mounted, ignore. std::string mount = m3u8;
if (hls.find(r->vhost) == hls.end()) {
return ret;
}
SrsHlsEntry* entry = hls[r->vhost]; std::string sid = r->get_stream_url();
srs_assert(entry); SrsHlsEntry* entry = NULL;
std::string mount = entry->mount; // create stream from template when not found.
if (shls.find(sid) == shls.end()) {
if (thls.find(r->vhost) == thls.end()) {
srs_info("ignore mount hls stream for disabled");
return ret;
}
// replace the vhost variable SrsHlsEntry* tmpl = thls[r->vhost];
mount = srs_string_replace(mount, "[vhost]", r->vhost);
mount = srs_string_replace(mount, "[app]", r->app);
mount = srs_string_replace(mount, "[stream]", r->stream);
// remove the default vhost mount entry = new SrsHlsEntry();
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); entry->mount = tmpl->mount;
if (entry->streams.find(mount) == entry->streams.end()) { shls[sid] = entry;
ISrsHttpHandler* he = new SrsHlsM3u8Stream();
entry->streams[mount] = he;
if ((ret = mux.handle(mount, he)) != ERROR_SUCCESS) { if (entry->streams.find(mount) == entry->streams.end()) {
srs_error("handle mount=%s failed. ret=%d", mount.c_str(), ret); ISrsHttpHandler* he = new SrsHlsM3u8Stream();
return ret; entry->streams[mount] = he;
if ((ret = mux.handle(mount, he)) != ERROR_SUCCESS) {
srs_error("handle mount=%s failed. ret=%d", mount.c_str(), ret);
return ret;
}
} }
} else {
entry = shls[sid];
} }
// update the m3u8 stream. // update the m3u8 stream.
@ -934,12 +972,14 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
std::string sid = r->get_stream_url();
// when no hls mounted, ignore. // when no hls mounted, ignore.
if (hls.find(r->vhost) == hls.end()) { if (shls.find(sid) == shls.end()) {
return ret; return ret;
} }
SrsHlsEntry* entry = hls[r->vhost]; SrsHlsEntry* entry = shls[sid];
srs_assert(entry); srs_assert(entry);
std::string mount = entry->mount; std::string mount = entry->mount;
@ -983,12 +1023,14 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
void SrsHttpServer::unmount_hls(SrsRequest* r) void SrsHttpServer::unmount_hls(SrsRequest* r)
{ {
if (hls.find(r->vhost) == hls.end()) { std::string sid = r->get_stream_url();
if (shls.find(sid) == shls.end()) {
srs_info("ignore unmount hls stream for disabled"); srs_info("ignore unmount hls stream for disabled");
return; return;
} }
SrsHlsEntry* entry = hls[r->vhost]; SrsHlsEntry* entry = shls[sid];
std::map<std::string, ISrsHttpHandler*>::iterator it; std::map<std::string, ISrsHttpHandler*>::iterator it;
for (it = entry->streams.begin(); it != entry->streams.end(); ++it) { for (it = entry->streams.begin(); it != entry->streams.end(); ++it) {
@ -1097,9 +1139,8 @@ int SrsHttpServer::initialize_flv_streaming()
} }
SrsLiveEntry* entry = new SrsLiveEntry(); SrsLiveEntry* entry = new SrsLiveEntry();
entry->vhost = vhost;
entry->mount = _srs_config->get_vhost_http_remux_mount(vhost); entry->mount = _srs_config->get_vhost_http_remux_mount(vhost);
flvs[vhost] = entry; tflvs[vhost] = entry;
srs_trace("http flv live stream, vhost=%s, mount=%s", srs_trace("http flv live stream, vhost=%s, mount=%s",
vhost.c_str(), entry->mount.c_str()); vhost.c_str(), entry->mount.c_str());
} }
@ -1131,9 +1172,8 @@ int SrsHttpServer::initialize_hls_streaming()
} }
SrsHlsEntry* entry = new SrsHlsEntry(); SrsHlsEntry* entry = new SrsHlsEntry();
entry->vhost = vhost;
entry->mount = _srs_config->get_hls_mount(vhost); entry->mount = _srs_config->get_hls_mount(vhost);
hls[vhost] = entry; thls[vhost] = entry;
srs_trace("http hls live stream, vhost=%s, mount=%s", srs_trace("http hls live stream, vhost=%s, mount=%s",
vhost.c_str(), entry->mount.c_str()); vhost.c_str(), entry->mount.c_str());
} }

@ -252,8 +252,10 @@ private:
*/ */
struct SrsLiveEntry struct SrsLiveEntry
{ {
std::string vhost; // for template, the mount contains variables.
// for concrete stream, the mount is url to access.
std::string mount; std::string mount;
SrsLiveStream* stream; SrsLiveStream* stream;
SrsStreamCache* cache; SrsStreamCache* cache;
@ -297,7 +299,8 @@ public:
*/ */
struct SrsHlsEntry struct SrsHlsEntry
{ {
std::string vhost; // for template, the mount contains variables.
// for concrete stream, the mount is url to access.
std::string mount; std::string mount;
// key: the m3u8/ts file path. // key: the m3u8/ts file path.
@ -315,10 +318,14 @@ class SrsHttpServer : public ISrsReloadHandler
{ {
public: public:
SrsHttpServeMux mux; SrsHttpServeMux mux;
// the flv live streaming template. // the flv live streaming template, to create streams.
std::map<std::string, SrsLiveEntry*> flvs; std::map<std::string, SrsLiveEntry*> tflvs;
// the hls live streaming template. // the flv live streaming streams, crote by template.
std::map<std::string, SrsHlsEntry*> hls; std::map<std::string, SrsLiveEntry*> sflvs;
// the hls live streaming template, to create streams.
std::map<std::string, SrsHlsEntry*> thls;
// the hls live streaming streams, crote by template.
std::map<std::string, SrsHlsEntry*> shls;
public: public:
SrsHttpServer(); SrsHttpServer();
virtual ~SrsHttpServer(); virtual ~SrsHttpServer();

@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version // current release version
#define VERSION_MAJOR 2 #define VERSION_MAJOR 2
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_REVISION 132 #define VERSION_REVISION 133
// server info. // server info.
#define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_KEY "SRS"

Loading…
Cancel
Save