1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

Merge branch '2.0release' into develop

This commit is contained in:
winlin 2015-08-21 17:15:42 +08:00
commit 0a4d78383c
18 changed files with 434 additions and 178 deletions

4
trunk/configure vendored
View file

@ -159,7 +159,7 @@ MODULE_DEPENDS=("CORE" "KERNEL")
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot}) ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack"
"srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_protocol_buffer" "srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_protocol_buffer"
"srs_raw_avc" "srs_rtsp_stack" "srs_http_stack" "srs_protocol_kbps") "srs_raw_avc" "srs_rtsp_stack" "srs_http_stack" "srs_protocol_kbps" "srs_protocol_json")
PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh
PROTOCOL_OBJS="${MODULE_OBJS[@]}" PROTOCOL_OBJS="${MODULE_OBJS[@]}"
# #
@ -172,7 +172,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
"srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream"
"srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config"
"srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
"srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
"srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static"
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds" "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
"srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call"

View file

@ -58,6 +58,8 @@ file
../../src/protocol/srs_rtmp_amf0.cpp, ../../src/protocol/srs_rtmp_amf0.cpp,
../../src/protocol/srs_protocol_buffer.hpp, ../../src/protocol/srs_protocol_buffer.hpp,
../../src/protocol/srs_protocol_buffer.cpp, ../../src/protocol/srs_protocol_buffer.cpp,
../../src/protocol/srs_protocol_json.hpp,
../../src/protocol/srs_protocol_json.cpp,
../../src/protocol/srs_rtmp_handshake.hpp, ../../src/protocol/srs_rtmp_handshake.hpp,
../../src/protocol/srs_rtmp_handshake.cpp, ../../src/protocol/srs_rtmp_handshake.cpp,
../../src/protocol/srs_rtmp_io.hpp, ../../src/protocol/srs_rtmp_io.hpp,
@ -109,8 +111,6 @@ file
../../src/app/srs_app_http_static.cpp, ../../src/app/srs_app_http_static.cpp,
../../src/app/srs_app_ingest.hpp, ../../src/app/srs_app_ingest.hpp,
../../src/app/srs_app_ingest.cpp, ../../src/app/srs_app_ingest.cpp,
../../src/app/srs_app_json.hpp,
../../src/app/srs_app_json.cpp,
../../src/app/srs_app_listener.hpp, ../../src/app/srs_app_listener.hpp,
../../src/app/srs_app_listener.cpp, ../../src/app/srs_app_listener.cpp,
../../src/app/srs_app_log.hpp, ../../src/app/srs_app_log.hpp,

View file

@ -11,6 +11,7 @@
3C036B561B2D0AC10078E2E0 /* srs_app_http_stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C036B531B2D0AC10078E2E0 /* srs_app_http_stream.cpp */; }; 3C036B561B2D0AC10078E2E0 /* srs_app_http_stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C036B531B2D0AC10078E2E0 /* srs_app_http_stream.cpp */; };
3C068D6A1B10149F00AA722C /* srs_protocol_kbps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C068D681B10149F00AA722C /* srs_protocol_kbps.cpp */; }; 3C068D6A1B10149F00AA722C /* srs_protocol_kbps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C068D681B10149F00AA722C /* srs_protocol_kbps.cpp */; };
3C068D6D1B10175500AA722C /* srs_protocol_buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */; }; 3C068D6D1B10175500AA722C /* srs_protocol_buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */; };
3C0D422E1B87165900C2508B /* srs_protocol_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D422C1B87165900C2508B /* srs_protocol_json.cpp */; };
3C0E1B8D1B0F5ADF003ADEF7 /* srs_http_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */; }; 3C0E1B8D1B0F5ADF003ADEF7 /* srs_http_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */; };
3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */; }; 3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */; };
3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */; }; 3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */; };
@ -52,7 +53,6 @@
3C1232A11AAE81D900CE8F6C /* srs_app_http_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */; }; 3C1232A11AAE81D900CE8F6C /* srs_app_http_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */; };
3C1232A21AAE81D900CE8F6C /* srs_app_http_hooks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */; }; 3C1232A21AAE81D900CE8F6C /* srs_app_http_hooks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */; };
3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */; }; 3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */; };
3C1232A51AAE81D900CE8F6C /* srs_app_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */; };
3C1232A71AAE81D900CE8F6C /* srs_app_listener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */; }; 3C1232A71AAE81D900CE8F6C /* srs_app_listener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */; };
3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */; }; 3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */; };
3C1232A91AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232761AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp */; }; 3C1232A91AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232761AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp */; };
@ -131,6 +131,8 @@
3C068D691B10149F00AA722C /* srs_protocol_kbps.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_kbps.hpp; path = ../../../src/protocol/srs_protocol_kbps.hpp; sourceTree = "<group>"; }; 3C068D691B10149F00AA722C /* srs_protocol_kbps.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_kbps.hpp; path = ../../../src/protocol/srs_protocol_kbps.hpp; sourceTree = "<group>"; };
3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_protocol_buffer.cpp; path = ../../../src/protocol/srs_protocol_buffer.cpp; sourceTree = "<group>"; }; 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_protocol_buffer.cpp; path = ../../../src/protocol/srs_protocol_buffer.cpp; sourceTree = "<group>"; };
3C068D6C1B10175500AA722C /* srs_protocol_buffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_buffer.hpp; path = ../../../src/protocol/srs_protocol_buffer.hpp; sourceTree = "<group>"; }; 3C068D6C1B10175500AA722C /* srs_protocol_buffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_buffer.hpp; path = ../../../src/protocol/srs_protocol_buffer.hpp; sourceTree = "<group>"; };
3C0D422C1B87165900C2508B /* srs_protocol_json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_protocol_json.cpp; path = ../../../src/protocol/srs_protocol_json.cpp; sourceTree = "<group>"; };
3C0D422D1B87165900C2508B /* srs_protocol_json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_json.hpp; path = ../../../src/protocol/srs_protocol_json.hpp; sourceTree = "<group>"; };
3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_http_stack.cpp; path = ../../../src/protocol/srs_http_stack.cpp; sourceTree = "<group>"; }; 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_http_stack.cpp; path = ../../../src/protocol/srs_http_stack.cpp; sourceTree = "<group>"; };
3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_http_stack.hpp; path = ../../../src/protocol/srs_http_stack.hpp; sourceTree = "<group>"; }; 3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_http_stack.hpp; path = ../../../src/protocol/srs_http_stack.hpp; sourceTree = "<group>"; };
3C1231E51AAE64A400CE8F6C /* srs_xcode */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = srs_xcode; sourceTree = BUILT_PRODUCTS_DIR; }; 3C1231E51AAE64A400CE8F6C /* srs_xcode */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = srs_xcode; sourceTree = BUILT_PRODUCTS_DIR; };
@ -214,8 +216,6 @@
3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_hooks.hpp; path = ../../../src/app/srs_app_http_hooks.hpp; sourceTree = "<group>"; }; 3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_hooks.hpp; path = ../../../src/app/srs_app_http_hooks.hpp; sourceTree = "<group>"; };
3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_ingest.cpp; path = ../../../src/app/srs_app_ingest.cpp; sourceTree = "<group>"; }; 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_ingest.cpp; path = ../../../src/app/srs_app_ingest.cpp; sourceTree = "<group>"; };
3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_ingest.hpp; path = ../../../src/app/srs_app_ingest.hpp; sourceTree = "<group>"; }; 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_ingest.hpp; path = ../../../src/app/srs_app_ingest.hpp; sourceTree = "<group>"; };
3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_json.cpp; path = ../../../src/app/srs_app_json.cpp; sourceTree = "<group>"; };
3C12326F1AAE81D900CE8F6C /* srs_app_json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_json.hpp; path = ../../../src/app/srs_app_json.hpp; sourceTree = "<group>"; };
3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_listener.cpp; path = ../../../src/app/srs_app_listener.cpp; sourceTree = "<group>"; }; 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_listener.cpp; path = ../../../src/app/srs_app_listener.cpp; sourceTree = "<group>"; };
3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_listener.hpp; path = ../../../src/app/srs_app_listener.hpp; sourceTree = "<group>"; }; 3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_listener.hpp; path = ../../../src/app/srs_app_listener.hpp; sourceTree = "<group>"; };
3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_log.cpp; path = ../../../src/app/srs_app_log.cpp; sourceTree = "<group>"; }; 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_log.cpp; path = ../../../src/app/srs_app_log.cpp; sourceTree = "<group>"; };
@ -496,6 +496,8 @@
3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */, 3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */,
3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */, 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */,
3C068D6C1B10175500AA722C /* srs_protocol_buffer.hpp */, 3C068D6C1B10175500AA722C /* srs_protocol_buffer.hpp */,
3C0D422C1B87165900C2508B /* srs_protocol_json.cpp */,
3C0D422D1B87165900C2508B /* srs_protocol_json.hpp */,
3C068D681B10149F00AA722C /* srs_protocol_kbps.cpp */, 3C068D681B10149F00AA722C /* srs_protocol_kbps.cpp */,
3C068D691B10149F00AA722C /* srs_protocol_kbps.hpp */, 3C068D691B10149F00AA722C /* srs_protocol_kbps.hpp */,
3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */, 3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */,
@ -563,8 +565,6 @@
3C036B541B2D0AC10078E2E0 /* srs_app_http_stream.hpp */, 3C036B541B2D0AC10078E2E0 /* srs_app_http_stream.hpp */,
3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */, 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */,
3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */, 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */,
3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */,
3C12326F1AAE81D900CE8F6C /* srs_app_json.hpp */,
3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */, 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */,
3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */, 3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */,
3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */, 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */,
@ -862,12 +862,12 @@
3C689F961AB6AAAC00C9CEEE /* event.c in Sources */, 3C689F961AB6AAAC00C9CEEE /* event.c in Sources */,
3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */, 3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */,
3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */, 3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */,
3C0D422E1B87165900C2508B /* srs_protocol_json.cpp in Sources */,
3C1232B41AAE81D900CE8F6C /* srs_app_st.cpp in Sources */, 3C1232B41AAE81D900CE8F6C /* srs_app_st.cpp in Sources */,
3C1232481AAE81A400CE8F6C /* srs_rtmp_stack.cpp in Sources */, 3C1232481AAE81A400CE8F6C /* srs_rtmp_stack.cpp in Sources */,
3C1232B01AAE81D900CE8F6C /* srs_app_security.cpp in Sources */, 3C1232B01AAE81D900CE8F6C /* srs_app_security.cpp in Sources */,
3C12322B1AAE814D00CE8F6C /* srs_kernel_utility.cpp in Sources */, 3C12322B1AAE814D00CE8F6C /* srs_kernel_utility.cpp in Sources */,
3C12324A1AAE81A400CE8F6C /* srs_rtsp_stack.cpp in Sources */, 3C12324A1AAE81A400CE8F6C /* srs_rtsp_stack.cpp in Sources */,
3C1232A51AAE81D900CE8F6C /* srs_app_json.cpp in Sources */,
3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */, 3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */,
3C12329F1AAE81D900CE8F6C /* srs_app_http_api.cpp in Sources */, 3C12329F1AAE81D900CE8F6C /* srs_app_http_api.cpp in Sources */,
3C1EE6AE1AB1055800576EE9 /* srs_app_hds.cpp in Sources */, 3C1EE6AE1AB1055800576EE9 /* srs_app_hds.cpp in Sources */,

View file

@ -40,7 +40,7 @@ using namespace std;
#include <srs_kernel_file.hpp> #include <srs_kernel_file.hpp>
#include <srs_rtmp_amf0.hpp> #include <srs_rtmp_amf0.hpp>
#include <srs_kernel_stream.hpp> #include <srs_kernel_stream.hpp>
#include <srs_app_json.hpp> #include <srs_protocol_json.hpp>
#include <srs_app_utility.hpp> #include <srs_app_utility.hpp>
// update the flv duration and filesize every this interval in ms. // update the flv duration and filesize every this interval in ms.

View file

@ -32,7 +32,7 @@ using namespace std;
#include <srs_kernel_log.hpp> #include <srs_kernel_log.hpp>
#include <srs_app_config.hpp> #include <srs_app_config.hpp>
#include <srs_app_http_client.hpp> #include <srs_app_http_client.hpp>
#include <srs_app_json.hpp> #include <srs_protocol_json.hpp>
#include <srs_app_utility.hpp> #include <srs_app_utility.hpp>
#include <srs_core_autofree.hpp> #include <srs_core_autofree.hpp>
#include <srs_app_http_conn.hpp> #include <srs_app_http_conn.hpp>

View file

@ -33,7 +33,7 @@ using namespace std;
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
#include <srs_app_st.hpp> #include <srs_app_st.hpp>
#include <srs_core_autofree.hpp> #include <srs_core_autofree.hpp>
#include <srs_app_json.hpp> #include <srs_protocol_json.hpp>
#include <srs_kernel_utility.hpp> #include <srs_kernel_utility.hpp>
#include <srs_app_utility.hpp> #include <srs_app_utility.hpp>
#include <srs_app_statistic.hpp> #include <srs_app_statistic.hpp>
@ -112,6 +112,7 @@ int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JFIELD_STR("requests", "the request itself, for http debug") << SRS_JFIELD_CONT << SRS_JFIELD_STR("requests", "the request itself, for http debug") << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("vhosts", "dumps vhost to json") << SRS_JFIELD_CONT << SRS_JFIELD_STR("vhosts", "dumps vhost to json") << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("streams", "dumps streams to json") << SRS_JFIELD_CONT << SRS_JFIELD_STR("streams", "dumps streams to json") << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("clients", "dumps clients to json") << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("test", SRS_JOBJECT_START) << SRS_JFIELD_ORG("test", SRS_JOBJECT_START)
<< SRS_JFIELD_STR("requests", "show the request info") << SRS_JFIELD_CONT << SRS_JFIELD_STR("requests", "show the request info") << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("errors", "always return an error 100") << SRS_JFIELD_CONT << SRS_JFIELD_STR("errors", "always return an error 100") << SRS_JFIELD_CONT
@ -442,17 +443,45 @@ SrsGoApiVhosts::~SrsGoApiVhosts()
int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
std::stringstream data; int ret = ERROR_SUCCESS;
SrsStatistic* stat = SrsStatistic::instance();
int ret = stat->dumps_vhosts(data);
SrsStatistic* stat = SrsStatistic::instance();
std::stringstream ss; std::stringstream ss;
ss << SRS_JOBJECT_START // path: {pattern}{vhost_id}
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT // e.g. /api/v1/vhosts/100 pattern= /api/v1/vhosts/, vhost_id=100
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT int vid = r->parse_rest_id(entry->pattern);
<< SRS_JFIELD_ORG("vhosts", data.str()) SrsStatisticVhost* vhost = NULL;
<< SRS_JOBJECT_END;
if (vid > 0 && (vhost = stat->find_vhost(vid)) == NULL) {
ret = ERROR_RTMP_STREAM_NOT_FOUND;
srs_error("vhost id=%d not found. ret=%d", vid, ret);
return srs_http_response_code(w, ret);
}
if (r->is_http_get()) {
std::stringstream data;
if (!vhost) {
ret = stat->dumps_vhosts(data);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("vhosts", data.str())
<< SRS_JOBJECT_END;
} else {
ret = vhost->dumps(data);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("vhost", data.str())
<< SRS_JOBJECT_END;
}
return srs_http_response_json(w, ss.str());
}
return srs_http_response_json(w, ss.str()); return srs_http_response_json(w, ss.str());
} }
@ -468,63 +497,114 @@ SrsGoApiStreams::~SrsGoApiStreams()
int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsStatistic* stat = SrsStatistic::instance(); SrsStatistic* stat = SrsStatistic::instance();
std::stringstream ss; std::stringstream ss;
// path: {pattern}{stream_id}
// e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100
int sid = r->parse_rest_id(entry->pattern);
SrsStatisticStream* stream = NULL;
if (sid >= 0 && (stream = stat->find_stream(sid)) == NULL) {
ret = ERROR_RTMP_STREAM_NOT_FOUND;
srs_error("stream stream_id=%d not found. ret=%d", sid, ret);
return srs_http_response_code(w, ret);
}
if (r->is_http_delete()) { if (r->is_http_delete()) {
// path: {pattern}{stream_id} srs_assert(stream);
// e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100
string sid = r->path().substr((int)entry->pattern.length());
if (sid.empty()) {
ret = ERROR_REQUEST_DATA;
srs_error("invalid param, stream_id=%s. ret=%d", sid.c_str(), ret);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret)
<< SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str());
}
int stream_id = ::atoi(sid.c_str());
SrsStatisticStream* stream = stat->find_stream(stream_id);
if (stream == NULL) {
ret = ERROR_RTMP_STREAM_NOT_FOUND;
srs_error("stream stream_id=%s not found. ret=%d", sid.c_str(), ret);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret)
<< SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str());
}
SrsSource* source = SrsSource::fetch(stream->vhost->vhost, stream->app, stream->stream);
if (source) {
source->set_expired();
srs_warn("disconnent stream=%d successfully. vhost=%s, app=%s, stream=%s.",
stream_id, stream->vhost->vhost.c_str(), stream->app.c_str(), stream->stream.c_str());
} else {
ret = ERROR_SOURCE_NOT_FOUND;
}
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret)
<< SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str());
} else {
std::stringstream data;
int ret = stat->dumps_streams(data);
ss << SRS_JOBJECT_START SrsSource* source = SrsSource::fetch(stream->vhost->vhost, stream->app, stream->stream);
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT if (!source) {
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT ret = ERROR_SOURCE_NOT_FOUND;
<< SRS_JFIELD_ORG("streams", data.str()) srs_warn("source not found for sid=%d", sid);
<< SRS_JOBJECT_END; return srs_http_response_code(w, ret);
}
source->set_expired();
srs_warn("disconnent stream=%d successfully. vhost=%s, app=%s, stream=%s.",
sid, stream->vhost->vhost.c_str(), stream->app.c_str(), stream->stream.c_str());
return srs_http_response_code(w, ret);
} else if (r->is_http_get()) {
std::stringstream data;
if (!stream) {
ret = stat->dumps_streams(data);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("streams", data.str())
<< SRS_JOBJECT_END;
} else {
ret = stream->dumps(data);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("stream", data.str())
<< SRS_JOBJECT_END;
}
return srs_http_response_json(w, ss.str()); return srs_http_response_json(w, ss.str());
} }
return ret;
}
SrsGoApiClients::SrsGoApiClients()
{
}
SrsGoApiClients::~SrsGoApiClients()
{
}
int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
int ret = ERROR_SUCCESS;
SrsStatistic* stat = SrsStatistic::instance();
std::stringstream ss;
// path: {pattern}{client_id}
// e.g. /api/v1/clients/100 pattern= /api/v1/clients/, client_id=100
int cid = r->parse_rest_id(entry->pattern);
SrsStatisticClient* client = NULL;
if (cid >= 0 && (client = stat->find_client(cid)) == NULL) {
ret = ERROR_RTMP_STREAM_NOT_FOUND;
srs_error("stream client_id=%d not found. ret=%d", cid, ret);
return srs_http_response_code(w, ret);
}
if (r->is_http_get()) {
std::stringstream data;
if (!client) {
ret = stat->dumps_clients(data, 0, 10);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("clients", data.str())
<< SRS_JOBJECT_END;
} else {
ret = client->dumps(data);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("client", data.str())
<< SRS_JOBJECT_END;
}
return srs_http_response_json(w, ss.str());
}
return ret;
} }
SrsGoApiError::SrsGoApiError() SrsGoApiError::SrsGoApiError()
@ -537,15 +617,7 @@ SrsGoApiError::~SrsGoApiError()
int SrsGoApiError::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) int SrsGoApiError::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
std::stringstream ss; return srs_http_response_code(w, 100);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(100) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("msg", "SRS demo error.") << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("path", r->path())
<< SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str());
} }

View file

@ -159,6 +159,15 @@ public:
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
}; };
class SrsGoApiClients : public ISrsHttpHandler
{
public:
SrsGoApiClients();
virtual ~SrsGoApiClients();
public:
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
};
class SrsGoApiError : public ISrsHttpHandler class SrsGoApiError : public ISrsHttpHandler
{ {
public: public:

View file

@ -654,6 +654,7 @@ string SrsHttpMessage::uri()
uri += host(); uri += host();
uri += path(); uri += path();
return uri; return uri;
} }
@ -677,6 +678,21 @@ string SrsHttpMessage::ext()
return _ext; return _ext;
} }
int SrsHttpMessage::parse_rest_id(string pattern)
{
string p = _uri->get_path();
if (p.length() <= pattern.length()) {
return -1;
}
string id = p.substr((int)pattern.length());
if (!id.empty()) {
return ::atoi(id.c_str());
}
return -1;
}
int SrsHttpMessage::body_read_all(string& body) int SrsHttpMessage::body_read_all(string& body)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;

View file

@ -246,6 +246,10 @@ public:
virtual std::string host(); virtual std::string host();
virtual std::string path(); virtual std::string path();
virtual std::string ext(); virtual std::string ext();
/**
* get the RESTful matched id.
*/
virtual int parse_rest_id(std::string pattern);
public: public:
/** /**
* read body to string. * read body to string.

View file

@ -31,7 +31,7 @@ using namespace std;
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
#include <srs_rtmp_stack.hpp> #include <srs_rtmp_stack.hpp>
#include <srs_app_st.hpp> #include <srs_app_st.hpp>
#include <srs_app_json.hpp> #include <srs_protocol_json.hpp>
#include <srs_app_dvr.hpp> #include <srs_app_dvr.hpp>
#include <srs_app_http_client.hpp> #include <srs_app_http_client.hpp>
#include <srs_core_autofree.hpp> #include <srs_core_autofree.hpp>

View file

@ -773,10 +773,10 @@ int SrsServer::http_handle()
if ((ret = http_api_mux->handle("/", new SrsHttpNotFoundHandler())) != ERROR_SUCCESS) { if ((ret = http_api_mux->handle("/", new SrsHttpNotFoundHandler())) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = http_api_mux->handle("/api", new SrsGoApiApi())) != ERROR_SUCCESS) { if ((ret = http_api_mux->handle("/api/", new SrsGoApiApi())) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = http_api_mux->handle("/api/v1", new SrsGoApiV1())) != ERROR_SUCCESS) { if ((ret = http_api_mux->handle("/api/v1/", new SrsGoApiV1())) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = http_api_mux->handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) { if ((ret = http_api_mux->handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) {
@ -800,12 +800,15 @@ int SrsServer::http_handle()
if ((ret = http_api_mux->handle("/api/v1/authors", new SrsGoApiAuthors())) != ERROR_SUCCESS) { if ((ret = http_api_mux->handle("/api/v1/authors", new SrsGoApiAuthors())) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = http_api_mux->handle("/api/v1/vhosts", new SrsGoApiVhosts())) != ERROR_SUCCESS) { if ((ret = http_api_mux->handle("/api/v1/vhosts/", new SrsGoApiVhosts())) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = http_api_mux->handle("/api/v1/streams/", new SrsGoApiStreams())) != ERROR_SUCCESS) { if ((ret = http_api_mux->handle("/api/v1/streams/", new SrsGoApiStreams())) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = http_api_mux->handle("/api/v1/clients/", new SrsGoApiClients())) != ERROR_SUCCESS) {
return ret;
}
// test the request info. // test the request info.
if ((ret = http_api_mux->handle("/api/v1/test/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) { if ((ret = http_api_mux->handle("/api/v1/test/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) {

View file

@ -28,7 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using namespace std; using namespace std;
#include <srs_rtmp_stack.hpp> #include <srs_rtmp_stack.hpp>
#include <srs_app_json.hpp> #include <srs_protocol_json.hpp>
#include <srs_protocol_kbps.hpp> #include <srs_protocol_kbps.hpp>
#include <srs_app_conn.hpp> #include <srs_app_conn.hpp>
#include <srs_app_config.hpp> #include <srs_app_config.hpp>
@ -47,6 +47,8 @@ SrsStatisticVhost::SrsStatisticVhost()
kbps = new SrsKbps(); kbps = new SrsKbps();
kbps->set_io(NULL, NULL); kbps->set_io(NULL, NULL);
nb_clients = 0;
} }
SrsStatisticVhost::~SrsStatisticVhost() SrsStatisticVhost::~SrsStatisticVhost()
@ -54,6 +56,33 @@ SrsStatisticVhost::~SrsStatisticVhost()
srs_freep(kbps); srs_freep(kbps);
} }
int SrsStatisticVhost::dumps(stringstream& ss)
{
int ret = ERROR_SUCCESS;
// dumps the config of vhost.
bool hls_enabled = _srs_config->get_hls_enabled(vhost);
bool enabled = _srs_config->get_vhost_enabled(vhost);
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ORG("id", id) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("name", vhost) << SRS_JFIELD_CONT
<< SRS_JFIELD_BOOL("enabled", enabled) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("clients", nb_clients) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("send_bytes", kbps->get_send_bytes()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("recv_bytes", kbps->get_recv_bytes()) << SRS_JFIELD_CONT
<< SRS_JFIELD_NAME("hls") << SRS_JOBJECT_START
<< SRS_JFIELD_BOOL("enabled", hls_enabled);
if (hls_enabled) {
ss << SRS_JFIELD_CONT;
ss << SRS_JFIELD_ORG("fragment", _srs_config->get_hls_fragment(vhost));
}
ss << SRS_JOBJECT_END
<< SRS_JOBJECT_END;
return ret;
}
SrsStatisticStream::SrsStatisticStream() SrsStatisticStream::SrsStatisticStream()
{ {
id = srs_generate_id(); id = srs_generate_id();
@ -73,6 +102,8 @@ SrsStatisticStream::SrsStatisticStream()
kbps = new SrsKbps(); kbps = new SrsKbps();
kbps->set_io(NULL, NULL); kbps->set_io(NULL, NULL);
nb_clients = 0;
} }
SrsStatisticStream::~SrsStatisticStream() SrsStatisticStream::~SrsStatisticStream()
@ -80,6 +111,48 @@ SrsStatisticStream::~SrsStatisticStream()
srs_freep(kbps); srs_freep(kbps);
} }
int SrsStatisticStream::dumps(stringstream& ss)
{
int ret = ERROR_SUCCESS;
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ORG("id", id) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("name", stream) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("vhost", vhost->id) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("app", app) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("clients", nb_clients) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("send_bytes", kbps->get_send_bytes()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("recv_bytes", kbps->get_recv_bytes()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("live_ms", srs_get_system_time_ms()) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("status", status) << SRS_JFIELD_CONT;
if (!has_video) {
ss << SRS_JFIELD_NULL("video") << SRS_JFIELD_CONT;
} else {
ss << SRS_JFIELD_NAME("video") << SRS_JOBJECT_START
<< SRS_JFIELD_STR("codec", srs_codec_video2str(vcodec)) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("profile", srs_codec_avc_profile2str(avc_profile)) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("level", srs_codec_avc_level2str(avc_level))
<< SRS_JOBJECT_END
<< SRS_JFIELD_CONT;
}
if (!has_audio) {
ss << SRS_JFIELD_NULL("audio");
} else {
ss << SRS_JFIELD_NAME("audio") << SRS_JOBJECT_START
<< SRS_JFIELD_STR("codec", srs_codec_audio2str(acodec)) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("sample_rate", (int)flv_sample_rates[asample_rate]) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("channel", (int)asound_type + 1) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("profile", srs_codec_aac_object2str(aac_object))
<< SRS_JOBJECT_END;
}
ss << SRS_JOBJECT_END;
return ret;
}
void SrsStatisticStream::publish() void SrsStatisticStream::publish()
{ {
status = STATISTIC_STREAM_STATUS_PUBLISHING; status = STATISTIC_STREAM_STATUS_PUBLISHING;
@ -92,6 +165,26 @@ void SrsStatisticStream::close()
status = STATISTIC_STREAM_STATUS_IDLING; status = STATISTIC_STREAM_STATUS_IDLING;
} }
SrsStatisticClient::SrsStatisticClient()
{
id = 0;
}
SrsStatisticClient::~SrsStatisticClient()
{
}
int SrsStatisticClient::dumps(stringstream& ss)
{
int ret = ERROR_SUCCESS;
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ORG("id", id)
<< SRS_JOBJECT_END;
return ret;
}
SrsStatistic* SrsStatistic::_instance = new SrsStatistic(); SrsStatistic* SrsStatistic::_instance = new SrsStatistic();
SrsStatistic::SrsStatistic() SrsStatistic::SrsStatistic()
@ -107,14 +200,14 @@ SrsStatistic::~SrsStatistic()
srs_freep(kbps); srs_freep(kbps);
if (true) { if (true) {
std::map<std::string, SrsStatisticVhost*>::iterator it; std::map<int64_t, SrsStatisticVhost*>::iterator it;
for (it = vhosts.begin(); it != vhosts.end(); it++) { for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second; SrsStatisticVhost* vhost = it->second;
srs_freep(vhost); srs_freep(vhost);
} }
} }
if (true) { if (true) {
std::map<std::string, SrsStatisticStream*>::iterator it; std::map<int64_t, SrsStatisticStream*>::iterator it;
for (it = streams.begin(); it != streams.end(); it++) { for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second; SrsStatisticStream* stream = it->second;
srs_freep(stream); srs_freep(stream);
@ -127,6 +220,11 @@ SrsStatistic::~SrsStatistic()
srs_freep(client); srs_freep(client);
} }
} }
vhosts.clear();
rvhosts.clear();
streams.clear();
rstreams.clear();
} }
SrsStatistic* SrsStatistic::instance() SrsStatistic* SrsStatistic::instance()
@ -134,16 +232,29 @@ SrsStatistic* SrsStatistic::instance()
return _instance; return _instance;
} }
SrsStatisticStream* SrsStatistic::find_stream(int stream_id) SrsStatisticVhost* SrsStatistic::find_vhost(int vid)
{
std::map<int64_t, SrsStatisticVhost*>::iterator it;
if ((it = vhosts.find(vid)) != vhosts.end()) {
return it->second;
}
return NULL;
}
SrsStatisticStream* SrsStatistic::find_stream(int sid)
{
std::map<int64_t, SrsStatisticStream*>::iterator it;
if ((it = streams.find(sid)) != streams.end()) {
return it->second;
}
return NULL;
}
SrsStatisticClient* SrsStatistic::find_client(int cid)
{ {
std::map<int, SrsStatisticClient*>::iterator it; std::map<int, SrsStatisticClient*>::iterator it;
for (it = clients.begin(); it != clients.end(); it++) { if ((it = clients.find(cid)) != clients.end()) {
SrsStatisticClient* client = it->second; return it->second;
SrsStatisticStream* stream = client->stream;
if (stream_id == stream->id) {
return stream;
}
} }
return NULL; return NULL;
} }
@ -215,6 +326,10 @@ int SrsStatistic::on_client(int id, SrsRequest* req)
} else { } else {
client = clients[id]; client = clients[id];
} }
// got client.
stream->nb_clients++;
vhost->nb_clients++;
return ret; return ret;
} }
@ -222,12 +337,19 @@ int SrsStatistic::on_client(int id, SrsRequest* req)
void SrsStatistic::on_disconnect(int id) void SrsStatistic::on_disconnect(int id)
{ {
std::map<int, SrsStatisticClient*>::iterator it; std::map<int, SrsStatisticClient*>::iterator it;
it = clients.find(id); if ((it = clients.find(id)) == clients.end()) {
if (it != clients.end()) { return;
SrsStatisticClient* client = it->second;
srs_freep(client);
clients.erase(it);
} }
SrsStatisticClient* client = it->second;
SrsStatisticStream* stream = client->stream;
SrsStatisticVhost* vhost = stream->vhost;
srs_freep(client);
clients.erase(it);
stream->nb_clients--;
vhost->nb_clients--;
} }
void SrsStatistic::kbps_add_delta(SrsConnection* conn) void SrsStatistic::kbps_add_delta(SrsConnection* conn)
@ -256,14 +378,14 @@ SrsKbps* SrsStatistic::kbps_sample()
{ {
kbps->sample(); kbps->sample();
if (true) { if (true) {
std::map<std::string, SrsStatisticVhost*>::iterator it; std::map<int64_t, SrsStatisticVhost*>::iterator it;
for (it = vhosts.begin(); it != vhosts.end(); it++) { for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second; SrsStatisticVhost* vhost = it->second;
vhost->kbps->sample(); vhost->kbps->sample();
} }
} }
if (true) { if (true) {
std::map<std::string, SrsStatisticStream*>::iterator it; std::map<int64_t, SrsStatisticStream*>::iterator it;
for (it = streams.begin(); it != streams.end(); it++) { for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second; SrsStatisticStream* stream = it->second;
stream->kbps->sample(); stream->kbps->sample();
@ -283,29 +405,17 @@ int SrsStatistic::dumps_vhosts(stringstream& ss)
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
ss << SRS_JARRAY_START; ss << SRS_JARRAY_START;
std::map<std::string, SrsStatisticVhost*>::iterator it; std::map<int64_t, SrsStatisticVhost*>::iterator it;
for (it = vhosts.begin(); it != vhosts.end(); it++) { for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second; SrsStatisticVhost* vhost = it->second;
if (it != vhosts.begin()) { if (it != vhosts.begin()) {
ss << SRS_JFIELD_CONT; ss << SRS_JFIELD_CONT;
} }
// dumps the config of vhost. if ((ret = vhost->dumps(ss)) != ERROR_SUCCESS) {
bool hls_enabled = _srs_config->get_hls_enabled(vhost->vhost); return ret;
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ORG("id", vhost->id) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("name", vhost->vhost) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("send_bytes", vhost->kbps->get_send_bytes()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("recv_bytes", vhost->kbps->get_recv_bytes()) << SRS_JFIELD_CONT
<< SRS_JFIELD_NAME("hls") << SRS_JOBJECT_START
<< SRS_JFIELD_BOOL("enabled", hls_enabled);
if (hls_enabled) {
ss << SRS_JFIELD_CONT;
ss << SRS_JFIELD_ORG("fragment", _srs_config->get_hls_fragment(vhost->vhost));
} }
ss << SRS_JOBJECT_END
<< SRS_JOBJECT_END;
} }
ss << SRS_JARRAY_END; ss << SRS_JARRAY_END;
@ -317,77 +427,64 @@ int SrsStatistic::dumps_streams(stringstream& ss)
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
ss << SRS_JARRAY_START; ss << SRS_JARRAY_START;
std::map<std::string, SrsStatisticStream*>::iterator it; std::map<int64_t, SrsStatisticStream*>::iterator it;
for (it = streams.begin(); it != streams.end(); it++) { for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second; SrsStatisticStream* stream = it->second;
if (it != streams.begin()) { if (it != streams.begin()) {
ss << SRS_JFIELD_CONT; ss << SRS_JFIELD_CONT;
} }
int client_num = 0; if ((ret = stream->dumps(ss)) != ERROR_SUCCESS) {
std::map<int, SrsStatisticClient*>::iterator it_client; return ret;
for (it_client = clients.begin(); it_client != clients.end(); it_client++) {
SrsStatisticClient* client = it_client->second;
if (client->stream == stream) {
client_num++;
}
} }
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ORG("id", stream->id) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("name", stream->stream) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("vhost", stream->vhost->id) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("app", stream->app) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("clients", client_num) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("send_bytes", stream->kbps->get_send_bytes()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("recv_bytes", stream->kbps->get_recv_bytes()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("live_ms", srs_get_system_time_ms()) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("status", stream->status) << SRS_JFIELD_CONT;
if (!stream->has_video) {
ss << SRS_JFIELD_NULL("video") << SRS_JFIELD_CONT;
} else {
ss << SRS_JFIELD_NAME("video")
<< SRS_JOBJECT_START
<< SRS_JFIELD_STR("codec", srs_codec_video2str(stream->vcodec)) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("profile", srs_codec_avc_profile2str(stream->avc_profile)) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("level", srs_codec_avc_level2str(stream->avc_level))
<< SRS_JOBJECT_END
<< SRS_JFIELD_CONT;
}
if (!stream->has_audio) {
ss << SRS_JFIELD_NULL("audio");
} else {
ss << SRS_JFIELD_NAME("audio")
<< SRS_JOBJECT_START
<< SRS_JFIELD_STR("codec", srs_codec_audio2str(stream->acodec)) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("sample_rate", (int)flv_sample_rates[stream->asample_rate]) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("channel", (int)stream->asound_type + 1) << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("profile", srs_codec_aac_object2str(stream->aac_object))
<< SRS_JOBJECT_END;
}
ss << SRS_JOBJECT_END;
} }
ss << SRS_JARRAY_END; ss << SRS_JARRAY_END;
return ret; return ret;
} }
int SrsStatistic::dumps_clients(stringstream& ss, int start, int count)
{
int ret = ERROR_SUCCESS;
ss << SRS_JARRAY_START;
std::map<int, SrsStatisticClient*>::iterator it = clients.begin();
for (int i = 0; i < count && it != clients.end(); it++) {
if (i < start) {
continue;
}
SrsStatisticClient* client = it->second;
if (i != start) {
ss << SRS_JFIELD_CONT;
}
if ((ret = client->dumps(ss)) != ERROR_SUCCESS) {
return ret;
}
}
ss << SRS_JARRAY_END;
return ret;
}
SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req) SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req)
{ {
SrsStatisticVhost* vhost = NULL; SrsStatisticVhost* vhost = NULL;
// create vhost if not exists. // create vhost if not exists.
if (vhosts.find(req->vhost) == vhosts.end()) { if (rvhosts.find(req->vhost) == rvhosts.end()) {
vhost = new SrsStatisticVhost(); vhost = new SrsStatisticVhost();
vhost->vhost = req->vhost; vhost->vhost = req->vhost;
vhosts[req->vhost] = vhost; rvhosts[req->vhost] = vhost;
vhosts[vhost->id] = vhost;
return vhost; return vhost;
} }
vhost = vhosts[req->vhost]; vhost = rvhosts[req->vhost];
return vhost; return vhost;
} }
@ -399,17 +496,18 @@ SrsStatisticStream* SrsStatistic::create_stream(SrsStatisticVhost* vhost, SrsReq
SrsStatisticStream* stream = NULL; SrsStatisticStream* stream = NULL;
// create stream if not exists. // create stream if not exists.
if (streams.find(url) == streams.end()) { if (rstreams.find(url) == rstreams.end()) {
stream = new SrsStatisticStream(); stream = new SrsStatisticStream();
stream->vhost = vhost; stream->vhost = vhost;
stream->stream = req->stream; stream->stream = req->stream;
stream->app = req->app; stream->app = req->app;
stream->url = url; stream->url = url;
streams[url] = stream; rstreams[url] = stream;
streams[stream->id] = stream;
return stream; return stream;
} }
stream = streams[url]; stream = rstreams[url];
return stream; return stream;
} }

View file

@ -47,6 +47,7 @@ struct SrsStatisticVhost
public: public:
int64_t id; int64_t id;
std::string vhost; std::string vhost;
int nb_clients;
public: public:
/** /**
* vhost total kbps. * vhost total kbps.
@ -55,6 +56,8 @@ public:
public: public:
SrsStatisticVhost(); SrsStatisticVhost();
virtual ~SrsStatisticVhost(); virtual ~SrsStatisticVhost();
public:
virtual int dumps(std::stringstream& ss);
}; };
struct SrsStatisticStream struct SrsStatisticStream
@ -66,6 +69,7 @@ public:
std::string stream; std::string stream;
std::string url; std::string url;
std::string status; std::string status;
int nb_clients;
public: public:
/** /**
* stream total kbps. * stream total kbps.
@ -93,6 +97,8 @@ public:
public: public:
SrsStatisticStream(); SrsStatisticStream();
virtual ~SrsStatisticStream(); virtual ~SrsStatisticStream();
public:
virtual int dumps(std::stringstream& ss);
public: public:
/** /**
* publish the stream. * publish the stream.
@ -109,6 +115,11 @@ struct SrsStatisticClient
public: public:
SrsStatisticStream* stream; SrsStatisticStream* stream;
int id; int id;
public:
SrsStatisticClient();
virtual ~SrsStatisticClient();
public:
virtual int dumps(std::stringstream& ss);
}; };
class SrsStatistic class SrsStatistic
@ -117,10 +128,19 @@ private:
static SrsStatistic *_instance; static SrsStatistic *_instance;
// the id to identify the sever. // the id to identify the sever.
int64_t _server_id; int64_t _server_id;
// key: vhost name, value: vhost object. private:
std::map<std::string, SrsStatisticVhost*> vhosts; // key: vhost id, value: vhost object.
// key: stream url, value: stream object. std::map<int64_t, SrsStatisticVhost*> vhosts;
std::map<std::string, SrsStatisticStream*> streams; // key: vhost url, value: vhost Object.
// @remark a fast index for vhosts.
std::map<std::string, SrsStatisticVhost*> rvhosts;
private:
// key: stream id, value: stream Object.
std::map<int64_t, SrsStatisticStream*> streams;
// key: stream url, value: stream Object.
// @remark a fast index for streams.
std::map<std::string, SrsStatisticStream*> rstreams;
private:
// key: client id, value: stream object. // key: client id, value: stream object.
std::map<int, SrsStatisticClient*> clients; std::map<int, SrsStatisticClient*> clients;
// server total kbps. // server total kbps.
@ -131,7 +151,10 @@ private:
public: public:
static SrsStatistic* instance(); static SrsStatistic* instance();
public: public:
virtual SrsStatisticStream* find_stream(int stream_id); virtual SrsStatisticVhost* find_vhost(int vid);
virtual SrsStatisticStream* find_stream(int sid);
virtual SrsStatisticClient* find_client(int cid);
public:
/** /**
* when got video info for stream. * when got video info for stream.
*/ */
@ -192,6 +215,12 @@ public:
* dumps the streams to sstream in json. * dumps the streams to sstream in json.
*/ */
virtual int dumps_streams(std::stringstream& ss); virtual int dumps_streams(std::stringstream& ss);
/**
* dumps the clients to sstream in json.
* @param start the start index, from 0.
* @param count the max count of clients to dump.
*/
virtual int dumps_clients(std::stringstream& ss, int start, int count);
private: private:
virtual SrsStatisticVhost* create_vhost(SrsRequest* req); virtual SrsStatisticVhost* create_vhost(SrsRequest* req);
virtual SrsStatisticStream* create_stream(SrsStatisticVhost* vhost, SrsRequest* req); virtual SrsStatisticStream* create_stream(SrsStatisticVhost* vhost, SrsRequest* req);

View file

@ -43,7 +43,7 @@ using namespace std;
#include <srs_kernel_utility.hpp> #include <srs_kernel_utility.hpp>
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
#include <srs_protocol_kbps.hpp> #include <srs_protocol_kbps.hpp>
#include <srs_app_json.hpp> #include <srs_protocol_json.hpp>
#include <srs_kernel_stream.hpp> #include <srs_kernel_stream.hpp>
// the longest time to wait for a process to quit. // the longest time to wait for a process to quit.

View file

@ -32,6 +32,7 @@ using namespace std;
#include <srs_kernel_log.hpp> #include <srs_kernel_log.hpp>
#include <srs_kernel_utility.hpp> #include <srs_kernel_utility.hpp>
#include <srs_kernel_file.hpp> #include <srs_kernel_file.hpp>
#include <srs_protocol_json.hpp>
#define SRS_HTTP_DEFAULT_PAGE "index.html" #define SRS_HTTP_DEFAULT_PAGE "index.html"
@ -143,6 +144,17 @@ int srs_http_response_json(ISrsHttpResponseWriter* w, string data)
return w->write((char*)data.data(), (int)data.length()); return w->write((char*)data.data(), (int)data.length());
} }
int srs_http_response_code(ISrsHttpResponseWriter* w, int code)
{
std::stringstream ss;
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(code)
<< SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str());
}
SrsHttpHeader::SrsHttpHeader() SrsHttpHeader::SrsHttpHeader()
{ {
} }

View file

@ -78,6 +78,11 @@ class ISrsHttpResponseWriter;
// helper function: response in json format. // helper function: response in json format.
extern int srs_http_response_json(ISrsHttpResponseWriter* w, std::string data); extern int srs_http_response_json(ISrsHttpResponseWriter* w, std::string data);
/**
* response a typical code object, for example:
* {code : 100}
*/
extern int srs_http_response_code(ISrsHttpResponseWriter* w, int code);
// get the status text of code. // get the status text of code.
extern std::string srs_generate_http_status_text(int status); extern std::string srs_generate_http_status_text(int status);
@ -488,6 +493,14 @@ public:
virtual std::string host() = 0; virtual std::string host() = 0;
virtual std::string path() = 0; virtual std::string path() = 0;
virtual std::string ext() = 0; virtual std::string ext() = 0;
/**
* get the RESTful id,
* for example, pattern is /api/v1/streams, path is /api/v1/streams/100,
* then the rest id is 100.
* @param pattern the handler pattern which will serve the request.
* @return the REST id; -1 if not matched.
*/
virtual int parse_rest_id(std::string pattern) = 0;
public: public:
/** /**
* read body to string. * read body to string.

View file

@ -21,7 +21,7 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_json.hpp> #include <srs_protocol_json.hpp>
using namespace std; using namespace std;

View file

@ -21,11 +21,11 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_JSON_HPP #ifndef SRS_PROTOCOL_JSON_HPP
#define SRS_APP_JSON_HPP #define SRS_PROTOCOL_JSON_HPP
/* /*
#include <srs_app_json.hpp> #include <srs_protocol_json.hpp>
*/ */
#include <srs_core.hpp> #include <srs_core.hpp>