diff --git a/README.md b/README.md
index 1ea4288fc..fcbac90fc 100755
--- a/README.md
+++ b/README.md
@@ -116,6 +116,7 @@ cd simple-rtmp-server/trunk
See also:
* Usage: How to delivery RTMP?([CN][v1_CN_SampleRTMP], [EN][v1_EN_SampleRTMP])
+* Usage: How to delivery RTMP Cluster?([CN][v1_CN_SampleRTMPCluster], [EN][v1_EN_SampleRTMPCluster])
* Usage: How to delivery HTTP FLV Live Streaming?([CN][v2_CN_SampleHttpFlv], [EN][v2_EN_SampleHttpFlv])
* Usage: How to delivery HTTP FLV Live Streaming Cluster?([CN][v2_CN_SampleHttpFlvCluster], [EN][v2_EN_SampleHttpFlvCluster])
* Usage: How to delivery HLS?([CN][v1_CN_SampleHLS], [EN][v1_EN_SampleHLS])
@@ -343,6 +344,7 @@ Remark:
### SRS 2.0 history
+* v2.0, 2015-05-24, fix [#404](https://github.com/simple-rtmp-server/srs/issues/404) register handler then start http thread. 2.0.167.
* v2.0, 2015-05-23, refine the thread, protocol, kbps code. 2.0.166
* v2.0, 2015-05-23, fix [#391](https://github.com/simple-rtmp-server/srs/issues/391) copy request for async call.
* v2.0, 2015-05-22, fix [#397](https://github.com/simple-rtmp-server/srs/issues/397) the USER_HZ maybe not 100. 2.0.165
@@ -843,6 +845,8 @@ Winlin
[v1_EN_Git]: https://github.com/simple-rtmp-server/srs/wiki/v1_EN_Git
[v1_CN_SampleRTMP]: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_SampleRTMP
[v1_EN_SampleRTMP]: https://github.com/simple-rtmp-server/srs/wiki/v1_EN_SampleRTMP
+[v1_CN_SampleRTMPCluster]: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_SampleRTMPCluster
+[v1_EN_SampleRTMPCluster]: https://github.com/simple-rtmp-server/srs/wiki/v1_EN_SampleRTMPCluster
[v1_CN_SampleHLS]: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_SampleHLS
[v1_EN_SampleHLS]: https://github.com/simple-rtmp-server/srs/wiki/v1_EN_SampleHLS
[v1_CN_SampleTranscode2HLS]: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_SampleTranscode2HLS
diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh
index b068d28f2..0fde6acb9 100644
--- a/trunk/auto/depends.sh
+++ b/trunk/auto/depends.sh
@@ -504,11 +504,7 @@ if [ $__SRS_BUILD_NGINX = YES ]; then
# srs will write ts/m3u8 file use current user,
# nginx default use nobody, so cannot read the ts/m3u8 created by srs.
cp ${SRS_OBJS}/nginx/conf/nginx.conf ${SRS_OBJS}/nginx/conf/nginx.conf.bk
- if [ $OS_IS_OSX = YES ]; then
- sed -i '' "s/^.user nobody;/user `whoami`;/g" ${SRS_OBJS}/nginx/conf/nginx.conf
- else
- sed -i "s/^.user nobody;/user `whoami`;/g" ${SRS_OBJS}/nginx/conf/nginx.conf
- fi
+ $SED '' "s/^.user nobody;/user `whoami`;/g" ${SRS_OBJS}/nginx/conf/nginx.conf
fi
# the demo dir.
diff --git a/trunk/auto/generate-srs-librtmp-single.sh b/trunk/auto/generate-srs-librtmp-single.sh
index 3ca5dee79..ce03b8f33 100755
--- a/trunk/auto/generate-srs-librtmp-single.sh
+++ b/trunk/auto/generate-srs-librtmp-single.sh
@@ -1,5 +1,16 @@
#!/bin/bash
+OS_IS_OSX=NO
+uname -s|grep Darwin >/dev/null 2>&1
+ret=$?; if [[ 0 -eq $ret ]]; then
+ OS_IS_OSX=YES
+fi
+echo "Is OSX: ${OS_IS_OSX}"
+
+# the sed command
+SED="sed -i"
+if [ $OS_IS_OSX = YES ]; then SED="sed -i ''"; fi
+
# when export srs-librtmp single files
# package the whole project to srs_librtmp.h and srs_librtmp.cpp
#
@@ -59,7 +70,7 @@ function build_module_hpp()
for item in ${SRS_LIBRTMP_OBJS[*]}; do
FILE_NAME="${item%.*}"
echo "// following is generated by ${FILE_NAME}.hpp" >> $FILE &&
- sed -i "s|#include >$FILE
ret=$?; if [[ $ret -ne 0 ]]; then
echo -e "${RED}failed to generate the srs_librtmp.cpp by ${FILE_NAME}.hpp. {${BLACK}"
@@ -78,7 +89,7 @@ function build_module_cpp()
for item in ${SRS_LIBRTMP_OBJS[*]}; do
FILE_NAME="${item%.*}"
echo "// following is generated by ${FILE_NAME}.cpp" >> $FILE &&
- sed -i "s|#include >$FILE
ret=$?; if [[ $ret -ne 0 ]]; then
echo -e "${RED}failed to generate the srs_librtmp.cpp by ${FILE_NAME}.cpp. {${BLACK}"
diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp
index 80f2cb02e..0654ac362 100644
--- a/trunk/src/app/srs_app_http_conn.cpp
+++ b/trunk/src/app/srs_app_http_conn.cpp
@@ -1854,17 +1854,20 @@ int SrsHttpServer::http_mount(SrsSource* s, SrsRequest* r)
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.
+ // we must register the handler, then start the thread,
+ // for the thread will cause thread switch context.
+ // @see https://github.com/simple-rtmp-server/srs/issues/404
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;
}
+
+ // start http stream cache thread
+ if ((ret = entry->cache->start()) != ERROR_SUCCESS) {
+ srs_error("http: start stream cache failed. ret=%d", ret);
+ return ret;
+ }
srs_trace("http: mount flv stream for vhost=%s, mount=%s", sid.c_str(), mount.c_str());
} else {
entry = sflvs[sid];
diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp
index 5634db625..cdea9cd59 100644
--- a/trunk/src/app/srs_app_server.cpp
+++ b/trunk/src/app/srs_app_server.cpp
@@ -786,6 +786,13 @@ int SrsServer::http_handle()
return ret;
}
#endif
+
+#ifdef SRS_AUTO_HTTP_SERVER
+ // for SRS go-sharp to detect the status of HTTP server of SRS HTTP FLV Cluster.
+ if ((ret = http_stream_mux->mux.handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) {
+ return ret;
+ }
+#endif
return ret;
}
diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp
index 8a29c6c76..725a4401d 100644
--- a/trunk/src/kernel/srs_kernel_flv.cpp
+++ b/trunk/src/kernel/srs_kernel_flv.cpp
@@ -134,7 +134,9 @@ int SrsFlvEncoder::write_metadata(char type, char* data, int size)
tag_stream->write_3bytes(size);
if ((ret = write_tag(tag_header, sizeof(tag_header), data, size)) != ERROR_SUCCESS) {
- srs_error("write flv data tag failed. ret=%d", ret);
+ if (!srs_is_client_gracefully_close(ret)) {
+ srs_error("write flv data tag failed. ret=%d", ret);
+ }
return ret;
}
@@ -168,7 +170,9 @@ int SrsFlvEncoder::write_audio(int64_t timestamp, char* data, int size)
tag_stream->write_1bytes((timestamp >> 24) & 0xFF);
if ((ret = write_tag(tag_header, sizeof(tag_header), data, size)) != ERROR_SUCCESS) {
- srs_error("write flv audio tag failed. ret=%d", ret);
+ if (!srs_is_client_gracefully_close(ret)) {
+ srs_error("write flv audio tag failed. ret=%d", ret);
+ }
return ret;
}
@@ -221,13 +225,17 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s
// write tag header.
if ((ret = _fs->write(header, header_size, NULL)) != ERROR_SUCCESS) {
- srs_error("write flv tag header failed. ret=%d", ret);
+ if (!srs_is_client_gracefully_close(ret)) {
+ srs_error("write flv tag header failed. ret=%d", ret);
+ }
return ret;
}
// write tag data.
if ((ret = _fs->write(tag, tag_size, NULL)) != ERROR_SUCCESS) {
- srs_error("write flv tag failed. ret=%d", ret);
+ if (!srs_is_client_gracefully_close(ret)) {
+ srs_error("write flv tag failed. ret=%d", ret);
+ }
return ret;
}
@@ -238,7 +246,9 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s
}
tag_stream->write_4bytes(tag_size + header_size);
if ((ret = _fs->write(pre_size, sizeof(pre_size), NULL)) != ERROR_SUCCESS) {
- srs_error("write flv previous tag size failed. ret=%d", ret);
+ if (!srs_is_client_gracefully_close(ret)) {
+ srs_error("write flv previous tag size failed. ret=%d", ret);
+ }
return ret;
}