winlin

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

@@ -551,6 +551,7 @@ Supported operating systems and hardware: @@ -551,6 +551,7 @@ Supported operating systems and hardware:
551 551
552 ### SRS 2.0 history 552 ### SRS 2.0 history
553 553
  554 +* 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.
554 * v2.0, 2015-03-06, refine http request parse. 2.0.132. 555 * v2.0, 2015-03-06, refine http request parse. 2.0.132.
555 * v2.0, 2015-03-01, for [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), revert dvr http api. 2.0.128. 556 * v2.0, 2015-03-01, for [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), revert dvr http api. 2.0.128.
556 * 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 557 * 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() @@ -771,19 +771,35 @@ SrsHttpServer::~SrsHttpServer()
771 { 771 {
772 if (true) { 772 if (true) {
773 std::map<std::string, SrsLiveEntry*>::iterator it; 773 std::map<std::string, SrsLiveEntry*>::iterator it;
774 - for (it = flvs.begin(); it != flvs.end(); ++it) { 774 + for (it = tflvs.begin(); it != tflvs.end(); ++it) {
775 SrsLiveEntry* entry = it->second; 775 SrsLiveEntry* entry = it->second;
776 srs_freep(entry); 776 srs_freep(entry);
777 } 777 }
778 - flvs.clear(); 778 + tflvs.clear();
  779 + }
  780 + if (true) {
  781 + std::map<std::string, SrsLiveEntry*>::iterator it;
  782 + for (it = sflvs.begin(); it != sflvs.end(); ++it) {
  783 + SrsLiveEntry* entry = it->second;
  784 + srs_freep(entry);
  785 + }
  786 + sflvs.clear();
  787 + }
  788 + if (true) {
  789 + std::map<std::string, SrsHlsEntry*>::iterator it;
  790 + for (it = thls.begin(); it != thls.end(); ++it) {
  791 + SrsHlsEntry* entry = it->second;
  792 + srs_freep(entry);
  793 + }
  794 + thls.clear();
779 } 795 }
780 if (true) { 796 if (true) {
781 std::map<std::string, SrsHlsEntry*>::iterator it; 797 std::map<std::string, SrsHlsEntry*>::iterator it;
782 - for (it = hls.begin(); it != hls.end(); ++it) { 798 + for (it = shls.begin(); it != shls.end(); ++it) {
783 SrsHlsEntry* entry = it->second; 799 SrsHlsEntry* entry = it->second;
784 srs_freep(entry); 800 srs_freep(entry);
785 } 801 }
786 - hls.clear(); 802 + shls.clear();
787 } 803 }
788 } 804 }
789 805
@@ -814,56 +830,72 @@ int SrsHttpServer::mount(SrsSource* s, SrsRequest* r) @@ -814,56 +830,72 @@ int SrsHttpServer::mount(SrsSource* s, SrsRequest* r)
814 { 830 {
815 int ret = ERROR_SUCCESS; 831 int ret = ERROR_SUCCESS;
816 832
817 - if (flvs.find(r->vhost) == flvs.end()) {  
818 - srs_info("ignore mount flv stream for disabled");  
819 - return ret;  
820 - } 833 + // the id to identify stream.
  834 + std::string sid = r->get_stream_url();
  835 + SrsLiveEntry* entry = NULL;
821 836
822 - SrsLiveEntry* entry = flvs[r->vhost]; 837 + // create stream from template when not found.
  838 + if (sflvs.find(sid) == sflvs.end()) {
  839 + if (tflvs.find(r->vhost) == tflvs.end()) {
  840 + srs_info("ignore mount flv stream for disabled");
  841 + return ret;
  842 + }
823 843
824 - // TODO: FIXME: supports reload.  
825 - if (entry->stream) {  
826 - entry->stream->entry->enabled = true;  
827 - return ret;  
828 - }  
829 -  
830 - std::string mount = entry->mount;  
831 -  
832 - // replace the vhost variable  
833 - mount = srs_string_replace(mount, "[vhost]", r->vhost);  
834 - mount = srs_string_replace(mount, "[app]", r->app);  
835 - mount = srs_string_replace(mount, "[stream]", r->stream); 844 + SrsLiveEntry* tmpl = tflvs[r->vhost];
836 845
837 - // remove the default vhost mount  
838 - mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); 846 + std::string mount = tmpl->mount;
839 847
840 - entry->cache = new SrsStreamCache(s, r);  
841 - entry->stream = new SrsLiveStream(s, r, entry->cache); 848 + // replace the vhost variable
  849 + mount = srs_string_replace(mount, "[vhost]", r->vhost);
  850 + mount = srs_string_replace(mount, "[app]", r->app);
  851 + mount = srs_string_replace(mount, "[stream]", r->stream);
842 852
843 - // start http stream cache thread  
844 - if ((ret = entry->cache->start()) != ERROR_SUCCESS) {  
845 - srs_error("http: start stream cache failed. ret=%d", ret);  
846 - return ret; 853 + // remove the default vhost mount
  854 + mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
  855 +
  856 + entry = new SrsLiveEntry();
  857 + entry->mount = mount;
  858 +
  859 + entry->cache = new SrsStreamCache(s, r);
  860 + entry->stream = new SrsLiveStream(s, r, entry->cache);
  861 +
  862 + sflvs[sid] = entry;
  863 +
  864 + // start http stream cache thread
  865 + if ((ret = entry->cache->start()) != ERROR_SUCCESS) {
  866 + srs_error("http: start stream cache failed. ret=%d", ret);
  867 + return ret;
  868 + }
  869 +
  870 + // mount the http flv stream.
  871 + if ((ret = mux.handle(mount, entry->stream)) != ERROR_SUCCESS) {
  872 + srs_error("http: mount flv stream for vhost=%s failed. ret=%d", sid.c_str(), ret);
  873 + return ret;
  874 + }
  875 + srs_trace("http: mount flv stream for vhost=%s, mount=%s", sid.c_str(), mount.c_str());
  876 + } else {
  877 + entry = sflvs[sid];
847 } 878 }
848 879
849 - // mount the http flv stream.  
850 - if ((ret = mux.handle(mount, entry->stream)) != ERROR_SUCCESS) {  
851 - srs_error("http: mount flv stream for vhost=%s failed. ret=%d", r->vhost.c_str(), ret); 880 + // TODO: FIXME: supports reload.
  881 + if (entry->stream) {
  882 + entry->stream->entry->enabled = true;
852 return ret; 883 return ret;
853 } 884 }
854 - srs_trace("http: mount flv stream for vhost=%s, mount=%s", r->vhost.c_str(), mount.c_str());  
855 885
856 return ret; 886 return ret;
857 } 887 }
858 888
859 void SrsHttpServer::unmount(SrsSource* s, SrsRequest* r) 889 void SrsHttpServer::unmount(SrsSource* s, SrsRequest* r)
860 { 890 {
861 - if (flvs.find(r->vhost) == flvs.end()) { 891 + std::string sid = r->get_stream_url();
  892 +
  893 + if (sflvs.find(sid) == sflvs.end()) {
862 srs_info("ignore unmount flv stream for disabled"); 894 srs_info("ignore unmount flv stream for disabled");
863 return; 895 return;
864 } 896 }
865 897
866 - SrsLiveEntry* entry = flvs[r->vhost]; 898 + SrsLiveEntry* entry = sflvs[sid];
867 entry->stream->entry->enabled = false; 899 entry->stream->entry->enabled = false;
868 } 900 }
869 901
@@ -871,12 +903,14 @@ int SrsHttpServer::mount_hls(SrsRequest* r) @@ -871,12 +903,14 @@ int SrsHttpServer::mount_hls(SrsRequest* r)
871 { 903 {
872 int ret = ERROR_SUCCESS; 904 int ret = ERROR_SUCCESS;
873 905
874 - if (hls.find(r->vhost) == hls.end()) { 906 + std::string sid = r->get_stream_url();
  907 +
  908 + if (shls.find(sid) == shls.end()) {
875 srs_info("ignore mount hls stream for disabled"); 909 srs_info("ignore mount hls stream for disabled");
876 return ret; 910 return ret;
877 } 911 }
878 912
879 - SrsHlsEntry* entry = hls[r->vhost]; 913 + SrsHlsEntry* entry = shls[sid];
880 914
881 // TODO: FIXME: supports reload. 915 // TODO: FIXME: supports reload.
882 std::map<std::string, ISrsHttpHandler*>::iterator it; 916 std::map<std::string, ISrsHttpHandler*>::iterator it;
@@ -891,33 +925,37 @@ int SrsHttpServer::mount_hls(SrsRequest* r) @@ -891,33 +925,37 @@ int SrsHttpServer::mount_hls(SrsRequest* r)
891 int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8) 925 int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8)
892 { 926 {
893 int ret = ERROR_SUCCESS; 927 int ret = ERROR_SUCCESS;
  928 +
  929 + std::string mount = m3u8;
894 930
895 - // when no hls mounted, ignore.  
896 - if (hls.find(r->vhost) == hls.end()) {  
897 - return ret;  
898 - } 931 + std::string sid = r->get_stream_url();
  932 + SrsHlsEntry* entry = NULL;
899 933
900 - SrsHlsEntry* entry = hls[r->vhost];  
901 - srs_assert(entry);  
902 -  
903 - std::string mount = entry->mount;  
904 -  
905 - // replace the vhost variable  
906 - mount = srs_string_replace(mount, "[vhost]", r->vhost);  
907 - mount = srs_string_replace(mount, "[app]", r->app);  
908 - mount = srs_string_replace(mount, "[stream]", r->stream);  
909 -  
910 - // remove the default vhost mount  
911 - mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");  
912 -  
913 - if (entry->streams.find(mount) == entry->streams.end()) {  
914 - ISrsHttpHandler* he = new SrsHlsM3u8Stream();  
915 - entry->streams[mount] = he;  
916 -  
917 - if ((ret = mux.handle(mount, he)) != ERROR_SUCCESS) {  
918 - srs_error("handle mount=%s failed. ret=%d", mount.c_str(), ret); 934 + // create stream from template when not found.
  935 + if (shls.find(sid) == shls.end()) {
  936 + if (thls.find(r->vhost) == thls.end()) {
  937 + srs_info("ignore mount hls stream for disabled");
919 return ret; 938 return ret;
920 } 939 }
  940 +
  941 + SrsHlsEntry* tmpl = thls[r->vhost];
  942 +
  943 + entry = new SrsHlsEntry();
  944 + entry->mount = tmpl->mount;
  945 +
  946 + shls[sid] = entry;
  947 +
  948 + if (entry->streams.find(mount) == entry->streams.end()) {
  949 + ISrsHttpHandler* he = new SrsHlsM3u8Stream();
  950 + entry->streams[mount] = he;
  951 +
  952 + if ((ret = mux.handle(mount, he)) != ERROR_SUCCESS) {
  953 + srs_error("handle mount=%s failed. ret=%d", mount.c_str(), ret);
  954 + return ret;
  955 + }
  956 + }
  957 + } else {
  958 + entry = shls[sid];
921 } 959 }
922 960
923 // update the m3u8 stream. 961 // update the m3u8 stream.
@@ -934,12 +972,14 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts) @@ -934,12 +972,14 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
934 { 972 {
935 int ret = ERROR_SUCCESS; 973 int ret = ERROR_SUCCESS;
936 974
  975 + std::string sid = r->get_stream_url();
  976 +
937 // when no hls mounted, ignore. 977 // when no hls mounted, ignore.
938 - if (hls.find(r->vhost) == hls.end()) { 978 + if (shls.find(sid) == shls.end()) {
939 return ret; 979 return ret;
940 } 980 }
941 981
942 - SrsHlsEntry* entry = hls[r->vhost]; 982 + SrsHlsEntry* entry = shls[sid];
943 srs_assert(entry); 983 srs_assert(entry);
944 984
945 std::string mount = entry->mount; 985 std::string mount = entry->mount;
@@ -983,12 +1023,14 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts) @@ -983,12 +1023,14 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
983 1023
984 void SrsHttpServer::unmount_hls(SrsRequest* r) 1024 void SrsHttpServer::unmount_hls(SrsRequest* r)
985 { 1025 {
986 - if (hls.find(r->vhost) == hls.end()) { 1026 + std::string sid = r->get_stream_url();
  1027 +
  1028 + if (shls.find(sid) == shls.end()) {
987 srs_info("ignore unmount hls stream for disabled"); 1029 srs_info("ignore unmount hls stream for disabled");
988 return; 1030 return;
989 } 1031 }
990 1032
991 - SrsHlsEntry* entry = hls[r->vhost]; 1033 + SrsHlsEntry* entry = shls[sid];
992 1034
993 std::map<std::string, ISrsHttpHandler*>::iterator it; 1035 std::map<std::string, ISrsHttpHandler*>::iterator it;
994 for (it = entry->streams.begin(); it != entry->streams.end(); ++it) { 1036 for (it = entry->streams.begin(); it != entry->streams.end(); ++it) {
@@ -1097,9 +1139,8 @@ int SrsHttpServer::initialize_flv_streaming() @@ -1097,9 +1139,8 @@ int SrsHttpServer::initialize_flv_streaming()
1097 } 1139 }
1098 1140
1099 SrsLiveEntry* entry = new SrsLiveEntry(); 1141 SrsLiveEntry* entry = new SrsLiveEntry();
1100 - entry->vhost = vhost;  
1101 entry->mount = _srs_config->get_vhost_http_remux_mount(vhost); 1142 entry->mount = _srs_config->get_vhost_http_remux_mount(vhost);
1102 - flvs[vhost] = entry; 1143 + tflvs[vhost] = entry;
1103 srs_trace("http flv live stream, vhost=%s, mount=%s", 1144 srs_trace("http flv live stream, vhost=%s, mount=%s",
1104 vhost.c_str(), entry->mount.c_str()); 1145 vhost.c_str(), entry->mount.c_str());
1105 } 1146 }
@@ -1131,9 +1172,8 @@ int SrsHttpServer::initialize_hls_streaming() @@ -1131,9 +1172,8 @@ int SrsHttpServer::initialize_hls_streaming()
1131 } 1172 }
1132 1173
1133 SrsHlsEntry* entry = new SrsHlsEntry(); 1174 SrsHlsEntry* entry = new SrsHlsEntry();
1134 - entry->vhost = vhost;  
1135 entry->mount = _srs_config->get_hls_mount(vhost); 1175 entry->mount = _srs_config->get_hls_mount(vhost);
1136 - hls[vhost] = entry; 1176 + thls[vhost] = entry;
1137 srs_trace("http hls live stream, vhost=%s, mount=%s", 1177 srs_trace("http hls live stream, vhost=%s, mount=%s",
1138 vhost.c_str(), entry->mount.c_str()); 1178 vhost.c_str(), entry->mount.c_str());
1139 } 1179 }
@@ -252,8 +252,10 @@ private: @@ -252,8 +252,10 @@ private:
252 */ 252 */
253 struct SrsLiveEntry 253 struct SrsLiveEntry
254 { 254 {
255 - std::string vhost; 255 + // for template, the mount contains variables.
  256 + // for concrete stream, the mount is url to access.
256 std::string mount; 257 std::string mount;
  258 +
257 SrsLiveStream* stream; 259 SrsLiveStream* stream;
258 SrsStreamCache* cache; 260 SrsStreamCache* cache;
259 261
@@ -297,7 +299,8 @@ public: @@ -297,7 +299,8 @@ public:
297 */ 299 */
298 struct SrsHlsEntry 300 struct SrsHlsEntry
299 { 301 {
300 - std::string vhost; 302 + // for template, the mount contains variables.
  303 + // for concrete stream, the mount is url to access.
301 std::string mount; 304 std::string mount;
302 305
303 // key: the m3u8/ts file path. 306 // key: the m3u8/ts file path.
@@ -315,10 +318,14 @@ class SrsHttpServer : public ISrsReloadHandler @@ -315,10 +318,14 @@ class SrsHttpServer : public ISrsReloadHandler
315 { 318 {
316 public: 319 public:
317 SrsHttpServeMux mux; 320 SrsHttpServeMux mux;
318 - // the flv live streaming template.  
319 - std::map<std::string, SrsLiveEntry*> flvs;  
320 - // the hls live streaming template.  
321 - std::map<std::string, SrsHlsEntry*> hls; 321 + // the flv live streaming template, to create streams.
  322 + std::map<std::string, SrsLiveEntry*> tflvs;
  323 + // the flv live streaming streams, crote by template.
  324 + std::map<std::string, SrsLiveEntry*> sflvs;
  325 + // the hls live streaming template, to create streams.
  326 + std::map<std::string, SrsHlsEntry*> thls;
  327 + // the hls live streaming streams, crote by template.
  328 + std::map<std::string, SrsHlsEntry*> shls;
322 public: 329 public:
323 SrsHttpServer(); 330 SrsHttpServer();
324 virtual ~SrsHttpServer(); 331 virtual ~SrsHttpServer();
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 132 34 +#define VERSION_REVISION 133
35 35
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"