fixbug[play packet decode bug: srs only read bool type play reset value, actuall…
…y this value can be bool or number]
正在显示
74 个修改的文件
包含
1591 行增加
和
1050 行删除
AUTHORS.txt
0 → 100644
| 1 | The MIT License (MIT) | 1 | The MIT License (MIT) |
| 2 | 2 | ||
| 3 | -Copyright (c) 2013 winlin | 3 | +Copyright (c) 2013-2014 winlin |
| 4 | 4 | ||
| 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 6 | this software and associated documentation files (the "Software"), to deal in | 6 | this software and associated documentation files (the "Software"), to deal in |
| 1 | -simple-rtmp-server | 1 | +Simple-RTMP-Server |
| 2 | ================== | 2 | ================== |
| 3 | 3 | ||
| 4 | -srs(simple rtmp origin live server) over state-threads.<br/> | ||
| 5 | -srs is a simple, high-performance, running in single process, origin live server.<br/> | ||
| 6 | -srs supports vhost, rtmp, HLS, transcoding, forward, http hooks. <br/> | ||
| 7 | -blog: [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin) <br/> | ||
| 8 | -see also: [https://github.com/winlinvip/simple-rtmp-server](https://github.com/winlinvip/simple-rtmp-server) <br/> | ||
| 9 | -see also: [http://winlinvip.github.io/simple-rtmp-server](http://winlinvip.github.io/simple-rtmp-server) <br/> | 4 | +SRS(SIMPLE RTMP Server) over state-threads created in 2013.<br/> |
| 5 | +SRS is a simple, high-performance, running in single process, origin live server.<br/> | ||
| 6 | +SRS supports vhost, rtmp, HLS, transcoding, forward, http hooks. <br/> | ||
| 7 | +Blog: [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin) <br/> | ||
| 8 | +See also: [https://github.com/winlinvip/simple-rtmp-server](https://github.com/winlinvip/simple-rtmp-server) <br/> | ||
| 9 | +See also: [http://winlinvip.github.io/simple-rtmp-server](http://winlinvip.github.io/simple-rtmp-server) <br/> | ||
| 10 | TencentQQ: [http://url.cn/WAHICw](http://url.cn/WAHICw) (Group: 212189142) | 10 | TencentQQ: [http://url.cn/WAHICw](http://url.cn/WAHICw) (Group: 212189142) |
| 11 | 11 | ||
| 12 | -### Contributors | ||
| 13 | -winlin([winterserver](#)): [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin) <br/> | ||
| 14 | -wenjie([wenjiegit](https://github.com/wenjiegit/simple-rtmp-server)): [http://blog.chinaunix.net/uid/25006789.html](http://blog.chinaunix.net/uid/25006789.html) <br/> | ||
| 15 | -about the contributors: <br/> | ||
| 16 | -1. contribute important features to srs. <br/> | ||
| 17 | -2. the name of all contributors will send in the response of NetConnection.connect and metadata. | 12 | +### AUTHORS |
| 13 | +The PRIMARY AUTHORS are (and/or have been)(Authors ordered by first contribution): <br/> | ||
| 14 | +* winlin([winterserver](#)): [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin) <br/> | ||
| 15 | +* wenjie([wenjiegit](https://github.com/wenjiegit/simple-rtmp-server)): [http://blog.chinaunix.net/uid/25006789.html](http://blog.chinaunix.net/uid/25006789.html) <br/> | ||
| 16 | + | ||
| 17 | +About the primary AUTHORS: <br/> | ||
| 18 | +* Contribute important features to SRS. <br/> | ||
| 19 | +* Names of all PRIMARY AUTHORS response in NetConnection.connect and metadata. <br/> | ||
| 20 | + | ||
| 21 | +And here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS --<br/> | ||
| 22 | +people who have submitted patches, reported bugs, added translations, helped<br/> | ||
| 23 | +answer newbie questions, and generally made SRS that much better: [AUTHORS.txt](https://github.com/winlinvip/simple-rtmp-server/blob/master/AUTHORS.txt) | ||
| 18 | 24 | ||
| 19 | ### Usage(simple) | 25 | ### Usage(simple) |
| 20 | -<strong>step -1:</strong> get srs<br/> | 26 | +<strong>Step -1:</strong> get SRS<br/> |
| 21 | <pre> | 27 | <pre> |
| 22 | git clone https://github.com/winlinvip/simple-rtmp-server && | 28 | git clone https://github.com/winlinvip/simple-rtmp-server && |
| 23 | cd simple-rtmp-server/trunk | 29 | cd simple-rtmp-server/trunk |
| 24 | </pre> | 30 | </pre> |
| 25 | -<strong>step 0:</strong> build srs system.<br/> | 31 | +<strong>Step 0:</strong> build SRS system.<br/> |
| 26 | <pre> | 32 | <pre> |
| 27 | bash scripts/build.sh | 33 | bash scripts/build.sh |
| 28 | </pre> | 34 | </pre> |
| 29 | -<strong>step 1:</strong> start srs all demo features.<br/> | 35 | +<strong>Step 1:</strong> start SRS all demo features.<br/> |
| 30 | <pre> | 36 | <pre> |
| 31 | bash scripts/run.sh | 37 | bash scripts/run.sh |
| 32 | </pre> | 38 | </pre> |
| 33 | -<strong>step 2:</strong> srs live show: [http://your-server-ip](http://your-server-ip) <br/> | ||
| 34 | -<strong>step 3:</strong> stop srs demo<br/> | 39 | +<strong>Step 2:</strong> SRS live show: [http://your-server-ip](http://your-server-ip) <br/> |
| 40 | +<strong>Step 3:</strong> stop SRS demo<br/> | ||
| 35 | <pre> | 41 | <pre> |
| 36 | bash scripts/stop.sh | 42 | bash scripts/stop.sh |
| 37 | </pre> | 43 | </pre> |
| 38 | 44 | ||
| 39 | ### Usage(detail) | 45 | ### Usage(detail) |
| 40 | -<strong>step 0:</strong> get srs <br/> | 46 | +<strong>Step 0:</strong> get SRS <br/> |
| 41 | <pre> | 47 | <pre> |
| 42 | git clone https://github.com/winlinvip/simple-rtmp-server && | 48 | git clone https://github.com/winlinvip/simple-rtmp-server && |
| 43 | cd simple-rtmp-server/trunk | 49 | cd simple-rtmp-server/trunk |
| 44 | </pre> | 50 | </pre> |
| 45 | -<strong>step 1:</strong> build srs <br/> | 51 | +<strong>Step 1:</strong> build SRS <br/> |
| 46 | <pre> | 52 | <pre> |
| 47 | ./configure --with-ssl --with-hls --with-ffmpeg --with-http && make | 53 | ./configure --with-ssl --with-hls --with-ffmpeg --with-http && make |
| 48 | </pre> | 54 | </pre> |
| 49 | -<strong>step 2:</strong> start srs <br/> | 55 | +<strong>Step 2:</strong> start SRS <br/> |
| 50 | <pre> | 56 | <pre> |
| 51 | ./objs/srs -c conf/srs.conf | 57 | ./objs/srs -c conf/srs.conf |
| 52 | </pre> | 58 | </pre> |
| 53 | -<strong>step 3(optinal):</strong> start srs listen at 19350 to forward to<br/> | 59 | +<strong>Step 3(optinal):</strong> start SRS listen at 19350 to forward to<br/> |
| 54 | <pre> | 60 | <pre> |
| 55 | ./objs/srs -c conf/srs.19350.conf | 61 | ./objs/srs -c conf/srs.19350.conf |
| 56 | </pre> | 62 | </pre> |
| 57 | -<strong>step 4(optinal):</strong> start nginx for HLS <br/> | 63 | +<strong>Step 4(optinal):</strong> start nginx for HLS <br/> |
| 58 | <pre> | 64 | <pre> |
| 59 | sudo ./objs/nginx/sbin/nginx | 65 | sudo ./objs/nginx/sbin/nginx |
| 60 | </pre> | 66 | </pre> |
| 61 | -<strong>step 5(optinal):</strong> start http hooks for srs callback <br/> | 67 | +<strong>Step 5(optinal):</strong> start http hooks for SRS callback <br/> |
| 62 | <pre> | 68 | <pre> |
| 63 | python ./research/api-server/server.py 8085 | 69 | python ./research/api-server/server.py 8085 |
| 64 | </pre> | 70 | </pre> |
| 65 | -<strong>step 6:</strong> publish demo live stream <br/> | 71 | +<strong>Step 6:</strong> publish demo live stream <br/> |
| 66 | <pre> | 72 | <pre> |
| 67 | FMS URL: rtmp://127.0.0.1/live?vhost=demo.srs.com | 73 | FMS URL: rtmp://127.0.0.1/live?vhost=demo.srs.com |
| 68 | Stream: livestream | 74 | Stream: livestream |
| @@ -74,7 +80,7 @@ FFMPEG to publish the default demo stream: | @@ -74,7 +80,7 @@ FFMPEG to publish the default demo stream: | ||
| 74 | sleep 1; \ | 80 | sleep 1; \ |
| 75 | done | 81 | done |
| 76 | </pre> | 82 | </pre> |
| 77 | -<strong>step 7:</strong> publish players live stream <br/> | 83 | +<strong>Step 7:</strong> publish players live stream <br/> |
| 78 | <pre> | 84 | <pre> |
| 79 | FMS URL: rtmp://127.0.0.1/live?vhost=players | 85 | FMS URL: rtmp://127.0.0.1/live?vhost=players |
| 80 | Stream: livestream | 86 | Stream: livestream |
| @@ -86,7 +92,7 @@ FFMPEG to publish the players demo stream: | @@ -86,7 +92,7 @@ FFMPEG to publish the players demo stream: | ||
| 86 | sleep 1; \ | 92 | sleep 1; \ |
| 87 | done | 93 | done |
| 88 | </pre> | 94 | </pre> |
| 89 | -<strong>step 8:</strong> add server ip to client hosts as demo. <br/> | 95 | +<strong>Step 8:</strong> add server ip to client hosts as demo. <br/> |
| 90 | <pre> | 96 | <pre> |
| 91 | # edit the folowing file: | 97 | # edit the folowing file: |
| 92 | # linux: /etc/hosts | 98 | # linux: /etc/hosts |
| @@ -94,14 +100,14 @@ FFMPEG to publish the players demo stream: | @@ -94,14 +100,14 @@ FFMPEG to publish the players demo stream: | ||
| 94 | # where server ip is 192.168.2.111 | 100 | # where server ip is 192.168.2.111 |
| 95 | 192.168.2.111 demo.srs.com | 101 | 192.168.2.111 demo.srs.com |
| 96 | </pre> | 102 | </pre> |
| 97 | -<strong>step 9:</strong> play live stream. <br/> | 103 | +<strong>Step 9:</strong> play live stream. <br/> |
| 98 | <pre> | 104 | <pre> |
| 99 | players: http://demo.srs.com/players | 105 | players: http://demo.srs.com/players |
| 100 | rtmp url: rtmp://demo.srs.com/live/livestream | 106 | rtmp url: rtmp://demo.srs.com/live/livestream |
| 101 | m3u8 url: http://demo.srs.com/live/livestream.m3u8 | 107 | m3u8 url: http://demo.srs.com/live/livestream.m3u8 |
| 102 | for android: http://demo.srs.com/live/livestream.html | 108 | for android: http://demo.srs.com/live/livestream.html |
| 103 | </pre> | 109 | </pre> |
| 104 | -<strong>step 10(optinal):</strong> play live stream auto transcoded<br/> | 110 | +<strong>Step 10(optinal):</strong> play live stream auto transcoded<br/> |
| 105 | <pre> | 111 | <pre> |
| 106 | rtmp url: rtmp://demo.srs.com/live/livestream_ld | 112 | rtmp url: rtmp://demo.srs.com/live/livestream_ld |
| 107 | m3u8 url: http://demo.srs.com/live/livestream_ld.m3u8 | 113 | m3u8 url: http://demo.srs.com/live/livestream_ld.m3u8 |
| @@ -110,7 +116,7 @@ rtmp url: rtmp://demo.srs.com/live/livestream_sd | @@ -110,7 +116,7 @@ rtmp url: rtmp://demo.srs.com/live/livestream_sd | ||
| 110 | m3u8 url: http://demo.srs.com/live/livestream_sd.m3u8 | 116 | m3u8 url: http://demo.srs.com/live/livestream_sd.m3u8 |
| 111 | for android: http://demo.srs.com/live/livestream_sd.html | 117 | for android: http://demo.srs.com/live/livestream_sd.html |
| 112 | </pre> | 118 | </pre> |
| 113 | -<strong>step 11(optinal):</strong> play live stream auto forwarded, the hls dir change to /forward<br/> | 119 | +<strong>Step 11(optinal):</strong> play live stream auto forwarded, the hls dir change to /forward<br/> |
| 114 | <pre> | 120 | <pre> |
| 115 | rtmp url: rtmp://demo.srs.com:19350/live/livestream | 121 | rtmp url: rtmp://demo.srs.com:19350/live/livestream |
| 116 | m3u8 url: http://demo.srs.com/forward/live/livestream.m3u8 | 122 | m3u8 url: http://demo.srs.com/forward/live/livestream.m3u8 |
| @@ -122,7 +128,7 @@ rtmp url: rtmp://demo.srs.com:19350/live/livestream_sd | @@ -122,7 +128,7 @@ rtmp url: rtmp://demo.srs.com:19350/live/livestream_sd | ||
| 122 | m3u8 url: http://demo.srs.com/forward/live/livestream_sd.m3u8 | 128 | m3u8 url: http://demo.srs.com/forward/live/livestream_sd.m3u8 |
| 123 | for android: http://demo.srs.com/forward/live/livestream_sd.html | 129 | for android: http://demo.srs.com/forward/live/livestream_sd.html |
| 124 | </pre> | 130 | </pre> |
| 125 | -<strong>step 12(optinal):</strong> modify the config and reload it (all features support reload)<br/> | 131 | +<strong>Step 12(optinal):</strong> modify the config and reload it (all features support reload)<br/> |
| 126 | <pre> | 132 | <pre> |
| 127 | killall -1 srs | 133 | killall -1 srs |
| 128 | </pre> | 134 | </pre> |
| @@ -135,7 +141,7 @@ killall -s SIGHUP srs | @@ -135,7 +141,7 @@ killall -s SIGHUP srs | ||
| 135 | System Architecture: | 141 | System Architecture: |
| 136 | <pre> | 142 | <pre> |
| 137 | +------------------------------------------------------+ | 143 | +------------------------------------------------------+ |
| 138 | -| SRS(Simple Rtmp Server) | | 144 | +| SRS(Simple RTMP Server) | |
| 139 | +---------------+---------------+-----------+----------+ | 145 | +---------------+---------------+-----------+----------+ |
| 140 | | API/hook | Transcoder | HLS | RTMP | | 146 | | API/hook | Transcoder | HLS | RTMP | |
| 141 | | http-parser | FFMPEG/x264 | NGINX/ts | protocol | | 147 | | http-parser | FFMPEG/x264 | NGINX/ts | protocol | |
| @@ -151,7 +157,7 @@ Stream Architecture: | @@ -151,7 +157,7 @@ Stream Architecture: | ||
| 151 | + Publish + + Deliver | | 157 | + Publish + + Deliver | |
| 152 | +---|-----+ +----|-----+ | 158 | +---|-----+ +----|-----+ |
| 153 | +-----------+-------------------------+----------------+ | 159 | +-----------+-------------------------+----------------+ |
| 154 | -| Encoder | SRS(Simple Rtmp Server) | Client | | 160 | +| Encoder | SRS(Simple RTMP Server) | Client | |
| 155 | +-----------+-------------------------+----------------+ | 161 | +-----------+-------------------------+----------------+ |
| 156 | | (FMLE, | +-> RTMP protocol ----+-> Flash Player | | 162 | | (FMLE, | +-> RTMP protocol ----+-> Flash Player | |
| 157 | | FFMPEG, --+-> +-> HLS/NGINX --------+-> m3u8 player | | 163 | | FFMPEG, --+-> +-> HLS/NGINX --------+-> m3u8 player | |
| @@ -186,7 +192,7 @@ Bandwidth Test Workflow: | @@ -186,7 +192,7 @@ Bandwidth Test Workflow: | ||
| 186 | | final(2)-----------------> | | 192 | | final(2)-----------------> | |
| 187 | | <END> | | 193 | | <END> | |
| 188 | 194 | ||
| 189 | -@see: class SrsBandwidth comments. | 195 | +@See: class SrsBandwidth comments. |
| 190 | </pre> | 196 | </pre> |
| 191 | 197 | ||
| 192 | ### System Requirements | 198 | ### System Requirements |
| @@ -195,37 +201,38 @@ Supported operating systems and hardware: | @@ -195,37 +201,38 @@ Supported operating systems and hardware: | ||
| 195 | * All handware. | 201 | * All handware. |
| 196 | 202 | ||
| 197 | ### Summary | 203 | ### Summary |
| 198 | -1. simple: also stable enough.<br/> | ||
| 199 | -2. high-performance: single-thread, async socket, event/st-thread driven.<br/> | ||
| 200 | -3. no edge server, origin server only.<br/> | ||
| 201 | -4. no vod streaming, live streaming only.<br/> | ||
| 202 | -5. no multiple processes, single process only.<br/> | ||
| 203 | -6. support vhost, support \_\_defaultVhost\_\_.<br/> | ||
| 204 | -7. support adobe rtmp live streaming.<br/> | ||
| 205 | -8. support apple hls(m3u8) live streaming.<br/> | ||
| 206 | -9. support reload config to enable changes.<br/> | ||
| 207 | -10. support cache last gop for flash player to fast startup.<br/> | ||
| 208 | -11. support listen at multiple ports.<br/> | ||
| 209 | -12. support long time(>4.6hours) publish/play.<br/> | ||
| 210 | -13. high performace, 1800 connections(500kbps), 900Mbps, CPU 90.2%, 41MB<br/> | ||
| 211 | -14. support forward publish stream to build active-standby cluster.<br/> | ||
| 212 | -15. support broadcast by forward the stream to other servers(origin/edge).<br/> | ||
| 213 | -16. support live stream transcoding by ffmpeg.<br/> | ||
| 214 | -17. support live stream forward(acopy/vcopy) by ffmpeg.<br/> | ||
| 215 | -18. support ffmpeg filters(logo/overlay/crop), x264 params.<br/> | ||
| 216 | -19. support audio transcode only, speex/mp3 to aac<br/> | ||
| 217 | -20. support http callback api hooks(for authentication and injection).<br/> | ||
| 218 | -21. support bandwidth test api and flash client.<br/> | ||
| 219 | -22. player, publisher(encoder), and demo pages(jquery+bootstrap). <br/> | ||
| 220 | -23. demo video meeting or chat(srs+cherrypy+jquery+bootstrap). <br/> | ||
| 221 | -24. [plan] support network based cli and json result.<br/> | ||
| 222 | -25. [plan] support adobe flash refer/token/swf verification.<br/> | ||
| 223 | -26. [plan] support adobe amf3 codec.<br/> | ||
| 224 | -27. [plan] support dvr(record live to vod file)<br/> | ||
| 225 | -28. [plan] support FMS edge protocol<br/> | ||
| 226 | -29. [plan] support encryption: RTMPE/RTMPS, HLS DRM<br/> | ||
| 227 | -30. [plan] support RTMPT, http to tranverse firewalls<br/> | ||
| 228 | -31. [plan] support file source, transcoding file to live stream<br/> | 204 | +1. Simple: also stable enough.<br/> |
| 205 | +2. [High-performance](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance): single-thread, async socket, event/st-thread driven.<br/> | ||
| 206 | +3. NO edge server, origin server only.<br/> | ||
| 207 | +4. NO vod streaming, live streaming only.<br/> | ||
| 208 | +5. NO multiple processes, single process only.<br/> | ||
| 209 | +6. Support vhost, support \_\_defaultVhost\_\_.<br/> | ||
| 210 | +7. Support adobe rtmp live streaming.<br/> | ||
| 211 | +8. Support apple hls(m3u8) live streaming.<br/> | ||
| 212 | +9. Support reload config to enable changes.<br/> | ||
| 213 | +10. Support cache last gop for flash player to fast startup.<br/> | ||
| 214 | +11. Support listen at multiple ports.<br/> | ||
| 215 | +12. Support long time(>4.6hours) publish/play.<br/> | ||
| 216 | +13. High performace, 1800 connections(500kbps), 900Mbps, CPU 90.2%, 41MB<br/> | ||
| 217 | +14. Support forward publish stream to build active-standby [cluster](https://github.com/winlinvip/simple-rtmp-server/wiki/Cluster).<br/> | ||
| 218 | +15. Support broadcast by forward the stream to other servers(origin/edge).<br/> | ||
| 219 | +16. Support live stream transcoding by ffmpeg.<br/> | ||
| 220 | +17. Support live stream forward(acopy/vcopy) by ffmpeg.<br/> | ||
| 221 | +18. Support ffmpeg filters(logo/overlay/crop), x264 params.<br/> | ||
| 222 | +19. Support audio transcode only, speex/mp3 to aac<br/> | ||
| 223 | +20. Support http callback api hooks(for authentication and injection).<br/> | ||
| 224 | +21. Support bandwidth test api and flash client.<br/> | ||
| 225 | +22. Player, publisher(encoder), and demo pages(jquery+bootstrap). <br/> | ||
| 226 | +23. Demo video meeting or chat(SRS+cherrypy+jquery+bootstrap). <br/> | ||
| 227 | +24. [dev] Full documents in wiki, in chineses. <br/> | ||
| 228 | +25. [plan] Support network based cli and json result.<br/> | ||
| 229 | +26. [plan] Support adobe flash refer/token/swf verification.<br/> | ||
| 230 | +27. [plan] Support adobe amf3 codec.<br/> | ||
| 231 | +28. [plan] Support dvr(record live to vod file)<br/> | ||
| 232 | +29. [plan] Support FMS edge protocol<br/> | ||
| 233 | +30. [plan] Support encryption: RTMPE/RTMPS, HLS DRM<br/> | ||
| 234 | +31. [plan] Support RTMPT, http to tranverse firewalls<br/> | ||
| 235 | +32. [plan] Support file source, transcoding file to live stream<br/> | ||
| 229 | 236 | ||
| 230 | ### Performance | 237 | ### Performance |
| 231 | 1. 300 connections, 150Mbps, 500kbps, CPU 18.8%, 5956KB. | 238 | 1. 300 connections, 150Mbps, 500kbps, CPU 18.8%, 5956KB. |
| @@ -234,53 +241,54 @@ Supported operating systems and hardware: | @@ -234,53 +241,54 @@ Supported operating systems and hardware: | ||
| 234 | 4. 1200 connections, 600Mbps, 500kbps, CPU 72.4%, 15MB. | 241 | 4. 1200 connections, 600Mbps, 500kbps, CPU 72.4%, 15MB. |
| 235 | 5. 1500 connections, 750Mbps, 500kbps, CPU 81.9%, 28MB. | 242 | 5. 1500 connections, 750Mbps, 500kbps, CPU 81.9%, 28MB. |
| 236 | 6. 1800 connections, 900Mbps, 500kbps, CPU 90.2%, 41MB. | 243 | 6. 1800 connections, 900Mbps, 500kbps, CPU 90.2%, 41MB. |
| 244 | + | ||
| 237 | <pre> | 245 | <pre> |
| 246 | +[winlin@dev6 srs]$ dstat | ||
| 238 | ----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system-- | 247 | ----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system-- |
| 239 | usr sys idl wai hiq siq| read writ| recv send| in out | int csw | 248 | usr sys idl wai hiq siq| read writ| recv send| in out | int csw |
| 240 | 58 9 32 0 0 1| 0 4168k| 277M 277M| 0 0 | 29k 25k | 249 | 58 9 32 0 0 1| 0 4168k| 277M 277M| 0 0 | 29k 25k |
| 241 | 61 8 30 0 0 1| 0 1168k| 336M 336M| 0 0 | 29k 24k | 250 | 61 8 30 0 0 1| 0 1168k| 336M 336M| 0 0 | 29k 24k |
| 242 | 63 8 27 0 0 1| 0 2240k| 124M 124M| 0 0 | 32k 33k | 251 | 63 8 27 0 0 1| 0 2240k| 124M 124M| 0 0 | 32k 33k |
| 243 | 62 8 28 0 0 1| 0 1632k| 110M 110M| 0 0 | 31k 33k | 252 | 62 8 28 0 0 1| 0 1632k| 110M 110M| 0 0 | 31k 33k |
| 244 | - 67 9 23 0 0 2| 0 1604k| 130M 130M| 0 0 | 33k 32k | ||
| 245 | - 63 9 27 0 0 2| 0 1496k| 145M 145M| 0 0 | 32k 32k | ||
| 246 | - 61 9 29 0 0 1| 0 1112k| 132M 132M| 0 0 | 32k 33k | ||
| 247 | - 63 9 27 0 0 2| 0 1220k| 145M 145M| 0 0 | 32k 33k | ||
| 248 | 53 7 40 0 0 1| 0 1360k| 115M 115M| 0 0 | 24k 26k | 253 | 53 7 40 0 0 1| 0 1360k| 115M 115M| 0 0 | 24k 26k |
| 249 | 51 7 41 0 0 1| 0 1184k| 146M 146M| 0 0 | 24k 27k | 254 | 51 7 41 0 0 1| 0 1184k| 146M 146M| 0 0 | 24k 27k |
| 250 | 39 6 54 0 0 1| 0 1284k| 105M 105M| 0 0 | 22k 28k | 255 | 39 6 54 0 0 1| 0 1284k| 105M 105M| 0 0 | 22k 28k |
| 251 | 41 6 52 0 0 1| 0 1264k| 116M 116M| 0 0 | 25k 28k | 256 | 41 6 52 0 0 1| 0 1264k| 116M 116M| 0 0 | 25k 28k |
| 252 | 48 6 45 0 0 1| 0 1272k| 143M 143M| 0 0 | 27k 27k | 257 | 48 6 45 0 0 1| 0 1272k| 143M 143M| 0 0 | 27k 27k |
| 253 | </pre> | 258 | </pre> |
| 259 | +See also: [Performance Test Guide](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance) | ||
| 254 | 260 | ||
| 255 | ### Releases | 261 | ### Releases |
| 256 | -* 2013-12-25, [release v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9), support bandwidth test, add player/encoder/chat demos. 20926 lines.<br/> | ||
| 257 | -* 2013-12-08, [release v0.8](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.8), support http hooks callback, update [st_load](https://github.com/winlinvip/st-load). 19186 lines.<br/> | ||
| 258 | -* 2013-12-03, [release v0.7](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.7), support live stream transcoding. 17605 lines.<br/> | ||
| 259 | -* 2013-11-29, [release v0.6](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.6), support forward stream to origin/edge. 16094 lines.<br/> | ||
| 260 | -* 2013-11-26, [release v0.5](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.5), support HLS(m3u8), fragment and window. 14449 lines.<br/> | ||
| 261 | -* 2013-11-10, [release v0.4](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.4), support reload config, pause, longtime publish/play. 12500 lines.<br/> | ||
| 262 | -* 2013-11-04, [release v0.3](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.3), support vhost, refer, gop cache, listen multiple ports. 11773 lines.<br/> | ||
| 263 | -* 2013-10-25, [release v0.2](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.2), support rtmp flash publish, h264, time jitter correct. 10125 lines.<br/> | ||
| 264 | -* 2013-10-23, [release v0.1](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.1), support rtmp FMLE/FFMPEG publish, vp6. 8287 lines.<br/> | ||
| 265 | -* 2013-10-17, created.<br/> | 262 | +* 2013-12-25, [Release v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9), support bandwidth test, add player/encoder/chat demos. 20926 lines.<br/> |
| 263 | +* 2013-12-08, [Release v0.8](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.8), support http hooks callback, update [st_load](https://github.com/winlinvip/st-load). 19186 lines.<br/> | ||
| 264 | +* 2013-12-03, [Release v0.7](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.7), support live stream transcoding. 17605 lines.<br/> | ||
| 265 | +* 2013-11-29, [Release v0.6](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.6), support forward stream to origin/edge. 16094 lines.<br/> | ||
| 266 | +* 2013-11-26, [Release v0.5](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.5), support HLS(m3u8), fragment and window. 14449 lines.<br/> | ||
| 267 | +* 2013-11-10, [Release v0.4](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.4), support reload config, pause, longtime publish/play. 12500 lines.<br/> | ||
| 268 | +* 2013-11-04, [Release v0.3](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.3), support vhost, refer, gop cache, listen multiple ports. 11773 lines.<br/> | ||
| 269 | +* 2013-10-25, [Release v0.2](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.2), support rtmp flash publish, h264, time jitter correct. 10125 lines.<br/> | ||
| 270 | +* 2013-10-23, [Release v0.1](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.1), support rtmp FMLE/FFMPEG publish, vp6. 8287 lines.<br/> | ||
| 271 | +* 2013-10-17, Created.<br/> | ||
| 266 | 272 | ||
| 267 | ### Compare | 273 | ### Compare |
| 268 | -* srs v0.9: 20926 lines. player/encoder/chat demos. bandwidth test for encoder/CDN.<br/> | ||
| 269 | -* srs v0.8: 19186 lines. implements http hooks refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/> | ||
| 270 | -* srs v0.7: 17605 lines. implements transcoding(FFMPEG) feature refer to [wowza](http://www.wowza.com). <br/> | ||
| 271 | -* srs v0.6: 16094 lines. important feature forward for CDN. <br/> | ||
| 272 | -* srs v0.5: 14449 lines. implements HLS feature refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/> | ||
| 273 | -* srs v0.4: 12500 lines. important feature reload for CDN. <br/> | ||
| 274 | -* srs v0.3: 11773 lines. implements vhost feature refer to [FMS](http://www.adobe.com/products/adobe-media-server-family.html). <br/> | ||
| 275 | -* srs v0.2: 10125 lines. implements rtmp protocol stack refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/> | ||
| 276 | -* srs v0.1: 8287 lines. base on state-threads. <br/> | 274 | +* SRS v0.9: 20926 lines. player/encoder/chat demos. bandwidth test for encoder/CDN.<br/> |
| 275 | +* SRS v0.8: 19186 lines. implements http hooks refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/> | ||
| 276 | +* SRS v0.7: 17605 lines. implements transcoding(FFMPEG) feature refer to [wowza](http://www.wowza.com). <br/> | ||
| 277 | +* SRS v0.6: 16094 lines. important feature forward for CDN. <br/> | ||
| 278 | +* SRS v0.5: 14449 lines. implements HLS feature refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/> | ||
| 279 | +* SRS v0.4: 12500 lines. important feature reload for CDN. <br/> | ||
| 280 | +* SRS v0.3: 11773 lines. implements vhost feature refer to [FMS](http://www.adobe.com/products/adobe-media-server-family.html). <br/> | ||
| 281 | +* SRS v0.2: 10125 lines. implements rtmp protocol stack refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/> | ||
| 282 | +* SRS v0.1: 8287 lines. base on state-threads. <br/> | ||
| 277 | * nginx-rtmp v1.0.4: 26786 lines <br/> | 283 | * nginx-rtmp v1.0.4: 26786 lines <br/> |
| 278 | * nginx v1.5.0: 139524 lines <br/> | 284 | * nginx v1.5.0: 139524 lines <br/> |
| 279 | 285 | ||
| 280 | ### History | 286 | ### History |
| 287 | +* v1.0, 2014-01-01, change listen(512), chunk-size(60000), to improve performance. | ||
| 288 | +* v1.0, 2013-12-27, merge from wenjie, the bandwidth test feature. | ||
| 281 | * v0.9, 2013-12-25, [v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9) released. 20926 lines. | 289 | * v0.9, 2013-12-25, [v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9) released. 20926 lines. |
| 282 | * v0.9, 2013-12-25, fix the bitrate bug(in Bps), use enhanced microphone. | 290 | * v0.9, 2013-12-25, fix the bitrate bug(in Bps), use enhanced microphone. |
| 283 | -* v0.9, 2013-12-22, demo video meeting or chat(srs+cherrypy+jquery+bootstrap). | 291 | +* v0.9, 2013-12-22, demo video meeting or chat(SRS+cherrypy+jquery+bootstrap). |
| 284 | * v0.9, 2013-12-22, merge from wenjie, support banwidth test. | 292 | * v0.9, 2013-12-22, merge from wenjie, support banwidth test. |
| 285 | * v0.9, 2013-12-22, merge from wenjie: support set chunk size at vhost level | 293 | * v0.9, 2013-12-22, merge from wenjie: support set chunk size at vhost level |
| 286 | * v0.9, 2013-12-21, add [players](http://demo.srs.com/players) for play and publish. | 294 | * v0.9, 2013-12-21, add [players](http://demo.srs.com/players) for play and publish. |
| @@ -297,7 +305,7 @@ usr sys idl wai hiq siq| read writ| recv send| in out | int csw | @@ -297,7 +305,7 @@ usr sys idl wai hiq siq| read writ| recv send| in out | int csw | ||
| 297 | * v0.8, 2013-12-08, support multiple http hooks for a event. | 305 | * v0.8, 2013-12-08, support multiple http hooks for a event. |
| 298 | * v0.8, 2013-12-07, support http callback hooks, on_connect. | 306 | * v0.8, 2013-12-07, support http callback hooks, on_connect. |
| 299 | * v0.8, 2013-12-07, support network based cli and json result, add CherryPy 3.2.4. | 307 | * v0.8, 2013-12-07, support network based cli and json result, add CherryPy 3.2.4. |
| 300 | -* v0.8, 2013-12-07, update http/hls/rtmp load test tool [st_load](https://github.com/winlinvip/st-load), use srs rtmp sdk. | 308 | +* v0.8, 2013-12-07, update http/hls/rtmp load test tool [st_load](https://github.com/winlinvip/st-load), use SRS rtmp sdk. |
| 301 | * v0.8, 2013-12-06, support max_connections, drop if exceed. | 309 | * v0.8, 2013-12-06, support max_connections, drop if exceed. |
| 302 | * v0.8, 2013-12-05, support log_dir, write ffmpeg log to file. | 310 | * v0.8, 2013-12-05, support log_dir, write ffmpeg log to file. |
| 303 | * v0.8, 2013-12-05, fix the forward/hls/encoder bug. | 311 | * v0.8, 2013-12-05, fix the forward/hls/encoder bug. |
| 1 | # the listen ports, split by space. | 1 | # the listen ports, split by space. |
| 2 | listen 1935; | 2 | listen 1935; |
| 3 | +<<<<<<< HEAD | ||
| 4 | +======= | ||
| 5 | +# the default chunk size is 128, max is 65536, | ||
| 6 | +# some client does not support chunk size change, | ||
| 7 | +# however, most clients supports it and it can improve | ||
| 8 | +# performance about 10%. | ||
| 9 | +# default: 60000 | ||
| 10 | +chunk_size 60000; | ||
| 11 | +>>>>>>> upstream/master | ||
| 3 | # the logs dir. | 12 | # the logs dir. |
| 4 | # if enabled ffmpeg, each stracoding stream will create a log file. | 13 | # if enabled ffmpeg, each stracoding stream will create a log file. |
| 5 | # default: ./objs/logs | 14 | # default: ./objs/logs |
| @@ -28,7 +37,7 @@ vhost __defaultVhost__ { | @@ -28,7 +37,7 @@ vhost __defaultVhost__ { | ||
| 28 | # for which cannot identify the required vhost. | 37 | # for which cannot identify the required vhost. |
| 29 | # for default demo. | 38 | # for default demo. |
| 30 | vhost demo.srs.com { | 39 | vhost demo.srs.com { |
| 31 | - chunk_size 4096; | 40 | + chunk_size 60000; |
| 32 | enabled on; | 41 | enabled on; |
| 33 | gop_cache on; | 42 | gop_cache on; |
| 34 | queue_length 30; | 43 | queue_length 30; |
| @@ -226,7 +235,7 @@ vhost bandcheck.srs.com { | @@ -226,7 +235,7 @@ vhost bandcheck.srs.com { | ||
| 226 | enabled on; | 235 | enabled on; |
| 227 | # the key for server to valid, | 236 | # the key for server to valid, |
| 228 | # if invalid key, server disconnect and abort the bandwidth check. | 237 | # if invalid key, server disconnect and abort the bandwidth check. |
| 229 | - key 35c9b402c12a7246868752e2878f7e0e; | 238 | + key "35c9b402c12a7246868752e2878f7e0e"; |
| 230 | # the interval in seconds for bandwidth check, | 239 | # the interval in seconds for bandwidth check, |
| 231 | # server donot allow new test request. | 240 | # server donot allow new test request. |
| 232 | # default: 30 | 241 | # default: 30 |
| @@ -47,22 +47,27 @@ echo "" >> $SRS_AUTO_HEADERS_H | @@ -47,22 +47,27 @@ echo "" >> $SRS_AUTO_HEADERS_H | ||
| 47 | echo "generate Makefile" | 47 | echo "generate Makefile" |
| 48 | 48 | ||
| 49 | cat << END > ${SRS_MAKEFILE} | 49 | cat << END > ${SRS_MAKEFILE} |
| 50 | -.PHONY: default help clean server _prepare_dir | ||
| 51 | -default: server | 50 | +.PHONY: default help clean server bandwidth _prepare_dir |
| 51 | +default: server bandwidth | ||
| 52 | 52 | ||
| 53 | help: | 53 | help: |
| 54 | - @echo "Usage: make <help>|<clean>|<server>" | 54 | + @echo "Usage: make <help>|<clean>|<server>|<bandwidth>" |
| 55 | @echo " help display this help menu" | 55 | @echo " help display this help menu" |
| 56 | @echo " clean cleanup project" | 56 | @echo " clean cleanup project" |
| 57 | @echo " server build the srs(simple rtmp server) over st(state-threads)" | 57 | @echo " server build the srs(simple rtmp server) over st(state-threads)" |
| 58 | + @echo " bandwidth build the bandwidth test client tool." | ||
| 58 | 59 | ||
| 59 | clean: | 60 | clean: |
| 60 | - (rm -f Makefile; cd ${SRS_OBJS}; rm -rf srs Makefile *.hpp src st_*_load) | 61 | + (rm -f Makefile; cd ${SRS_OBJS}; rm -rf srs bandwidth Makefile *.hpp src st_*_load) |
| 61 | 62 | ||
| 62 | server: _prepare_dir | 63 | server: _prepare_dir |
| 63 | @echo "build the srs(simple rtmp server) over st(state-threads)" | 64 | @echo "build the srs(simple rtmp server) over st(state-threads)" |
| 64 | \$(MAKE) -f ${SRS_OBJS}/${SRS_MAKEFILE} srs | 65 | \$(MAKE) -f ${SRS_OBJS}/${SRS_MAKEFILE} srs |
| 65 | 66 | ||
| 67 | +bandwidth: _prepare_dir | ||
| 68 | + @echo "build the bandwidth test client tool" | ||
| 69 | + \$(MAKE) -f ${SRS_OBJS}/${SRS_MAKEFILE} bandwidth | ||
| 70 | + | ||
| 66 | # the ./configure will generate it. | 71 | # the ./configure will generate it. |
| 67 | _prepare_dir: | 72 | _prepare_dir: |
| 68 | @mkdir -p ${SRS_OBJS} | 73 | @mkdir -p ${SRS_OBJS} |
| @@ -87,7 +92,7 @@ GCC = g++ | @@ -87,7 +92,7 @@ GCC = g++ | ||
| 87 | LINK = \$(GCC) | 92 | LINK = \$(GCC) |
| 88 | AR = ar | 93 | AR = ar |
| 89 | 94 | ||
| 90 | -.PHONY: default srs | 95 | +.PHONY: default srs bandwidth |
| 91 | 96 | ||
| 92 | default: | 97 | default: |
| 93 | 98 | ||
| @@ -124,12 +129,12 @@ CORE_OBJS="${MODULE_OBJS[@]}" | @@ -124,12 +129,12 @@ CORE_OBJS="${MODULE_OBJS[@]}" | ||
| 124 | MODULE_ID="MAIN" | 129 | MODULE_ID="MAIN" |
| 125 | MODULE_DEPENDS=("CORE") | 130 | MODULE_DEPENDS=("CORE") |
| 126 | ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS}) | 131 | ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS}) |
| 127 | -MODULE_FILES=("srs_main_server") | 132 | +MODULE_FILES=("srs_main_server" "srs_main_bandcheck") |
| 128 | MODULE_DIR="src/main" . auto/modules.sh | 133 | MODULE_DIR="src/main" . auto/modules.sh |
| 129 | MAIN_OBJS="${MODULE_OBJS[@].o}" | 134 | MAIN_OBJS="${MODULE_OBJS[@].o}" |
| 130 | 135 | ||
| 131 | # all main entrances | 136 | # all main entrances |
| 132 | -MAIN_ENTRANCES=("srs_main_server") | 137 | +MAIN_ENTRANCES=("srs_main_server" "srs_main_bandcheck") |
| 133 | 138 | ||
| 134 | # srs(simple rtmp server) over st(state-threads) | 139 | # srs(simple rtmp server) over st(state-threads) |
| 135 | ModuleLibFiles=(${LibSTfile}) | 140 | ModuleLibFiles=(${LibSTfile}) |
| @@ -143,6 +148,7 @@ else | @@ -143,6 +148,7 @@ else | ||
| 143 | LINK_OPTIONS="-ldl" | 148 | LINK_OPTIONS="-ldl" |
| 144 | fi | 149 | fi |
| 145 | BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" SO_PATH="" . auto/apps.sh | 150 | BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" SO_PATH="" . auto/apps.sh |
| 151 | +BUILD_KEY="bandwidth" APP_MAIN="srs_main_bandcheck" APP_NAME="bandwidth" SO_PATH="" . auto/apps.sh | ||
| 146 | 152 | ||
| 147 | echo 'configure ok! ' | 153 | echo 'configure ok! ' |
| 148 | 154 |
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | ''' | 2 | ''' |
| 3 | The MIT License (MIT) | 3 | The MIT License (MIT) |
| 4 | 4 | ||
| 5 | -Copyright (c) 2013 winlin | 5 | +Copyright (c) 2013-2014 winlin |
| 6 | 6 | ||
| 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 8 | this software and associated documentation files (the "Software"), to deal in | 8 | this software and associated documentation files (the "Software"), to deal in |
| @@ -463,7 +463,7 @@ if __name__ != "__main__": | @@ -463,7 +463,7 @@ if __name__ != "__main__": | ||
| 463 | 463 | ||
| 464 | # check the user options | 464 | # check the user options |
| 465 | if len(sys.argv) <= 1: | 465 | if len(sys.argv) <= 1: |
| 466 | - print "SRS api callback server, Copyright (c) 2013 winlin" | 466 | + print "SRS api callback server, Copyright (c) 2013-2014 winlin" |
| 467 | print "Usage: python %s <port>"%(sys.argv[0]) | 467 | print "Usage: python %s <port>"%(sys.argv[0]) |
| 468 | print " port: the port to listen at." | 468 | print " port: the port to listen at." |
| 469 | print "For example:" | 469 | print "For example:" |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -417,38 +417,38 @@ public: | @@ -417,38 +417,38 @@ public: | ||
| 417 | */ | 417 | */ |
| 418 | enum TSPESStreamId | 418 | enum TSPESStreamId |
| 419 | { | 419 | { |
| 420 | - PES_program_stream_map = 0b10111100, // 0xbc | ||
| 421 | - PES_private_stream_1 = 0b10111101, // 0xbd | ||
| 422 | - PES_padding_stream = 0b10111110, // 0xbe | ||
| 423 | - PES_private_stream_2 = 0b10111111, // 0xbf | 420 | + PES_program_stream_map = 0xbc, // 0b10111100 |
| 421 | + PES_private_stream_1 = 0xbd, // 0b10111101 | ||
| 422 | + PES_padding_stream = 0xbe, // 0b10111110 | ||
| 423 | + PES_private_stream_2 = 0xbf, // 0b10111111 | ||
| 424 | 424 | ||
| 425 | // 110x xxxx | 425 | // 110x xxxx |
| 426 | // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC | 426 | // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC |
| 427 | // 14496-3 audio stream number x xxxx | 427 | // 14496-3 audio stream number x xxxx |
| 428 | // (stream_id>>5)&0x07 == PES_audio_prefix | 428 | // (stream_id>>5)&0x07 == PES_audio_prefix |
| 429 | - PES_audio_prefix = 0b110, | 429 | + PES_audio_prefix = 0x06, // 0b110 |
| 430 | 430 | ||
| 431 | // 1110 xxxx | 431 | // 1110 xxxx |
| 432 | // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC | 432 | // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC |
| 433 | // 14496-2 video stream number xxxx | 433 | // 14496-2 video stream number xxxx |
| 434 | // (stream_id>>4)&0x0f == PES_audio_prefix | 434 | // (stream_id>>4)&0x0f == PES_audio_prefix |
| 435 | - PES_video_prefix = 0b1110, | 435 | + PES_video_prefix = 0x0e, // 0b1110 |
| 436 | 436 | ||
| 437 | - PES_ECM_stream = 0b11110000, // 0xf0 | ||
| 438 | - PES_EMM_stream = 0b11110001, // 0xf1 | ||
| 439 | - PES_DSMCC_stream = 0b11110010, // 0xf2 | ||
| 440 | - PES_13522_stream = 0b11110011, // 0xf3 | ||
| 441 | - PES_H_222_1_type_A = 0b11110100, // 0xf4 | ||
| 442 | - PES_H_222_1_type_B = 0b11110101, // 0xf5 | ||
| 443 | - PES_H_222_1_type_C = 0b11110110, // 0xf6 | ||
| 444 | - PES_H_222_1_type_D = 0b11110111, // 0xf7 | ||
| 445 | - PES_H_222_1_type_E = 0b11111000, // 0xf8 | ||
| 446 | - PES_ancillary_stream = 0b11111001, // 0xf9 | ||
| 447 | - PES_SL_packetized_stream = 0b11111010, // 0xfa | ||
| 448 | - PES_FlexMux_stream = 0b11111011, // 0xfb | 437 | + PES_ECM_stream = 0xf0, // 0b11110000 |
| 438 | + PES_EMM_stream = 0xf1, // 0b11110001 | ||
| 439 | + PES_DSMCC_stream = 0xf2, // 0b11110010 | ||
| 440 | + PES_13522_stream = 0xf3, // 0b11110011 | ||
| 441 | + PES_H_222_1_type_A = 0xf4, // 0b11110100 | ||
| 442 | + PES_H_222_1_type_B = 0xf5, // 0b11110101 | ||
| 443 | + PES_H_222_1_type_C = 0xf6, // 0b11110110 | ||
| 444 | + PES_H_222_1_type_D = 0xf7, // 0b11110111 | ||
| 445 | + PES_H_222_1_type_E = 0xf8, // 0b11111000 | ||
| 446 | + PES_ancillary_stream = 0xf9, // 0b11111001 | ||
| 447 | + PES_SL_packetized_stream = 0xfa, // 0b11111010 | ||
| 448 | + PES_FlexMux_stream = 0xfb, // 0b11111011 | ||
| 449 | // reserved data stream | 449 | // reserved data stream |
| 450 | // 1111 1100 … 1111 1110 | 450 | // 1111 1100 … 1111 1110 |
| 451 | - PES_program_stream_directory= 0b11111111, // 0xff | 451 | + PES_program_stream_directory= 0xff, // 0b11111111 |
| 452 | }; | 452 | }; |
| 453 | 453 | ||
| 454 | 454 |
| 1 | +<<<<<<< HEAD | ||
| 1 | // for bw to init url | 2 | // for bw to init url |
| 2 | // url: scheme://host:port/path?query#fragment | 3 | // url: scheme://host:port/path?query#fragment |
| 3 | function srs_init_bwt(rtmp_url, hls_url) { | 4 | function srs_init_bwt(rtmp_url, hls_url) { |
| @@ -24,4 +25,141 @@ function srs_bwt_check_url(url) { | @@ -24,4 +25,141 @@ function srs_bwt_check_url(url) { | ||
| 24 | function srs_bwt_build_default_url() { | 25 | function srs_bwt_build_default_url() { |
| 25 | var url_default = "rtmp://" + window.location.host + ":" + 1935 + "/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"; | 26 | var url_default = "rtmp://" + window.location.host + ":" + 1935 + "/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"; |
| 26 | return url_default; | 27 | return url_default; |
| 28 | +======= | ||
| 29 | +/** | ||
| 30 | +* the SrsBandwidth object. | ||
| 31 | +* @param container the html container id. | ||
| 32 | +* @param width a float value specifies the width of bandwidth. | ||
| 33 | +* @param height a float value specifies the height of bandwidth. | ||
| 34 | +* @param private_object [optional] an object that used as private object, | ||
| 35 | +* for example, the logic chat object which owner this bandwidth. | ||
| 36 | +*/ | ||
| 37 | +function SrsBandwidth(container, width, height, private_object) { | ||
| 38 | + if (!SrsBandwidth.__id) { | ||
| 39 | + SrsBandwidth.__id = 100; | ||
| 40 | + } | ||
| 41 | + if (!SrsBandwidth.__bandwidths) { | ||
| 42 | + SrsBandwidth.__bandwidths = []; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + SrsBandwidth.__bandwidths.push(this); | ||
| 46 | + | ||
| 47 | + this.private_object = private_object; | ||
| 48 | + this.container = container; | ||
| 49 | + this.width = width; | ||
| 50 | + this.height = height; | ||
| 51 | + this.id = SrsBandwidth.__id++; | ||
| 52 | + this.stream_url = null; | ||
| 53 | + this.callbackObj = null; | ||
| 54 | + | ||
| 55 | + // the callback set data. | ||
| 56 | + this.percent = 0; | ||
| 57 | + this.status = ""; | ||
| 58 | +} | ||
| 59 | +/** | ||
| 60 | +* user can set some callback, then start the bandwidth. | ||
| 61 | +* @param url the bandwidth test url. | ||
| 62 | +* callbacks: | ||
| 63 | +* on_bandwidth_ready():void, when srs bandwidth ready, user can play. | ||
| 64 | +* on_update_progress(percent:Number):void, when srs bandwidth update the progress. | ||
| 65 | +* percent:Number 100 means 100%. | ||
| 66 | +* on_update_status(status:String):void, when srs bandwidth update the status. | ||
| 67 | +* status:String the human readable status text. | ||
| 68 | +*/ | ||
| 69 | +SrsBandwidth.prototype.start = function(url) { | ||
| 70 | + if (url) { | ||
| 71 | + this.stream_url = url; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + // embed the flash. | ||
| 75 | + var flashvars = {}; | ||
| 76 | + flashvars.id = this.id; | ||
| 77 | + flashvars.on_bandwidth_ready = "__srs_on_bandwidth_ready"; | ||
| 78 | + flashvars.on_update_progress = "__srs_on_update_progress"; | ||
| 79 | + flashvars.on_update_status = "__srs_on_update_status"; | ||
| 80 | + | ||
| 81 | + var params = {}; | ||
| 82 | + params.wmode = "opaque"; | ||
| 83 | + params.allowFullScreen = "true"; | ||
| 84 | + params.allowScriptAccess = "always"; | ||
| 85 | + | ||
| 86 | + var attributes = {}; | ||
| 87 | + | ||
| 88 | + var self = this; | ||
| 89 | + | ||
| 90 | + swfobject.embedSWF( | ||
| 91 | + "srs_bwt/release/srs_bwt.swf?_version="+srs_get_version_code(), | ||
| 92 | + this.container, | ||
| 93 | + this.width, this.height, | ||
| 94 | + "11.1.0", "js/AdobeFlashbandwidthInstall.swf", | ||
| 95 | + flashvars, params, attributes, | ||
| 96 | + function(callbackObj){ | ||
| 97 | + self.callbackObj = callbackObj; | ||
| 98 | + } | ||
| 99 | + ); | ||
| 100 | + | ||
| 101 | + return this; | ||
| 102 | +} | ||
| 103 | +/** | ||
| 104 | +* play the stream. | ||
| 105 | +* @param stream_url the url of stream, rtmp or http. | ||
| 106 | +* @param volume the volume, 0 is mute, 1 is 100%, 2 is 200%. | ||
| 107 | +*/ | ||
| 108 | +SrsBandwidth.prototype.check_bandwidth = function(url) { | ||
| 109 | + this.stop(); | ||
| 110 | + SrsBandwidth.__bandwidths.push(this); | ||
| 111 | + | ||
| 112 | + if (url) { | ||
| 113 | + this.stream_url = url; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + this.callbackObj.ref.__check_bandwidth(this.stream_url); | ||
| 117 | +} | ||
| 118 | +SrsBandwidth.prototype.stop = function(url) { | ||
| 119 | + for (var i = 0; i < SrsBandwidth.__bandwidths.length; i++) { | ||
| 120 | + var bandwidth = SrsBandwidth.__bandwidths[i]; | ||
| 121 | + | ||
| 122 | + if (bandwidth.id != this.id) { | ||
| 123 | + continue; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + SrsBandwidth.__bandwidths.splice(i, 1); | ||
| 127 | + break; | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + this.callbackObj.ref.__stop(); | ||
| 131 | +} | ||
| 132 | +SrsBandwidth.prototype.on_bandwidth_ready = function() { | ||
| 133 | +} | ||
| 134 | +SrsBandwidth.prototype.on_update_progress = function(percent) { | ||
| 135 | +} | ||
| 136 | +SrsBandwidth.prototype.on_update_status = function(status) { | ||
| 137 | +} | ||
| 138 | +function __srs_find_bandwidth(id) { | ||
| 139 | + for (var i = 0; i < SrsBandwidth.__bandwidths.length; i++) { | ||
| 140 | + var bandwidth = SrsBandwidth.__bandwidths[i]; | ||
| 141 | + | ||
| 142 | + if (bandwidth.id != id) { | ||
| 143 | + continue; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + return bandwidth; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + throw new Error("bandwidth not found. id=" + id); | ||
| 150 | +} | ||
| 151 | +function __srs_on_bandwidth_ready(id) { | ||
| 152 | + var bandwidth = __srs_find_bandwidth(id); | ||
| 153 | + bandwidth.on_bandwidth_ready(); | ||
| 154 | +} | ||
| 155 | +function __srs_on_update_progress(id, percent) { | ||
| 156 | + var bandwidth = __srs_find_bandwidth(id); | ||
| 157 | + bandwidth.percent = percent; | ||
| 158 | + bandwidth.on_update_progress(percent); | ||
| 159 | +} | ||
| 160 | +function __srs_on_update_status(id, status) { | ||
| 161 | + var bandwidth = __srs_find_bandwidth(id); | ||
| 162 | + bandwidth.status = status; | ||
| 163 | + bandwidth.on_update_status(status); | ||
| 164 | +>>>>>>> upstream/master | ||
| 27 | } | 165 | } |
| @@ -10,7 +10,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; } | @@ -10,7 +10,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; } | ||
| 10 | function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } | 10 | function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } |
| 11 | 11 | ||
| 12 | // to query the swf anti cache. | 12 | // to query the swf anti cache. |
| 13 | -function srs_get_version_code() { return "1.17"; } | 13 | +function srs_get_version_code() { return "1.19"; } |
| 14 | // get the default vhost for players. | 14 | // get the default vhost for players. |
| 15 | function srs_get_player_vhost() { return "players"; } | 15 | function srs_get_player_vhost() { return "players"; } |
| 16 | // the api server port, for chat room. | 16 | // the api server port, for chat room. |
| @@ -80,6 +80,18 @@ function build_default_publish_rtmp_url() { | @@ -80,6 +80,18 @@ function build_default_publish_rtmp_url() { | ||
| 80 | return "rtmp://" + server + ":" + port + "/" + app + "...vhost..." + vhost + "/" + stream; | 80 | return "rtmp://" + server + ":" + port + "/" + app + "...vhost..." + vhost + "/" + stream; |
| 81 | } | 81 | } |
| 82 | } | 82 | } |
| 83 | +// for the bandwidth tool to init page | ||
| 84 | +function build_default_bandwidth_rtmp_url() { | ||
| 85 | + var query = parse_query_string(); | ||
| 86 | + | ||
| 87 | + var server = (query.server == undefined)? window.location.hostname:query.server; | ||
| 88 | + var port = (query.port == undefined)? 1935:query.port; | ||
| 89 | + var vhost = "bandcheck.srs.com"; | ||
| 90 | + var app = (query.app == undefined)? "app":query.app; | ||
| 91 | + var key = (query.key == undefined)? "35c9b402c12a7246868752e2878f7e0e":query.key; | ||
| 92 | + | ||
| 93 | + return "rtmp://" + server + ":" + port + "/" + app + "?key=" + key + "&vhost=" + vhost; | ||
| 94 | +} | ||
| 83 | 95 | ||
| 84 | /** | 96 | /** |
| 85 | @param server the ip of server. default to window.location.hostname | 97 | @param server the ip of server. default to window.location.hostname |
| @@ -139,6 +151,15 @@ function srs_init_publish(rtmp_url) { | @@ -139,6 +151,15 @@ function srs_init_publish(rtmp_url) { | ||
| 139 | $(rtmp_url).val(build_default_publish_rtmp_url()); | 151 | $(rtmp_url).val(build_default_publish_rtmp_url()); |
| 140 | } | 152 | } |
| 141 | } | 153 | } |
| 154 | +// for bw to init url | ||
| 155 | +// url: scheme://host:port/path?query#fragment | ||
| 156 | +function srs_init_bwt(rtmp_url, hls_url) { | ||
| 157 | + update_nav(); | ||
| 158 | + | ||
| 159 | + if (rtmp_url) { | ||
| 160 | + $(rtmp_url).val(build_default_bandwidth_rtmp_url()); | ||
| 161 | + } | ||
| 162 | +} | ||
| 142 | 163 | ||
| 143 | // check whether can republish | 164 | // check whether can republish |
| 144 | function srs_can_republish() { | 165 | function srs_can_republish() { |
| @@ -63,7 +63,7 @@ SrsPlayer.prototype.start = function(url) { | @@ -63,7 +63,7 @@ SrsPlayer.prototype.start = function(url) { | ||
| 63 | "srs_player/release/srs_player.swf?_version="+srs_get_version_code(), | 63 | "srs_player/release/srs_player.swf?_version="+srs_get_version_code(), |
| 64 | this.container, | 64 | this.container, |
| 65 | this.width, this.height, | 65 | this.width, this.height, |
| 66 | - "11.1", "js/AdobeFlashPlayerInstall.swf", | 66 | + "11.1.0", "js/AdobeFlashPlayerInstall.swf", |
| 67 | flashvars, params, attributes, | 67 | flashvars, params, attributes, |
| 68 | function(callbackObj){ | 68 | function(callbackObj){ |
| 69 | self.callbackObj = callbackObj; | 69 | self.callbackObj = callbackObj; |
| @@ -73,7 +73,7 @@ SrsPublisher.prototype.start = function() { | @@ -73,7 +73,7 @@ SrsPublisher.prototype.start = function() { | ||
| 73 | "srs_publisher/release/srs_publisher.swf?_version="+srs_get_version_code(), | 73 | "srs_publisher/release/srs_publisher.swf?_version="+srs_get_version_code(), |
| 74 | this.container, | 74 | this.container, |
| 75 | this.width, this.height, | 75 | this.width, this.height, |
| 76 | - "11.1", "js/AdobeFlashPlayerInstall.swf", | 76 | + "11.1.0", "js/AdobeFlashPlayerInstall.swf", |
| 77 | flashvars, params, attributes, | 77 | flashvars, params, attributes, |
| 78 | function(callbackObj){ | 78 | function(callbackObj){ |
| 79 | self.callbackObj = callbackObj; | 79 | self.callbackObj = callbackObj; |
| @@ -13,6 +13,21 @@ function padding(number, length, prefix) { | @@ -13,6 +13,21 @@ function padding(number, length, prefix) { | ||
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | * parse the query string to object. | 15 | * parse the query string to object. |
| 16 | +* parse the url location object as: host(hostname:http_port), pathname(dir/filename) | ||
| 17 | +* for example, url http://192.168.1.168:1980/ui/players.html?vhost=player.vhost.com&app=test&stream=livestream | ||
| 18 | +* parsed to object: | ||
| 19 | +{ | ||
| 20 | + host : "192.168.1.168:1980", | ||
| 21 | + hostname : "192.168.1.168", | ||
| 22 | + http_port : 1980, | ||
| 23 | + pathname : "/ui/players.html", | ||
| 24 | + dir : "/ui", | ||
| 25 | + filename : "/players.html", | ||
| 26 | + | ||
| 27 | + vhost : "player.vhost.com", | ||
| 28 | + app : "test", | ||
| 29 | + stream : "livestream" | ||
| 30 | +} | ||
| 16 | */ | 31 | */ |
| 17 | function parse_query_string(){ | 32 | function parse_query_string(){ |
| 18 | var obj = {}; | 33 | var obj = {}; |
| @@ -12,13 +12,18 @@ | @@ -12,13 +12,18 @@ | ||
| 12 | <script type="text/javascript" src="js/srs.player.js"></script> | 12 | <script type="text/javascript" src="js/srs.player.js"></script> |
| 13 | <script type="text/javascript" src="js/srs.publisher.js"></script> | 13 | <script type="text/javascript" src="js/srs.publisher.js"></script> |
| 14 | <script type="text/javascript" src="js/srs.utility.js"></script> | 14 | <script type="text/javascript" src="js/srs.utility.js"></script> |
| 15 | +<<<<<<< HEAD | ||
| 15 | <script type="text/javascript" src="js/srs.utility.js"></script> | 16 | <script type="text/javascript" src="js/srs.utility.js"></script> |
| 16 | <script type="text/javascript" src="js/srs.bandwidth.js"></script> | 17 | <script type="text/javascript" src="js/srs.bandwidth.js"></script> |
| 18 | +======= | ||
| 19 | + <script type="text/javascript" src="js/srs.bandwidth.js"></script> | ||
| 20 | +>>>>>>> upstream/master | ||
| 17 | <style> | 21 | <style> |
| 18 | body{ | 22 | body{ |
| 19 | padding-top: 55px; | 23 | padding-top: 55px; |
| 20 | } | 24 | } |
| 21 | #main_modal { | 25 | #main_modal { |
| 26 | +<<<<<<< HEAD | ||
| 22 | width: 600px; | 27 | width: 600px; |
| 23 | margin-left: -300px; | 28 | margin-left: -300px; |
| 24 | } | 29 | } |
| @@ -119,6 +124,56 @@ | @@ -119,6 +124,56 @@ | ||
| 119 | } | 124 | } |
| 120 | ); | 125 | ); |
| 121 | }); | 126 | }); |
| 127 | +======= | ||
| 128 | + width: 700px; | ||
| 129 | + margin-left: -350px; | ||
| 130 | + } | ||
| 131 | + </style> | ||
| 132 | + <script type="text/javascript"> | ||
| 133 | + var bandwidth = null; | ||
| 134 | + | ||
| 135 | + $(function(){ | ||
| 136 | + srs_init_bwt("#txt_url"); | ||
| 137 | + | ||
| 138 | + $("#btn_play").click(on_click_play); | ||
| 139 | + $("#main_modal").on("show", on_start_bandwidth_test); | ||
| 140 | + $("#main_modal").on("hide", on_stop_bandwidth_test); | ||
| 141 | + }); | ||
| 142 | + | ||
| 143 | + function on_click_play() { | ||
| 144 | + $("#check_status").text(""); | ||
| 145 | + $("#progress_bar").width("0%"); | ||
| 146 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
| 147 | + } | ||
| 148 | + function on_start_bandwidth_test() { | ||
| 149 | + $("#div_container").remove(); | ||
| 150 | + | ||
| 151 | + var div_container = $("<div/>"); | ||
| 152 | + $(div_container).attr("id", "div_container"); | ||
| 153 | + $("#player").append(div_container); | ||
| 154 | + | ||
| 155 | + var player = $("<div/>"); | ||
| 156 | + $(player).attr("id", "player_id"); | ||
| 157 | + $(div_container).append(player); | ||
| 158 | + | ||
| 159 | + var url = $("#txt_url").val(); | ||
| 160 | + | ||
| 161 | + bandwidth = new SrsBandwidth("player_id", 100, 1); | ||
| 162 | + bandwidth.on_bandwidth_ready = function() { | ||
| 163 | + this.check_bandwidth(url); | ||
| 164 | + } | ||
| 165 | + bandwidth.on_update_progress = function(percent) { | ||
| 166 | + $("#progress_bar").width(percent + "%"); | ||
| 167 | + } | ||
| 168 | + bandwidth.on_update_status = function(status) { | ||
| 169 | + $("#check_status").text(status); | ||
| 170 | + } | ||
| 171 | + bandwidth.start(url); | ||
| 172 | + } | ||
| 173 | + function on_stop_bandwidth_test() { | ||
| 174 | + bandwidth.stop(); | ||
| 175 | + } | ||
| 176 | +>>>>>>> upstream/master | ||
| 122 | </script> | 177 | </script> |
| 123 | </head> | 178 | </head> |
| 124 | <body> | 179 | <body> |
| @@ -141,6 +196,7 @@ | @@ -141,6 +196,7 @@ | ||
| 141 | </div> | 196 | </div> |
| 142 | </div> | 197 | </div> |
| 143 | <div class="container"> | 198 | <div class="container"> |
| 199 | +<<<<<<< HEAD | ||
| 144 | 200 | ||
| 145 | <div class="form-inline"> | 201 | <div class="form-inline"> |
| 146 | URL: | 202 | URL: |
| @@ -164,15 +220,49 @@ | @@ -164,15 +220,49 @@ | ||
| 164 | </div> | 220 | </div> |
| 165 | <span id="check_status1"><font ><strong id="check_status">status</strong></font> </span> | 221 | <span id="check_status1"><font ><strong id="check_status">status</strong></font> </span> |
| 166 | 222 | ||
| 223 | +======= | ||
| 224 | + <div class="alert alert-info fade in"> | ||
| 225 | + <button type="button" class="close" data-dismiss="alert">×</button> | ||
| 226 | + <strong><span>Usage:</span></strong> <span>点击“开始测速”即可测带宽,最大可测试带宽由服务器限制</span> | ||
| 227 | + </div> | ||
| 228 | + <div class="form-inline"> | ||
| 229 | + URL: | ||
| 230 | + <input type="text" id="txt_url" class="input-xxlarge" value=""></input> | ||
| 231 | + <button class="btn btn-primary" id="btn_play">开始测速</button> | ||
| 232 | + </div> | ||
| 233 | + <div id="main_modal" class="modal hide fade"> | ||
| 234 | + <div class="modal-header"> | ||
| 235 | + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||
| 236 | + <h3>SRS Bandwidth Check</h3> | ||
| 237 | + </div> | ||
| 238 | + <div class="modal-body"> | ||
| 239 | + <div class="row-fluid"> | ||
| 240 | + <div class="span1"></div> | ||
| 241 | + <div class="span10"> | ||
| 242 | + <div class="progress progress-striped active" id="pb_buffer_bg"> | ||
| 243 | + <div class="bar" style="width: 0%;" id="progress_bar"></div> | ||
| 244 | + </div> | ||
| 245 | + </div> | ||
| 246 | + <div class="span1"></div> | ||
| 247 | + </div> | ||
| 248 | + <span id="check_status">status</span> | ||
| 249 | + </div> | ||
| 250 | +>>>>>>> upstream/master | ||
| 167 | <div class="modal-footer"> | 251 | <div class="modal-footer"> |
| 168 | <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true"> 关闭 </button> | 252 | <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true"> 关闭 </button> |
| 169 | </div> | 253 | </div> |
| 170 | </div> | 254 | </div> |
| 255 | +<<<<<<< HEAD | ||
| 171 | 256 | ||
| 257 | +======= | ||
| 258 | +>>>>>>> upstream/master | ||
| 172 | <hr> | 259 | <hr> |
| 173 | <footer> | 260 | <footer> |
| 174 | <p><a href="https://github.com/winlinvip/simple-rtmp-server">SRS Team © 2013</a></p> | 261 | <p><a href="https://github.com/winlinvip/simple-rtmp-server">SRS Team © 2013</a></p> |
| 175 | </footer> | 262 | </footer> |
| 263 | + <div class="container"> | ||
| 264 | + <div id="player"></div> | ||
| 265 | + </div> | ||
| 176 | </div> | 266 | </div> |
| 177 | </body> | 267 | </body> |
| 178 | 268 |
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| 2 | <actionScriptProperties analytics="false" mainApplicationPath="srs_bwt.as" projectUUID="00251213-e6a2-4dd5-a033-125cc78f843c" version="10"> | 2 | <actionScriptProperties analytics="false" mainApplicationPath="srs_bwt.as" projectUUID="00251213-e6a2-4dd5-a033-125cc78f843c" version="10"> |
| 3 | +<<<<<<< HEAD | ||
| 3 | <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="true" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin-debug" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true"> | 4 | <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="true" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin-debug" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true"> |
| 5 | +======= | ||
| 6 | + <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="true" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="true" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="release" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true"> | ||
| 7 | +>>>>>>> upstream/master | ||
| 4 | <compilerSourcePath/> | 8 | <compilerSourcePath/> |
| 5 | <libraryPath defaultLinkType="0"> | 9 | <libraryPath defaultLinkType="0"> |
| 6 | <libraryPathEntry kind="4" path=""> | 10 | <libraryPathEntry kind="4" path=""> |
| @@ -17,6 +21,7 @@ | @@ -17,6 +21,7 @@ | ||
| 17 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="false"/> | 21 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="false"/> |
| 18 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/> | 22 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/> |
| 19 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="false"/> | 23 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="false"/> |
| 24 | +<<<<<<< HEAD | ||
| 20 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/videoPlayer.swc" useDefaultLinkType="false"/> | 25 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/videoPlayer.swc" useDefaultLinkType="false"/> |
| 21 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp_air.swc" useDefaultLinkType="false"/> | 26 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp_air.swc" useDefaultLinkType="false"/> |
| 22 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/> | 27 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/> |
| @@ -24,6 +29,15 @@ | @@ -24,6 +29,15 @@ | ||
| 24 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/> | 29 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/> |
| 25 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flash-integration.swc" useDefaultLinkType="false"/> | 30 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flash-integration.swc" useDefaultLinkType="false"/> |
| 26 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/> | 31 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/> |
| 32 | +======= | ||
| 33 | + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/> | ||
| 34 | + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp_air.swc" useDefaultLinkType="false"/> | ||
| 35 | + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/videoPlayer.swc" useDefaultLinkType="false"/> | ||
| 36 | + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark_dmv.swc" useDefaultLinkType="false"/> | ||
| 37 | + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/> | ||
| 38 | + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/> | ||
| 39 | + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flash-integration.swc" useDefaultLinkType="false"/> | ||
| 40 | +>>>>>>> upstream/master | ||
| 27 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_flashflexkit.swc" useDefaultLinkType="false"/> | 41 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_flashflexkit.swc" useDefaultLinkType="false"/> |
| 28 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/> | 42 | <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/> |
| 29 | </excludedEntries> | 43 | </excludedEntries> |
| @@ -20,10 +20,22 @@ package | @@ -20,10 +20,22 @@ package | ||
| 20 | 20 | ||
| 21 | public class srs_bwt extends Sprite | 21 | public class srs_bwt extends Sprite |
| 22 | { | 22 | { |
| 23 | +<<<<<<< HEAD | ||
| 23 | private var connection:NetConnection; | 24 | private var connection:NetConnection; |
| 24 | 25 | ||
| 25 | private var updatePlayProgressTimer:Timer; | 26 | private var updatePlayProgressTimer:Timer; |
| 26 | private var elapTimer:SrsElapsedTimer; | 27 | private var elapTimer:SrsElapsedTimer; |
| 28 | +======= | ||
| 29 | + private var connection:NetConnection = null; | ||
| 30 | + | ||
| 31 | + private var updatePlayProgressTimer:Timer = null; | ||
| 32 | + private var elapTimer:SrsElapsedTimer = null; | ||
| 33 | + | ||
| 34 | + // user set id. | ||
| 35 | + private var js_id:String = null; | ||
| 36 | + // play param url. | ||
| 37 | + private var user_url:String = null; | ||
| 38 | +>>>>>>> upstream/master | ||
| 27 | 39 | ||
| 28 | // server ip get from server | 40 | // server ip get from server |
| 29 | private var server_ip:String; | 41 | private var server_ip:String; |
| @@ -32,8 +44,13 @@ package | @@ -32,8 +44,13 @@ package | ||
| 32 | private var stop_pub:Boolean = false; | 44 | private var stop_pub:Boolean = false; |
| 33 | 45 | ||
| 34 | // js interface | 46 | // js interface |
| 47 | +<<<<<<< HEAD | ||
| 35 | private var js_update_progress:String; | 48 | private var js_update_progress:String; |
| 36 | private var js_progress_reset:String; | 49 | private var js_progress_reset:String; |
| 50 | +======= | ||
| 51 | + private var js_on_player_ready:String; | ||
| 52 | + private var js_update_progress:String; | ||
| 53 | +>>>>>>> upstream/master | ||
| 37 | private var js_update_status:String; | 54 | private var js_update_status:String; |
| 38 | 55 | ||
| 39 | private var value_progressbar:Number = 0; | 56 | private var value_progressbar:Number = 0; |
| @@ -44,10 +61,26 @@ package | @@ -44,10 +61,26 @@ package | ||
| 44 | 61 | ||
| 45 | public function srs_bwt() | 62 | public function srs_bwt() |
| 46 | { | 63 | { |
| 64 | +<<<<<<< HEAD | ||
| 65 | +======= | ||
| 66 | + if (!this.stage) { | ||
| 67 | + this.addEventListener(Event.ADDED_TO_STAGE, this.system_on_add_to_stage); | ||
| 68 | + } else { | ||
| 69 | + this.system_on_add_to_stage(null); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * system event callback, when this control added to stage. | ||
| 75 | + * the main function. | ||
| 76 | + */ | ||
| 77 | + private function system_on_add_to_stage(evt:Event):void { | ||
| 78 | +>>>>>>> upstream/master | ||
| 47 | this.stage.scaleMode = StageScaleMode.NO_SCALE; | 79 | this.stage.scaleMode = StageScaleMode.NO_SCALE; |
| 48 | this.stage.align = StageAlign.TOP_LEFT; | 80 | this.stage.align = StageAlign.TOP_LEFT; |
| 49 | 81 | ||
| 50 | var flashvars:Object = this.root.loaderInfo.parameters; | 82 | var flashvars:Object = this.root.loaderInfo.parameters; |
| 83 | +<<<<<<< HEAD | ||
| 51 | this.js_update_progress = flashvars.update_progress; | 84 | this.js_update_progress = flashvars.update_progress; |
| 52 | this.js_progress_reset = flashvars.progress_reset; | 85 | this.js_progress_reset = flashvars.progress_reset; |
| 53 | this.js_update_status = flashvars.update_status; | 86 | this.js_update_status = flashvars.update_status; |
| @@ -58,11 +91,56 @@ package | @@ -58,11 +91,56 @@ package | ||
| 58 | myMenu.customItems.push(new ContextMenuItem("Srs 带宽测试工具 0.1", true)); | 91 | myMenu.customItems.push(new ContextMenuItem("Srs 带宽测试工具 0.1", true)); |
| 59 | this.contextMenu = myMenu; | 92 | this.contextMenu = myMenu; |
| 60 | 93 | ||
| 94 | +======= | ||
| 95 | + | ||
| 96 | + if (!flashvars.hasOwnProperty("id")) { | ||
| 97 | + throw new Error("must specifies the id"); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + this.js_id = flashvars.id; | ||
| 101 | + this.js_on_player_ready = flashvars.on_bandwidth_ready; | ||
| 102 | + this.js_update_progress = flashvars.on_update_progress; | ||
| 103 | + this.js_update_status = flashvars.on_update_status; | ||
| 104 | + | ||
| 105 | + // init context menu | ||
| 106 | + var myMenu:ContextMenu = new ContextMenu(); | ||
| 107 | + myMenu.hideBuiltInItems(); | ||
| 108 | + myMenu.customItems.push(new ContextMenuItem("SRS 带宽测试工具", true)); | ||
| 109 | + this.contextMenu = myMenu; | ||
| 110 | + | ||
| 111 | + flash.utils.setTimeout(this.system_on_js_ready, 0); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + /** | ||
| 115 | + * system callack event, when js ready, register callback for js. | ||
| 116 | + * the actual main function. | ||
| 117 | + */ | ||
| 118 | + private function system_on_js_ready():void { | ||
| 119 | + if (!flash.external.ExternalInterface.available) { | ||
| 120 | + trace("js not ready, try later."); | ||
| 121 | + flash.utils.setTimeout(this.system_on_js_ready, 100); | ||
| 122 | + return; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + flash.external.ExternalInterface.addCallback("__check_bandwidth", this.js_call_check_bandwidth); | ||
| 126 | + flash.external.ExternalInterface.addCallback("__stop", this.js_call_stop); | ||
| 127 | + | ||
| 128 | + flash.external.ExternalInterface.call(this.js_on_player_ready, this.js_id); | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + private function js_call_check_bandwidth(url:String):void { | ||
| 132 | + js_call_stop(); | ||
| 133 | + | ||
| 134 | +>>>>>>> upstream/master | ||
| 61 | // init connection | 135 | // init connection |
| 62 | connection = new NetConnection; | 136 | connection = new NetConnection; |
| 63 | connection.client = this; | 137 | connection.client = this; |
| 64 | connection.addEventListener(NetStatusEvent.NET_STATUS, onStatus); | 138 | connection.addEventListener(NetStatusEvent.NET_STATUS, onStatus); |
| 139 | +<<<<<<< HEAD | ||
| 65 | connection.connect(flashvars.url); | 140 | connection.connect(flashvars.url); |
| 141 | +======= | ||
| 142 | + connection.connect(url); | ||
| 143 | +>>>>>>> upstream/master | ||
| 66 | //connection.connect("rtmp://192.168.8.234:1935/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"); | 144 | //connection.connect("rtmp://192.168.8.234:1935/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"); |
| 67 | 145 | ||
| 68 | // for play to update progress bar | 146 | // for play to update progress bar |
| @@ -73,10 +151,43 @@ package | @@ -73,10 +151,43 @@ package | ||
| 73 | updatePlayProgressTimer.addEventListener(TimerEvent.TIMER, onTimerTimeout); | 151 | updatePlayProgressTimer.addEventListener(TimerEvent.TIMER, onTimerTimeout); |
| 74 | updatePlayProgressTimer.start(); | 152 | updatePlayProgressTimer.start(); |
| 75 | } | 153 | } |
| 154 | +<<<<<<< HEAD | ||
| 76 | 155 | ||
| 77 | // get NetConnection NetStatusEvent | 156 | // get NetConnection NetStatusEvent |
| 78 | public function onStatus(evt:NetStatusEvent) : void{ | 157 | public function onStatus(evt:NetStatusEvent) : void{ |
| 79 | trace(evt.info.code); | 158 | trace(evt.info.code); |
| 159 | +======= | ||
| 160 | + private function js_call_stop():void { | ||
| 161 | + if (connection) { | ||
| 162 | + connection.close(); | ||
| 163 | + connection = null; | ||
| 164 | + } | ||
| 165 | + if (updatePlayProgressTimer) { | ||
| 166 | + updatePlayProgressTimer.stop(); | ||
| 167 | + updatePlayProgressTimer = null; | ||
| 168 | + } | ||
| 169 | + if (elapTimer) { | ||
| 170 | + elapTimer.restart(); | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + // get NetConnection NetStatusEvent | ||
| 175 | + public function onStatus(evt:NetStatusEvent) : void{ | ||
| 176 | + trace(evt.info.code); | ||
| 177 | + | ||
| 178 | + if (evt.info.hasOwnProperty("data") && evt.info.data) { | ||
| 179 | + // for context menu | ||
| 180 | + var customItems:Array = [new ContextMenuItem("SrsPlayer")]; | ||
| 181 | + if (evt.info.data.hasOwnProperty("srs_server")) { | ||
| 182 | + customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); | ||
| 183 | + } | ||
| 184 | + if (evt.info.data.hasOwnProperty("srs_primary_authors")) { | ||
| 185 | + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors)); | ||
| 186 | + } | ||
| 187 | + contextMenu.customItems = customItems; | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | +>>>>>>> upstream/master | ||
| 80 | switch(evt.info.code){ | 191 | switch(evt.info.code){ |
| 81 | case "NetConnection.Connect.Failed": | 192 | case "NetConnection.Connect.Failed": |
| 82 | updateState("连接服务器失败!"); | 193 | updateState("连接服务器失败!"); |
| @@ -92,8 +203,18 @@ package | @@ -92,8 +203,18 @@ package | ||
| 92 | //updateState("连接已断开!"); | 203 | //updateState("连接已断开!"); |
| 93 | break; | 204 | break; |
| 94 | } | 205 | } |
| 206 | +<<<<<<< HEAD | ||
| 95 | 207 | ||
| 96 | } | 208 | } |
| 209 | +======= | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + public function onTimerTimeout(evt:TimerEvent):void | ||
| 213 | + { | ||
| 214 | + value_progressbar = elapTimer.elapsed(); | ||
| 215 | + updateProgess(value_progressbar, max_progressbar); | ||
| 216 | + } | ||
| 217 | +>>>>>>> upstream/master | ||
| 97 | 218 | ||
| 98 | /** | 219 | /** |
| 99 | * NetConnection callback this function, when recv server call "onSrsBandCheckStartPlayBytes" | 220 | * NetConnection callback this function, when recv server call "onSrsBandCheckStartPlayBytes" |
| @@ -104,13 +225,18 @@ package | @@ -104,13 +225,18 @@ package | ||
| 104 | var interval_ms:Number = evt.interval_ms; | 225 | var interval_ms:Number = evt.interval_ms; |
| 105 | 226 | ||
| 106 | connection.call("onSrsBandCheckStartingPlayBytes", null); | 227 | connection.call("onSrsBandCheckStartingPlayBytes", null); |
| 228 | +<<<<<<< HEAD | ||
| 107 | updateState("测试下行带宽(" + server_ip + ")"); | 229 | updateState("测试下行带宽(" + server_ip + ")"); |
| 230 | +======= | ||
| 231 | + updateState("开始测试下行带宽,服务器IP:" + server_ip); | ||
| 232 | +>>>>>>> upstream/master | ||
| 108 | 233 | ||
| 109 | // we suppose play duration_ms = pub duration_ms | 234 | // we suppose play duration_ms = pub duration_ms |
| 110 | max_progressbar = duration_ms * 2; | 235 | max_progressbar = duration_ms * 2; |
| 111 | } | 236 | } |
| 112 | 237 | ||
| 113 | public function onSrsBandCheckPlaying(evt:Object):void{ | 238 | public function onSrsBandCheckPlaying(evt:Object):void{ |
| 239 | +<<<<<<< HEAD | ||
| 114 | 240 | ||
| 115 | } | 241 | } |
| 116 | 242 | ||
| @@ -118,6 +244,8 @@ package | @@ -118,6 +244,8 @@ package | ||
| 118 | { | 244 | { |
| 119 | value_progressbar = elapTimer.elapsed(); | 245 | value_progressbar = elapTimer.elapsed(); |
| 120 | updateProgess(value_progressbar, max_progressbar); | 246 | updateProgess(value_progressbar, max_progressbar); |
| 247 | +======= | ||
| 248 | +>>>>>>> upstream/master | ||
| 121 | } | 249 | } |
| 122 | 250 | ||
| 123 | public function onSrsBandCheckStopPlayBytes(evt:Object):void{ | 251 | public function onSrsBandCheckStopPlayBytes(evt:Object):void{ |
| @@ -133,6 +261,10 @@ package | @@ -133,6 +261,10 @@ package | ||
| 133 | kbps = (int(kbps * 10))/10.0; | 261 | kbps = (int(kbps * 10))/10.0; |
| 134 | 262 | ||
| 135 | flash.utils.setTimeout(stopPlayTest, 0); | 263 | flash.utils.setTimeout(stopPlayTest, 0); |
| 264 | +<<<<<<< HEAD | ||
| 265 | +======= | ||
| 266 | + updateState("下行带宽测试完毕,服务器: " + server_ip + "," + kbps + "kbps,开始测试上行带宽。"); | ||
| 267 | +>>>>>>> upstream/master | ||
| 136 | } | 268 | } |
| 137 | 269 | ||
| 138 | private function stopPlayTest():void{ | 270 | private function stopPlayTest():void{ |
| @@ -144,7 +276,10 @@ package | @@ -144,7 +276,10 @@ package | ||
| 144 | var interval_ms:Number = evt.interval_ms; | 276 | var interval_ms:Number = evt.interval_ms; |
| 145 | 277 | ||
| 146 | connection.call("onSrsBandCheckStartingPublishBytes", null); | 278 | connection.call("onSrsBandCheckStartingPublishBytes", null); |
| 279 | +<<<<<<< HEAD | ||
| 147 | updateState("测试上行带宽(" + server_ip + ")"); | 280 | updateState("测试上行带宽(" + server_ip + ")"); |
| 281 | +======= | ||
| 282 | +>>>>>>> upstream/master | ||
| 148 | 283 | ||
| 149 | flash.utils.setTimeout(publisher, 0); | 284 | flash.utils.setTimeout(publisher, 0); |
| 150 | } | 285 | } |
| @@ -208,6 +343,7 @@ package | @@ -208,6 +343,7 @@ package | ||
| 208 | connection.call("finalClientPacket", null); | 343 | connection.call("finalClientPacket", null); |
| 209 | } | 344 | } |
| 210 | 345 | ||
| 346 | +<<<<<<< HEAD | ||
| 211 | public function onBWDone():void{ | 347 | public function onBWDone():void{ |
| 212 | // do nothing | 348 | // do nothing |
| 213 | } | 349 | } |
| @@ -215,13 +351,27 @@ package | @@ -215,13 +351,27 @@ package | ||
| 215 | // update progressBar's value | 351 | // update progressBar's value |
| 216 | private function updateProgess(value:Number, maxValue:Number):void{ | 352 | private function updateProgess(value:Number, maxValue:Number):void{ |
| 217 | flash.external.ExternalInterface.call(this.js_update_progress, value * 100 / maxValue + "%"); | 353 | flash.external.ExternalInterface.call(this.js_update_progress, value * 100 / maxValue + "%"); |
| 354 | +======= | ||
| 355 | + // update progressBar's value | ||
| 356 | + private function updateProgess(value:Number, maxValue:Number):void{ | ||
| 357 | + flash.external.ExternalInterface.call(this.js_update_progress, this.js_id, value * 100 / maxValue); | ||
| 358 | +>>>>>>> upstream/master | ||
| 218 | trace(value + "-" + maxValue + "-" + value * 100 / maxValue + "%"); | 359 | trace(value + "-" + maxValue + "-" + value * 100 / maxValue + "%"); |
| 219 | } | 360 | } |
| 220 | 361 | ||
| 221 | // update checking status | 362 | // update checking status |
| 222 | private function updateState(text:String):void{ | 363 | private function updateState(text:String):void{ |
| 364 | +<<<<<<< HEAD | ||
| 223 | flash.external.ExternalInterface.call(this.js_update_status, text); | 365 | flash.external.ExternalInterface.call(this.js_update_status, text); |
| 224 | trace(text); | 366 | trace(text); |
| 225 | } | 367 | } |
| 368 | +======= | ||
| 369 | + flash.external.ExternalInterface.call(this.js_update_status, this.js_id, text); | ||
| 370 | + trace(text); | ||
| 371 | + } | ||
| 372 | + | ||
| 373 | + public function onBWDone():void{ | ||
| 374 | + } | ||
| 375 | +>>>>>>> upstream/master | ||
| 226 | } | 376 | } |
| 227 | } | 377 | } |
| @@ -305,8 +305,8 @@ package | @@ -305,8 +305,8 @@ package | ||
| 305 | if (evt.info.data.hasOwnProperty("srs_server")) { | 305 | if (evt.info.data.hasOwnProperty("srs_server")) { |
| 306 | customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); | 306 | customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); |
| 307 | } | 307 | } |
| 308 | - if (evt.info.data.hasOwnProperty("srs_contributor")) { | ||
| 309 | - customItems.push(new ContextMenuItem("Contributor: " + evt.info.data.srs_contributor)); | 308 | + if (evt.info.data.hasOwnProperty("srs_primary_authors")) { |
| 309 | + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors)); | ||
| 310 | } | 310 | } |
| 311 | contextMenu.customItems = customItems; | 311 | contextMenu.customItems = customItems; |
| 312 | } | 312 | } |
| @@ -334,7 +334,7 @@ package | @@ -334,7 +334,7 @@ package | ||
| 334 | if (url.indexOf("http") == 0) { | 334 | if (url.indexOf("http") == 0) { |
| 335 | media_stream.play(url); | 335 | media_stream.play(url); |
| 336 | } else { | 336 | } else { |
| 337 | - var streamName:String = url.substr(url.lastIndexOf("/")); | 337 | + var streamName:String = url.substr(url.lastIndexOf("/") + 1); |
| 338 | media_stream.play(streamName); | 338 | media_stream.play(streamName); |
| 339 | } | 339 | } |
| 340 | 340 |
| @@ -192,8 +192,8 @@ package | @@ -192,8 +192,8 @@ package | ||
| 192 | if (evt.info.data.hasOwnProperty("srs_server")) { | 192 | if (evt.info.data.hasOwnProperty("srs_server")) { |
| 193 | customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); | 193 | customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); |
| 194 | } | 194 | } |
| 195 | - if (evt.info.data.hasOwnProperty("srs_contributor")) { | ||
| 196 | - customItems.push(new ContextMenuItem("Contributor: " + evt.info.data.srs_contributor)); | 195 | + if (evt.info.data.hasOwnProperty("srs_primary_authors")) { |
| 196 | + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors)); | ||
| 197 | } | 197 | } |
| 198 | contextMenu.customItems = customItems; | 198 | contextMenu.customItems = customItems; |
| 199 | } | 199 | } |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -76,10 +76,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -76,10 +76,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 76 | #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT | 76 | #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT |
| 77 | #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" | 77 | #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" |
| 78 | #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" | 78 | #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" |
| 79 | -#define RTMP_SIG_SRS_EMAIL "winterserver@126.com" | 79 | +#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" |
| 80 | #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" | 80 | #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" |
| 81 | -#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013 winlin" | ||
| 82 | -#define RTMP_SIG_SRS_CONTRIBUTOR "winlin,wenjiegit" | 81 | +#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin" |
| 82 | +#define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjiegit" | ||
| 83 | 83 | ||
| 84 | // compare | 84 | // compare |
| 85 | #define srs_min(a, b) (((a) < (b))? (a) : (b)) | 85 | #define srs_min(a, b) (((a) < (b))? (a) : (b)) |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 wenjiegit | 4 | +Copyright (c) 2013-2014 wenjiegit |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 wenjiegit | 4 | +Copyright (c) 2013-2014 wenjiegit |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -42,11 +42,6 @@ using namespace std; | @@ -42,11 +42,6 @@ using namespace std; | ||
| 42 | #include <srs_core_http.hpp> | 42 | #include <srs_core_http.hpp> |
| 43 | #include <srs_core_bandwidth.hpp> | 43 | #include <srs_core_bandwidth.hpp> |
| 44 | 44 | ||
| 45 | -#define SRS_PULSE_TIMEOUT_MS 100 | ||
| 46 | -#define SRS_SEND_TIMEOUT_US 5000000L | ||
| 47 | -#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US | ||
| 48 | -#define SRS_STREAM_BUSY_SLEEP_MS 2000 | ||
| 49 | - | ||
| 50 | SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) | 45 | SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) |
| 51 | : SrsConnection(srs_server, client_stfd) | 46 | : SrsConnection(srs_server, client_stfd) |
| 52 | { | 47 | { |
| @@ -198,7 +193,7 @@ int SrsClient::service_cycle() | @@ -198,7 +193,7 @@ int SrsClient::service_cycle() | ||
| 198 | srs_warn("stream %s is already publishing. ret=%d", | 193 | srs_warn("stream %s is already publishing. ret=%d", |
| 199 | req->get_stream_url().c_str(), ret); | 194 | req->get_stream_url().c_str(), ret); |
| 200 | // to delay request | 195 | // to delay request |
| 201 | - st_usleep(SRS_STREAM_BUSY_SLEEP_MS * 1000); | 196 | + st_usleep(SRS_STREAM_BUSY_SLEEP_US); |
| 202 | return ret; | 197 | return ret; |
| 203 | } | 198 | } |
| 204 | 199 | ||
| @@ -324,12 +319,12 @@ int SrsClient::playing(SrsSource* source) | @@ -324,12 +319,12 @@ int SrsClient::playing(SrsSource* source) | ||
| 324 | SrsAutoFree(SrsConsumer, consumer, false); | 319 | SrsAutoFree(SrsConsumer, consumer, false); |
| 325 | srs_verbose("consumer created success."); | 320 | srs_verbose("consumer created success."); |
| 326 | 321 | ||
| 327 | - rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000); | 322 | + rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_US); |
| 328 | 323 | ||
| 329 | SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER); | 324 | SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER); |
| 330 | 325 | ||
| 331 | while (true) { | 326 | while (true) { |
| 332 | - pithy_print.elapse(SRS_PULSE_TIMEOUT_MS); | 327 | + pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000); |
| 333 | 328 | ||
| 334 | // switch to other st-threads. | 329 | // switch to other st-threads. |
| 335 | st_usleep(0); | 330 | st_usleep(0); |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -735,9 +735,9 @@ int SrsConfig::parse_argv(int& i, char** argv) | @@ -735,9 +735,9 @@ int SrsConfig::parse_argv(int& i, char** argv) | ||
| 735 | 735 | ||
| 736 | void SrsConfig::print_help(char** argv) | 736 | void SrsConfig::print_help(char** argv) |
| 737 | { | 737 | { |
| 738 | - printf(RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION | ||
| 739 | - " Copyright (c) 2013 winlin\n" | ||
| 740 | - "Contributors: "RTMP_SIG_SRS_CONTRIBUTOR"\n" | 738 | + printf( |
| 739 | + RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION" "RTMP_SIG_SRS_COPYRIGHT"\n" | ||
| 740 | + "Primary Authors: "RTMP_SIG_SRS_PRIMARY_AUTHROS"\n" | ||
| 741 | "Build: "SRS_BUILD_DATE" Configuration: "SRS_CONFIGURE"\n" | 741 | "Build: "SRS_BUILD_DATE" Configuration: "SRS_CONFIGURE"\n" |
| 742 | "Usage: %s [-h?vV] [-c <filename>]\n" | 742 | "Usage: %s [-h?vV] [-c <filename>]\n" |
| 743 | "\n" | 743 | "\n" |
| @@ -1664,4 +1664,3 @@ bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b) | @@ -1664,4 +1664,3 @@ bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b) | ||
| 1664 | 1664 | ||
| 1665 | return true; | 1665 | return true; |
| 1666 | } | 1666 | } |
| 1667 | - |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -57,7 +57,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -57,7 +57,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 57 | // the interval in seconds for bandwidth check | 57 | // the interval in seconds for bandwidth check |
| 58 | #define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000 | 58 | #define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000 |
| 59 | 59 | ||
| 60 | -#define SRS_CONF_DEFAULT_CHUNK_SIZE 4096 | 60 | +// the default chunk size for system. |
| 61 | +#define SRS_CONF_DEFAULT_CHUNK_SIZE 60000 | ||
| 61 | 62 | ||
| 62 | #define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300 | 63 | #define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300 |
| 63 | #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100 | 64 | #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100 |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -37,11 +37,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -37,11 +37,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 37 | #include <srs_core_config.hpp> | 37 | #include <srs_core_config.hpp> |
| 38 | #include <srs_core_rtmp.hpp> | 38 | #include <srs_core_rtmp.hpp> |
| 39 | #include <srs_core_pithy_print.hpp> | 39 | #include <srs_core_pithy_print.hpp> |
| 40 | +#include <srs_core_protocol.hpp> | ||
| 40 | 41 | ||
| 41 | #ifdef SRS_FFMPEG | 42 | #ifdef SRS_FFMPEG |
| 42 | 43 | ||
| 43 | -#define SRS_ENCODER_SLEEP_MS 2000 | ||
| 44 | - | ||
| 45 | #define SRS_ENCODER_COPY "copy" | 44 | #define SRS_ENCODER_COPY "copy" |
| 46 | #define SRS_ENCODER_VCODEC "libx264" | 45 | #define SRS_ENCODER_VCODEC "libx264" |
| 47 | #define SRS_ENCODER_ACODEC "libaacplus" | 46 | #define SRS_ENCODER_ACODEC "libaacplus" |
| @@ -483,7 +482,7 @@ void SrsFFMPEG::stop() | @@ -483,7 +482,7 @@ void SrsFFMPEG::stop() | ||
| 483 | 482 | ||
| 484 | SrsEncoder::SrsEncoder() | 483 | SrsEncoder::SrsEncoder() |
| 485 | { | 484 | { |
| 486 | - pthread = new SrsThread(this, SRS_ENCODER_SLEEP_MS); | 485 | + pthread = new SrsThread(this, SRS_ENCODER_SLEEP_US); |
| 487 | pithy_print = new SrsPithyPrint(SRS_STAGE_ENCODER); | 486 | pithy_print = new SrsPithyPrint(SRS_STAGE_ENCODER); |
| 488 | } | 487 | } |
| 489 | 488 | ||
| @@ -549,7 +548,7 @@ int SrsEncoder::cycle() | @@ -549,7 +548,7 @@ int SrsEncoder::cycle() | ||
| 549 | 548 | ||
| 550 | // pithy print | 549 | // pithy print |
| 551 | encoder(); | 550 | encoder(); |
| 552 | - pithy_print->elapse(SRS_ENCODER_SLEEP_MS); | 551 | + pithy_print->elapse(SRS_ENCODER_SLEEP_US / 1000); |
| 553 | 552 | ||
| 554 | return ret; | 553 | return ret; |
| 555 | } | 554 | } |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -38,11 +38,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -38,11 +38,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 38 | #include <srs_core_source.hpp> | 38 | #include <srs_core_source.hpp> |
| 39 | #include <srs_core_autofree.hpp> | 39 | #include <srs_core_autofree.hpp> |
| 40 | 40 | ||
| 41 | -#define SRS_PULSE_TIMEOUT_MS 100 | ||
| 42 | -#define SRS_FORWARDER_SLEEP_MS 2000 | ||
| 43 | -#define SRS_SEND_TIMEOUT_US 3000000L | ||
| 44 | -#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US | ||
| 45 | - | ||
| 46 | SrsForwarder::SrsForwarder(SrsSource* _source) | 41 | SrsForwarder::SrsForwarder(SrsSource* _source) |
| 47 | { | 42 | { |
| 48 | source = _source; | 43 | source = _source; |
| @@ -51,7 +46,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source) | @@ -51,7 +46,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source) | ||
| 51 | stfd = NULL; | 46 | stfd = NULL; |
| 52 | stream_id = 0; | 47 | stream_id = 0; |
| 53 | 48 | ||
| 54 | - pthread = new SrsThread(this, SRS_FORWARDER_SLEEP_MS); | 49 | + pthread = new SrsThread(this, SRS_FORWARDER_SLEEP_US); |
| 55 | queue = new SrsMessageQueue(); | 50 | queue = new SrsMessageQueue(); |
| 56 | jitter = new SrsRtmpJitter(); | 51 | jitter = new SrsRtmpJitter(); |
| 57 | } | 52 | } |
| @@ -286,11 +281,11 @@ int SrsForwarder::forward() | @@ -286,11 +281,11 @@ int SrsForwarder::forward() | ||
| 286 | { | 281 | { |
| 287 | int ret = ERROR_SUCCESS; | 282 | int ret = ERROR_SUCCESS; |
| 288 | 283 | ||
| 289 | - client->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000); | 284 | + client->set_recv_timeout(SRS_PULSE_TIMEOUT_US); |
| 290 | 285 | ||
| 291 | SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER); | 286 | SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER); |
| 292 | 287 | ||
| 293 | - while (true) { | 288 | + while (pthread->can_loop()) { |
| 294 | // switch to other st-threads. | 289 | // switch to other st-threads. |
| 295 | st_usleep(0); | 290 | st_usleep(0); |
| 296 | 291 | ||
| @@ -322,7 +317,7 @@ int SrsForwarder::forward() | @@ -322,7 +317,7 @@ int SrsForwarder::forward() | ||
| 322 | SrsAutoFree(SrsSharedPtrMessage*, msgs, true); | 317 | SrsAutoFree(SrsSharedPtrMessage*, msgs, true); |
| 323 | 318 | ||
| 324 | // pithy print | 319 | // pithy print |
| 325 | - pithy_print.elapse(SRS_PULSE_TIMEOUT_MS); | 320 | + pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000); |
| 326 | if (pithy_print.can_print()) { | 321 | if (pithy_print.can_print()) { |
| 327 | srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", | 322 | srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", |
| 328 | pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps()); | 323 | pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps()); |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -36,6 +36,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -36,6 +36,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 36 | #include <srs_core_log.hpp> | 36 | #include <srs_core_log.hpp> |
| 37 | #include <srs_core_error.hpp> | 37 | #include <srs_core_error.hpp> |
| 38 | 38 | ||
| 39 | +// the following is the timeout for rtmp protocol, | ||
| 40 | +// to avoid death connection. | ||
| 41 | + | ||
| 42 | +// when got a messae header, there must be some data, | ||
| 43 | +// increase recv timeout to got an entire message. | ||
| 44 | +#define SRS_MIN_RECV_TIMEOUT_US 60*1000*1000L | ||
| 45 | + | ||
| 46 | +// the timeout to wait for client control message, | ||
| 47 | +// if timeout, we generally ignore and send the data to client, | ||
| 48 | +// generally, it's the pulse time for data seding. | ||
| 49 | +#define SRS_PULSE_TIMEOUT_US 200*1000L | ||
| 50 | + | ||
| 51 | +// the timeout to wait client data, | ||
| 52 | +// if timeout, close the connection. | ||
| 53 | +#define SRS_SEND_TIMEOUT_US 30*1000*1000L | ||
| 54 | + | ||
| 55 | +// the timeout to send data to client, | ||
| 56 | +// if timeout, close the connection. | ||
| 57 | +#define SRS_RECV_TIMEOUT_US 30*1000*1000L | ||
| 58 | + | ||
| 59 | +// when stream is busy, for example, streaming is already | ||
| 60 | +// publishing, when a new client to request to publish, | ||
| 61 | +// sleep a while and close the connection. | ||
| 62 | +#define SRS_STREAM_BUSY_SLEEP_US 3*1000*1000L | ||
| 63 | + | ||
| 64 | +// when error, forwarder sleep for a while and retry. | ||
| 65 | +#define SRS_FORWARDER_SLEEP_US 3*1000*1000L | ||
| 66 | + | ||
| 67 | +// when error, encoder sleep for a while and retry. | ||
| 68 | +#define SRS_ENCODER_SLEEP_US 3*1000*1000L | ||
| 69 | + | ||
| 39 | class SrsSocket; | 70 | class SrsSocket; |
| 40 | class SrsBuffer; | 71 | class SrsBuffer; |
| 41 | class SrsPacket; | 72 | class SrsPacket; |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -391,12 +391,44 @@ int SrsRtmpClient::play(string stream, int stream_id) | @@ -391,12 +391,44 @@ int SrsRtmpClient::play(string stream, int stream_id) | ||
| 391 | } | 391 | } |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | + // SetChunkSize | ||
| 395 | + if (true) { | ||
| 396 | + SrsCommonMessage* msg = new SrsCommonMessage(); | ||
| 397 | + SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket(); | ||
| 398 | + | ||
| 399 | + pkt->chunk_size = SRS_CONF_DEFAULT_CHUNK_SIZE; | ||
| 400 | + msg->set_packet(pkt, 0); | ||
| 401 | + | ||
| 402 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 403 | + srs_error("send set chunk size failed. " | ||
| 404 | + "stream=%s, chunk_size=%d, ret=%d", | ||
| 405 | + stream.c_str(), SRS_CONF_DEFAULT_CHUNK_SIZE, ret); | ||
| 406 | + return ret; | ||
| 407 | + } | ||
| 408 | + } | ||
| 409 | + | ||
| 394 | return ret; | 410 | return ret; |
| 395 | } | 411 | } |
| 396 | 412 | ||
| 397 | int SrsRtmpClient::publish(string stream, int stream_id) | 413 | int SrsRtmpClient::publish(string stream, int stream_id) |
| 398 | { | 414 | { |
| 399 | int ret = ERROR_SUCCESS; | 415 | int ret = ERROR_SUCCESS; |
| 416 | + | ||
| 417 | + // SetChunkSize | ||
| 418 | + if (true) { | ||
| 419 | + SrsCommonMessage* msg = new SrsCommonMessage(); | ||
| 420 | + SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket(); | ||
| 421 | + | ||
| 422 | + pkt->chunk_size = SRS_CONF_DEFAULT_CHUNK_SIZE; | ||
| 423 | + msg->set_packet(pkt, 0); | ||
| 424 | + | ||
| 425 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 426 | + srs_error("send set chunk size failed. " | ||
| 427 | + "stream=%s, chunk_size=%d, ret=%d", | ||
| 428 | + stream.c_str(), SRS_CONF_DEFAULT_CHUNK_SIZE, ret); | ||
| 429 | + return ret; | ||
| 430 | + } | ||
| 431 | + } | ||
| 400 | 432 | ||
| 401 | // publish(stream) | 433 | // publish(stream) |
| 402 | if (true) { | 434 | if (true) { |
| @@ -617,7 +649,7 @@ int SrsRtmp::response_connect_app(SrsRequest *req, const char* server_ip) | @@ -617,7 +649,7 @@ int SrsRtmp::response_connect_app(SrsRequest *req, const char* server_ip) | ||
| 617 | data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB)); | 649 | data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB)); |
| 618 | data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL)); | 650 | data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL)); |
| 619 | data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT)); | 651 | data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT)); |
| 620 | - data->set("srs_contributor", new SrsAmf0String(RTMP_SIG_SRS_CONTRIBUTOR)); | 652 | + data->set("srs_primary_authors", new SrsAmf0String(RTMP_SIG_SRS_PRIMARY_AUTHROS)); |
| 621 | 653 | ||
| 622 | if (server_ip) { | 654 | if (server_ip) { |
| 623 | data->set("srs_server_ip", new SrsAmf0String(server_ip)); | 655 | data->set("srs_server_ip", new SrsAmf0String(server_ip)); |
| @@ -1194,4 +1226,3 @@ int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& | @@ -1194,4 +1226,3 @@ int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& | ||
| 1194 | 1226 | ||
| 1195 | return ret; | 1227 | return ret; |
| 1196 | } | 1228 | } |
| 1197 | - |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -110,7 +110,7 @@ enum SrsClientType | @@ -110,7 +110,7 @@ enum SrsClientType | ||
| 110 | */ | 110 | */ |
| 111 | class SrsRtmpClient | 111 | class SrsRtmpClient |
| 112 | { | 112 | { |
| 113 | -private: | 113 | +protected: |
| 114 | SrsProtocol* protocol; | 114 | SrsProtocol* protocol; |
| 115 | st_netfd_t stfd; | 115 | st_netfd_t stfd; |
| 116 | public: | 116 | public: |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 35 | #include <srs_core_client.hpp> | 35 | #include <srs_core_client.hpp> |
| 36 | #include <srs_core_config.hpp> | 36 | #include <srs_core_config.hpp> |
| 37 | 37 | ||
| 38 | -#define SERVER_LISTEN_BACKLOG 10 | 38 | +#define SERVER_LISTEN_BACKLOG 512 |
| 39 | #define SRS_TIME_RESOLUTION_MS 500 | 39 | #define SRS_TIME_RESOLUTION_MS 500 |
| 40 | 40 | ||
| 41 | SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type) | 41 | SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type) |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -642,7 +642,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata | @@ -642,7 +642,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata | ||
| 642 | metadata->metadata->set("server", new SrsAmf0String( | 642 | metadata->metadata->set("server", new SrsAmf0String( |
| 643 | RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")")); | 643 | RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")")); |
| 644 | metadata->metadata->set("contributor", | 644 | metadata->metadata->set("contributor", |
| 645 | - new SrsAmf0String(RTMP_SIG_SRS_CONTRIBUTOR)); | 645 | + new SrsAmf0String(RTMP_SIG_SRS_PRIMARY_AUTHROS)); |
| 646 | 646 | ||
| 647 | SrsAmf0Any* prop = NULL; | 647 | SrsAmf0Any* prop = NULL; |
| 648 | if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) { | 648 | if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) { |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -54,10 +54,10 @@ void ISrsThreadHandler::on_leave_loop() | @@ -54,10 +54,10 @@ void ISrsThreadHandler::on_leave_loop() | ||
| 54 | { | 54 | { |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | -SrsThread::SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_ms) | 57 | +SrsThread::SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_us) |
| 58 | { | 58 | { |
| 59 | handler = thread_handler; | 59 | handler = thread_handler; |
| 60 | - cycle_interval_milliseconds = interval_ms; | 60 | + cycle_interval_us = interval_us; |
| 61 | 61 | ||
| 62 | tid = NULL; | 62 | tid = NULL; |
| 63 | loop = false; | 63 | loop = false; |
| @@ -102,6 +102,11 @@ void SrsThread::stop() | @@ -102,6 +102,11 @@ void SrsThread::stop() | ||
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | +bool SrsThread::can_loop() | ||
| 106 | +{ | ||
| 107 | + return loop; | ||
| 108 | +} | ||
| 109 | + | ||
| 105 | void SrsThread::thread_cycle() | 110 | void SrsThread::thread_cycle() |
| 106 | { | 111 | { |
| 107 | int ret = ERROR_SUCCESS; | 112 | int ret = ERROR_SUCCESS; |
| @@ -138,7 +143,7 @@ failed: | @@ -138,7 +143,7 @@ failed: | ||
| 138 | break; | 143 | break; |
| 139 | } | 144 | } |
| 140 | 145 | ||
| 141 | - st_usleep(cycle_interval_milliseconds * 1000); | 146 | + st_usleep(cycle_interval_us); |
| 142 | } | 147 | } |
| 143 | 148 | ||
| 144 | handler->on_leave_loop(); | 149 | handler->on_leave_loop(); |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| @@ -43,6 +43,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -43,6 +43,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 43 | * when stop, the thread will interrupt the st_thread, | 43 | * when stop, the thread will interrupt the st_thread, |
| 44 | * which will cause the socket to return error and | 44 | * which will cause the socket to return error and |
| 45 | * terminate the cycle thread. | 45 | * terminate the cycle thread. |
| 46 | +* | ||
| 47 | +* when thread interrupt, the socket maybe not got EINT, | ||
| 48 | +* espectially on st_usleep(), so the cycle must check the loop, | ||
| 49 | +* when handler->cycle() has loop itself, for example: | ||
| 50 | +* handler->cycle() is: | ||
| 51 | +* while (true): | ||
| 52 | +* st_usleep(0); | ||
| 53 | +* if (read_from_socket(skt) < 0) break; | ||
| 54 | +* if thread stop when read_from_socket, it's ok, the loop will break, | ||
| 55 | +* but when thread stop interrupt the s_usleep(0), then the loop is | ||
| 56 | +* death loop. | ||
| 57 | +* in a word, the handler->cycle() must: | ||
| 58 | +* handler->cycle() is: | ||
| 59 | +* while (pthread->can_loop()): | ||
| 60 | +* st_usleep(0); | ||
| 61 | +* if (read_from_socket(skt) < 0) break; | ||
| 62 | +* check the loop, then it works. | ||
| 46 | */ | 63 | */ |
| 47 | class ISrsThreadHandler | 64 | class ISrsThreadHandler |
| 48 | { | 65 | { |
| @@ -68,14 +85,14 @@ private: | @@ -68,14 +85,14 @@ private: | ||
| 68 | bool loop; | 85 | bool loop; |
| 69 | private: | 86 | private: |
| 70 | ISrsThreadHandler* handler; | 87 | ISrsThreadHandler* handler; |
| 71 | - int64_t cycle_interval_milliseconds; | 88 | + int64_t cycle_interval_us; |
| 72 | public: | 89 | public: |
| 73 | /** | 90 | /** |
| 74 | * initialize the thread. | 91 | * initialize the thread. |
| 75 | * @param thread_handler, the cycle handler for the thread. | 92 | * @param thread_handler, the cycle handler for the thread. |
| 76 | - * @param interval_ms, the sleep interval when cycle finished. | 93 | + * @param interval_us, the sleep interval when cycle finished. |
| 77 | */ | 94 | */ |
| 78 | - SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_ms); | 95 | + SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_us); |
| 79 | virtual ~SrsThread(); | 96 | virtual ~SrsThread(); |
| 80 | public: | 97 | public: |
| 81 | /** | 98 | /** |
| @@ -90,6 +107,12 @@ public: | @@ -90,6 +107,12 @@ public: | ||
| 90 | * @remark user can stop multiple times, ignore if already stopped. | 107 | * @remark user can stop multiple times, ignore if already stopped. |
| 91 | */ | 108 | */ |
| 92 | virtual void stop(); | 109 | virtual void stop(); |
| 110 | + /** | ||
| 111 | + * whether the thread should loop, | ||
| 112 | + * used for handler->cycle() which has a loop method, | ||
| 113 | + * to check this method, break if false. | ||
| 114 | + */ | ||
| 115 | + virtual bool can_loop(); | ||
| 93 | private: | 116 | private: |
| 94 | virtual void thread_cycle(); | 117 | virtual void thread_cycle(); |
| 95 | static void* thread_fun(void* arg); | 118 | static void* thread_fun(void* arg); |
| 1 | -/* | ||
| 2 | -The MIT License (MIT) | ||
| 3 | - | ||
| 4 | -Copyright (c) 2013 wenjiegit | ||
| 5 | - | ||
| 6 | -Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | -this software and associated documentation files (the "Software"), to deal in | ||
| 8 | -the Software without restriction, including without limitation the rights to | ||
| 9 | -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | -the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | -subject to the following conditions: | ||
| 12 | - | ||
| 13 | -The above copyright notice and this permission notice shall be included in all | ||
| 14 | -copies or substantial portions of the Software. | ||
| 15 | - | ||
| 16 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | -*/ | ||
| 23 | - | ||
| 24 | -#include <sys/socket.h> | ||
| 25 | -#include <netinet/in.h> | ||
| 26 | -#include <arpa/inet.h> | ||
| 27 | -#include <sstream> | ||
| 28 | -#include <getopt.h> | ||
| 29 | -#include <stdlib.h> | ||
| 30 | - | ||
| 31 | -#include <srs_core_rtmp.hpp> | ||
| 32 | -#include <srs_core_protocol.hpp> | ||
| 33 | -#include <srs_core_error.hpp> | ||
| 34 | -#include <srs_core_amf0.hpp> | ||
| 35 | -#include <srs_core_autofree.hpp> | ||
| 36 | -#include <srs_core_stream.hpp> | ||
| 37 | - | ||
| 38 | -#include <st.h> | ||
| 39 | - | ||
| 40 | -// server play control | ||
| 41 | -#define SRS_BW_CHECK_START_PLAY "onSrsBandCheckStartPlayBytes" | ||
| 42 | -#define SRS_BW_CHECK_STARTING_PLAY "onSrsBandCheckStartingPlayBytes" | ||
| 43 | -#define SRS_BW_CHECK_STOP_PLAY "onSrsBandCheckStopPlayBytes" | ||
| 44 | -#define SRS_BW_CHECK_STOPPED_PLAY "onSrsBandCheckStoppedPlayBytes" | ||
| 45 | - | ||
| 46 | -// server publish control | ||
| 47 | -#define SRS_BW_CHECK_START_PUBLISH "onSrsBandCheckStartPublishBytes" | ||
| 48 | -#define SRS_BW_CHECK_STARTING_PUBLISH "onSrsBandCheckStartingPublishBytes" | ||
| 49 | -#define SRS_BW_CHECK_STOP_PUBLISH "onSrsBandCheckStopPublishBytes" | ||
| 50 | -#define SRS_BW_CHECK_STOPPED_PUBLISH "onSrsBandCheckStoppedPublishBytes" | ||
| 51 | - | ||
| 52 | -// EOF control. | ||
| 53 | -#define SRS_BW_CHECK_FINISHED "onSrsBandCheckFinished" | ||
| 54 | -#define SRS_BW_CHECK_FLASH_FINAL "finalClientPacket" | ||
| 55 | - | ||
| 56 | -// client only | ||
| 57 | -#define SRS_BW_CHECK_PLAYING "onSrsBandCheckPlaying" | ||
| 58 | -#define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing" | ||
| 59 | - | ||
| 60 | -/** | ||
| 61 | -* @brief class of Linux version band check client | ||
| 62 | -* check play and publish speed. | ||
| 63 | -*/ | ||
| 64 | -class SrsBandCheckClient : public SrsRtmpClient | ||
| 65 | -{ | ||
| 66 | -public: | ||
| 67 | - SrsBandCheckClient(st_netfd_t _stfd); | ||
| 68 | - ~SrsBandCheckClient(); | ||
| 69 | - | ||
| 70 | -public: | ||
| 71 | - /** | ||
| 72 | - * @brief test play | ||
| 73 | - * | ||
| 74 | - */ | ||
| 75 | - int check_play(); | ||
| 76 | - /** | ||
| 77 | - * @brief test publish | ||
| 78 | - * | ||
| 79 | - */ | ||
| 80 | - int check_publish(); | ||
| 81 | - | ||
| 82 | -private: | ||
| 83 | - /** | ||
| 84 | - * @brief just return success. | ||
| 85 | - */ | ||
| 86 | - int create_stream(int& stream_id); | ||
| 87 | - /** | ||
| 88 | - * @brief just return success. | ||
| 89 | - */ | ||
| 90 | - int play(std::string stream, int stream_id); | ||
| 91 | - /** | ||
| 92 | - * @brief just return success. | ||
| 93 | - */ | ||
| 94 | - int publish(std::string stream, int stream_id); | ||
| 95 | - | ||
| 96 | -private: | ||
| 97 | - int expect_start_play(); | ||
| 98 | - int send_starting_play(); | ||
| 99 | - int expect_stop_play(); | ||
| 100 | - int send_stopped_play(); | ||
| 101 | - int expect_start_pub(); | ||
| 102 | - int send_starting_pub(); | ||
| 103 | - int send_pub_data(); | ||
| 104 | - int expect_stop_pub(); | ||
| 105 | - /** | ||
| 106 | - * @brief expect result. | ||
| 107 | - * because the core module has no method to decode this packet | ||
| 108 | - * so we must get the internal data and decode it here. | ||
| 109 | - */ | ||
| 110 | - int expect_finished(); | ||
| 111 | - int send_stopped_pub(); | ||
| 112 | - /** | ||
| 113 | - * @brief notify server the check procedure is over. | ||
| 114 | - */ | ||
| 115 | - int send_final(); | ||
| 116 | -}; | ||
| 117 | - | ||
| 118 | -/** | ||
| 119 | -* @brief class of band check | ||
| 120 | -* used to check band width with a client @param bandCheck_Client | ||
| 121 | -*/ | ||
| 122 | -class SrsBandCheck | ||
| 123 | -{ | ||
| 124 | -public: | ||
| 125 | - SrsBandCheck(); | ||
| 126 | - ~SrsBandCheck(); | ||
| 127 | - | ||
| 128 | -public: | ||
| 129 | - /** | ||
| 130 | - * @brief band check method | ||
| 131 | - * | ||
| 132 | - * connect to server------>rtmp handshake------>rtmp connect------>play------>publish | ||
| 133 | - * @retval ERROR_SUCCESS when success. | ||
| 134 | - */ | ||
| 135 | - int check(const std::string& app, const std::string& tcUrl); | ||
| 136 | - | ||
| 137 | - /** | ||
| 138 | - * @brief set the address and port of test server | ||
| 139 | - * | ||
| 140 | - * @param server server address, domain or ip | ||
| 141 | - * @param server listened port ,default is 1935 | ||
| 142 | - */ | ||
| 143 | - void set_server(const std::string& server, int port = 1935); | ||
| 144 | - | ||
| 145 | -private: | ||
| 146 | - int connect_server(); | ||
| 147 | - | ||
| 148 | -private: | ||
| 149 | - SrsBandCheckClient* bandCheck_Client; | ||
| 150 | - std::string server_address; | ||
| 151 | - int server_port; | ||
| 152 | -}; | ||
| 153 | - | ||
| 154 | -/** | ||
| 155 | -* @brief init st lib | ||
| 156 | -*/ | ||
| 157 | -static int init_st(); | ||
| 158 | -static void print_help(); | ||
| 159 | -static void print_version(); | ||
| 160 | - | ||
| 161 | -/** | ||
| 162 | -* @brief get user option | ||
| 163 | -* @internal ip Mandatory arguments | ||
| 164 | -* @internal key Mandatory arguments | ||
| 165 | -* @internal port default 1935 | ||
| 166 | -* @internal vhost default bandcheck.srs.com | ||
| 167 | -*/ | ||
| 168 | -static int get_opt(int argc ,char* argv[]); | ||
| 169 | - | ||
| 170 | -/** | ||
| 171 | -* global var. | ||
| 172 | -*/ | ||
| 173 | -static struct option long_options[] = | ||
| 174 | -{ | ||
| 175 | - {"ip", required_argument, 0, 'i'}, | ||
| 176 | - {"port", optional_argument, 0, 'p'}, | ||
| 177 | - {"key", required_argument, 0, 'k'}, | ||
| 178 | - {"vhost", optional_argument, 0, 'v'}, | ||
| 179 | - {"help", no_argument, 0, 'h'}, | ||
| 180 | - {"version", no_argument, 0, 'V'}, | ||
| 181 | -}; | ||
| 182 | - | ||
| 183 | -static const char* short_options = "i:p::k:v::hV"; | ||
| 184 | - | ||
| 185 | -static std::string g_ip; | ||
| 186 | -static int g_port = 1935; | ||
| 187 | -static std::string g_key; | ||
| 188 | -static std::string g_vhost = "bandcheck.srs.com"; | ||
| 189 | - | ||
| 190 | -#define BUILD_VERSION "srs band check 0.1" | ||
| 191 | - | ||
| 192 | -int main(int argc ,char* argv[]) | ||
| 193 | -{ | ||
| 194 | - int ret = ERROR_SUCCESS; | ||
| 195 | - | ||
| 196 | - if ((ret = get_opt(argc, argv)) != ERROR_SUCCESS) { | ||
| 197 | - return -1; | ||
| 198 | - } | ||
| 199 | - | ||
| 200 | - // check param | ||
| 201 | - if (g_ip.empty()) { | ||
| 202 | - printf("ip address should not be empty."); | ||
| 203 | - return -1; | ||
| 204 | - } | ||
| 205 | - | ||
| 206 | - if (g_key.empty()) { | ||
| 207 | - printf("test key should not be empty."); | ||
| 208 | - return -1; | ||
| 209 | - } | ||
| 210 | - | ||
| 211 | - if ((ret = init_st()) != ERROR_SUCCESS) { | ||
| 212 | - srs_error("band check init failed. ret=%d", ret); | ||
| 213 | - return ret; | ||
| 214 | - } | ||
| 215 | - | ||
| 216 | - std::string app = "app?key=" + g_key + "&vhost=" + g_vhost; | ||
| 217 | - | ||
| 218 | - char tcUrl_buffer[1024] = {0}; | ||
| 219 | - sprintf(tcUrl_buffer, "rtmp://%s:%d/%s", g_ip.c_str(), g_port, app.c_str()); | ||
| 220 | - std::string tcUrl = tcUrl_buffer; | ||
| 221 | - | ||
| 222 | - SrsBandCheck band_check; | ||
| 223 | - band_check.set_server(g_ip, g_port); | ||
| 224 | - if ((ret = band_check.check(app, tcUrl)) != ERROR_SUCCESS) { | ||
| 225 | - srs_error("band check failed. address=%s ret=%d", "xx.com", ret); | ||
| 226 | - return -1; | ||
| 227 | - } | ||
| 228 | - | ||
| 229 | - return 0; | ||
| 230 | -} | ||
| 231 | - | ||
| 232 | -SrsBandCheckClient::SrsBandCheckClient(st_netfd_t _stfd) | ||
| 233 | - : SrsRtmpClient(_stfd) | ||
| 234 | -{ | ||
| 235 | -} | ||
| 236 | - | ||
| 237 | -SrsBandCheckClient::~SrsBandCheckClient() | ||
| 238 | -{ | ||
| 239 | -} | ||
| 240 | - | ||
| 241 | -int SrsBandCheckClient::check_play() | ||
| 242 | -{ | ||
| 243 | - int ret = ERROR_SUCCESS; | ||
| 244 | - | ||
| 245 | - if ((ret = expect_start_play()) != ERROR_SUCCESS) { | ||
| 246 | - srs_error("expect_start_play failed. ret=%d", ret); | ||
| 247 | - return ret; | ||
| 248 | - } | ||
| 249 | - | ||
| 250 | - if ((ret = send_starting_play()) != ERROR_SUCCESS) { | ||
| 251 | - srs_error("send starting play failed. ret=%d", ret); | ||
| 252 | - return ret; | ||
| 253 | - } | ||
| 254 | - | ||
| 255 | - if ((ret = expect_stop_play()) != ERROR_SUCCESS) { | ||
| 256 | - srs_error("expect stop play failed. ret=%d", ret); | ||
| 257 | - return ret; | ||
| 258 | - } | ||
| 259 | - | ||
| 260 | - if ((ret = send_stopped_play()) != ERROR_SUCCESS) { | ||
| 261 | - srs_error("send stopped play failed. ret=%d", ret); | ||
| 262 | - return ret; | ||
| 263 | - } | ||
| 264 | - | ||
| 265 | - return ret; | ||
| 266 | -} | ||
| 267 | - | ||
| 268 | -int SrsBandCheckClient::check_publish() | ||
| 269 | -{ | ||
| 270 | - int ret = ERROR_SUCCESS; | ||
| 271 | - | ||
| 272 | - if ((ret = expect_start_pub()) != ERROR_SUCCESS) { | ||
| 273 | - srs_error("expect start pub failed. ret=%d", ret); | ||
| 274 | - return ret; | ||
| 275 | - } | ||
| 276 | - | ||
| 277 | - if ((ret = send_starting_pub())!= ERROR_SUCCESS) { | ||
| 278 | - srs_error("send starting pub failed. ret=%d", ret); | ||
| 279 | - return ret; | ||
| 280 | - } | ||
| 281 | - | ||
| 282 | - if ((ret = send_pub_data()) != ERROR_SUCCESS) { | ||
| 283 | - srs_error("publish data failed. ret=%d", ret); | ||
| 284 | - return ret; | ||
| 285 | - } | ||
| 286 | - | ||
| 287 | - if ((ret = send_stopped_pub()) != ERROR_SUCCESS) { | ||
| 288 | - srs_error("send stopped pub failed. ret=%d", ret); | ||
| 289 | - return ret; | ||
| 290 | - } | ||
| 291 | - | ||
| 292 | - if ((ret = expect_finished()) != ERROR_SUCCESS) { | ||
| 293 | - srs_error("expect finished msg failed. ret=%d", ret); | ||
| 294 | - return ret; | ||
| 295 | - } | ||
| 296 | - | ||
| 297 | - if ((ret = send_final()) != ERROR_SUCCESS) { | ||
| 298 | - srs_error("send final msg failed. ret=%d", ret); | ||
| 299 | - return ret; | ||
| 300 | - } | ||
| 301 | - | ||
| 302 | - return ret; | ||
| 303 | -} | ||
| 304 | - | ||
| 305 | -int SrsBandCheckClient::create_stream(int &stream_id) | ||
| 306 | -{ | ||
| 307 | - return ERROR_SUCCESS; | ||
| 308 | -} | ||
| 309 | - | ||
| 310 | -int SrsBandCheckClient::play(std::string stream, int stream_id) | ||
| 311 | -{ | ||
| 312 | - return ERROR_SUCCESS; | ||
| 313 | -} | ||
| 314 | - | ||
| 315 | -int SrsBandCheckClient::publish(std::string stream, int stream_id) | ||
| 316 | -{ | ||
| 317 | - return ERROR_SUCCESS; | ||
| 318 | -} | ||
| 319 | - | ||
| 320 | -int SrsBandCheckClient::expect_start_play() | ||
| 321 | -{ | ||
| 322 | - int ret = ERROR_SUCCESS; | ||
| 323 | - | ||
| 324 | - // expect connect _result | ||
| 325 | - SrsCommonMessage* msg = NULL; | ||
| 326 | - SrsBandwidthPacket* pkt = NULL; | ||
| 327 | - if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 328 | - srs_error("expect bandcheck start play message failed. ret=%d", ret); | ||
| 329 | - return ret; | ||
| 330 | - } | ||
| 331 | - SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 332 | - srs_info("get bandcheck start play message"); | ||
| 333 | - | ||
| 334 | - if (pkt->command_name != SRS_BW_CHECK_START_PLAY) { | ||
| 335 | - srs_error("pkt error. expect=%s, actual=%s", SRS_BW_CHECK_START_PLAY, pkt->command_name.c_str()); | ||
| 336 | - return -1; | ||
| 337 | - } | ||
| 338 | - | ||
| 339 | - return ret; | ||
| 340 | -} | ||
| 341 | - | ||
| 342 | -int SrsBandCheckClient::send_starting_play() | ||
| 343 | -{ | ||
| 344 | - int ret = ERROR_SUCCESS; | ||
| 345 | - | ||
| 346 | - SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 347 | - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 348 | - pkt->command_name = SRS_BW_CHECK_STARTING_PLAY; | ||
| 349 | - msg->set_packet(pkt, 0); | ||
| 350 | - | ||
| 351 | - if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 352 | - srs_error("send starting play msg failed. ret=%d", ret); | ||
| 353 | - return ret; | ||
| 354 | - } | ||
| 355 | - | ||
| 356 | - return ret; | ||
| 357 | -} | ||
| 358 | - | ||
| 359 | -int SrsBandCheckClient::expect_stop_play() | ||
| 360 | -{ | ||
| 361 | - int ret = ERROR_SUCCESS; | ||
| 362 | - | ||
| 363 | - while (true) { | ||
| 364 | - SrsCommonMessage* msg = NULL; | ||
| 365 | - SrsBandwidthPacket* pkt = NULL; | ||
| 366 | - if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 367 | - srs_error("expect stop play message failed. ret=%d", ret); | ||
| 368 | - return ret; | ||
| 369 | - } | ||
| 370 | - SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 371 | - srs_info("get bandcheck stop play message"); | ||
| 372 | - | ||
| 373 | - if (pkt->command_name == SRS_BW_CHECK_STOP_PLAY) { | ||
| 374 | - break; | ||
| 375 | - } | ||
| 376 | - } | ||
| 377 | - | ||
| 378 | - return ret; | ||
| 379 | -} | ||
| 380 | - | ||
| 381 | -int SrsBandCheckClient::send_stopped_play() | ||
| 382 | -{ | ||
| 383 | - int ret = ERROR_SUCCESS; | ||
| 384 | - | ||
| 385 | - SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 386 | - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 387 | - pkt->command_name = SRS_BW_CHECK_STOPPED_PLAY; | ||
| 388 | - msg->set_packet(pkt, 0); | ||
| 389 | - | ||
| 390 | - if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 391 | - srs_error("send stopped play msg failed. ret=%d", ret); | ||
| 392 | - return ret; | ||
| 393 | - } | ||
| 394 | - | ||
| 395 | - return ret; | ||
| 396 | -} | ||
| 397 | - | ||
| 398 | -int SrsBandCheckClient::expect_start_pub() | ||
| 399 | -{ | ||
| 400 | - int ret = ERROR_SUCCESS; | ||
| 401 | - | ||
| 402 | - while (true) { | ||
| 403 | - SrsCommonMessage* msg = NULL; | ||
| 404 | - SrsBandwidthPacket* pkt = NULL; | ||
| 405 | - if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 406 | - srs_error("expect start pub message failed. ret=%d", ret); | ||
| 407 | - return ret; | ||
| 408 | - } | ||
| 409 | - SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 410 | - srs_info("get bandcheck start pub message"); | ||
| 411 | - | ||
| 412 | - if (pkt->command_name == SRS_BW_CHECK_START_PUBLISH) { | ||
| 413 | - break; | ||
| 414 | - } | ||
| 415 | - } | ||
| 416 | - | ||
| 417 | - return ret; | ||
| 418 | -} | ||
| 419 | - | ||
| 420 | -int SrsBandCheckClient::send_starting_pub() | ||
| 421 | -{ | ||
| 422 | - int ret = ERROR_SUCCESS; | ||
| 423 | - | ||
| 424 | - SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 425 | - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 426 | - pkt->command_name = SRS_BW_CHECK_STARTING_PUBLISH; | ||
| 427 | - msg->set_packet(pkt, 0); | ||
| 428 | - | ||
| 429 | - if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 430 | - srs_error("send starting play msg failed. ret=%d", ret); | ||
| 431 | - return ret; | ||
| 432 | - } | ||
| 433 | - srs_info("send starting play msg success."); | ||
| 434 | - | ||
| 435 | - return ret; | ||
| 436 | -} | ||
| 437 | - | ||
| 438 | -int SrsBandCheckClient::send_pub_data() | ||
| 439 | -{ | ||
| 440 | - int ret = ERROR_SUCCESS; | ||
| 441 | - | ||
| 442 | - int data_count = 100; | ||
| 443 | - while (true) { | ||
| 444 | - SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 445 | - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 446 | - pkt->command_name = SRS_BW_CHECK_PUBLISHING; | ||
| 447 | - msg->set_packet(pkt, 0); | ||
| 448 | - | ||
| 449 | - for (int i = 0; i < data_count; ++i) { | ||
| 450 | - std::stringstream seq; | ||
| 451 | - seq << i; | ||
| 452 | - std::string play_data = "SrS band check data from client's publishing......"; | ||
| 453 | - pkt->data->set(seq.str(), new SrsAmf0String(play_data.c_str())); | ||
| 454 | - } | ||
| 455 | - data_count += 100; | ||
| 456 | - | ||
| 457 | - if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 458 | - srs_error("send publish message failed.ret=%d", ret); | ||
| 459 | - return ret; | ||
| 460 | - } | ||
| 461 | - | ||
| 462 | - if ((ret = expect_stop_pub()) == ERROR_SUCCESS) { | ||
| 463 | - break; | ||
| 464 | - } | ||
| 465 | - } | ||
| 466 | - | ||
| 467 | - return ret; | ||
| 468 | -} | ||
| 469 | - | ||
| 470 | -int SrsBandCheckClient::expect_stop_pub() | ||
| 471 | -{ | ||
| 472 | - int ret = ERROR_SUCCESS; | ||
| 473 | - | ||
| 474 | - while (true) { | ||
| 475 | - if ((ret = st_netfd_poll(get_st_fd(), POLLIN, 1000)) == ERROR_SUCCESS) { | ||
| 476 | - SrsCommonMessage* msg = 0; | ||
| 477 | - if ((ret = recv_message(&msg)) != ERROR_SUCCESS) | ||
| 478 | - { | ||
| 479 | - srs_error("recv message failed while expect stop pub. ret=%d", ret); | ||
| 480 | - return ret; | ||
| 481 | - } | ||
| 482 | - | ||
| 483 | - if ((ret = msg->decode_packet(get_protocol())) != ERROR_SUCCESS) { | ||
| 484 | - srs_error("decode packet error while expect stop pub. ret=%d", ret); | ||
| 485 | - return ret; | ||
| 486 | - } | ||
| 487 | - | ||
| 488 | - SrsBandwidthPacket* pkt = dynamic_cast<SrsBandwidthPacket*>(msg->get_packet()); | ||
| 489 | - if (pkt && pkt->command_name == SRS_BW_CHECK_STOP_PUBLISH) { | ||
| 490 | - | ||
| 491 | - return ret; | ||
| 492 | - } | ||
| 493 | - } else { | ||
| 494 | - break; | ||
| 495 | - } | ||
| 496 | - } | ||
| 497 | - | ||
| 498 | - return ret; | ||
| 499 | -} | ||
| 500 | - | ||
| 501 | -int SrsBandCheckClient::expect_finished() | ||
| 502 | -{ | ||
| 503 | - int ret = ERROR_SUCCESS; | ||
| 504 | - | ||
| 505 | - while (true) { | ||
| 506 | - SrsCommonMessage* msg = NULL; | ||
| 507 | - SrsBandwidthPacket* pkt = NULL; | ||
| 508 | - if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 509 | - srs_error("expect finished message failed. ret=%d", ret); | ||
| 510 | - return ret; | ||
| 511 | - } | ||
| 512 | - SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 513 | - srs_info("get bandcheck finished message"); | ||
| 514 | - | ||
| 515 | - if (pkt->command_name == SRS_BW_CHECK_FINISHED) { | ||
| 516 | - SrsStream *stream = new SrsStream; | ||
| 517 | - SrsAutoFree(SrsStream, stream, false); | ||
| 518 | - | ||
| 519 | - if ((ret = stream->initialize((char*)msg->payload, msg->size)) != ERROR_SUCCESS) { | ||
| 520 | - srs_error("initialize stream error. ret=%d", ret); | ||
| 521 | - return ret; | ||
| 522 | - } | ||
| 523 | - | ||
| 524 | - std::string command_name; | ||
| 525 | - if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { | ||
| 526 | - srs_error("amfo read string error. ret=%d", ret); | ||
| 527 | - return ret; | ||
| 528 | - } | ||
| 529 | - | ||
| 530 | - double action_id; | ||
| 531 | - if ((ret = srs_amf0_read_number(stream, action_id)) != ERROR_SUCCESS) { | ||
| 532 | - srs_error("amfo read number error. ret=%d", ret); | ||
| 533 | - return ret; | ||
| 534 | - } | ||
| 535 | - | ||
| 536 | - if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { | ||
| 537 | - srs_error("amfo read number error. ret=%d", ret); | ||
| 538 | - return ret; | ||
| 539 | - } | ||
| 540 | - | ||
| 541 | - SrsAmf0Object* object; | ||
| 542 | - if ((ret = srs_amf0_read_object(stream, object)) != ERROR_SUCCESS) { | ||
| 543 | - srs_error("amfo read object error. ret=%d", ret); | ||
| 544 | - return ret; | ||
| 545 | - } | ||
| 546 | - | ||
| 547 | - int64_t start_time = 0; | ||
| 548 | - int64_t end_time = 0; | ||
| 549 | - | ||
| 550 | - SrsAmf0Any* start_time_any = object->get_property("start_time"); | ||
| 551 | - if (start_time_any && start_time_any->is_number()) { | ||
| 552 | - SrsAmf0Number* start_time_number = dynamic_cast<SrsAmf0Number*> (start_time_any); | ||
| 553 | - if (start_time_number) { | ||
| 554 | - start_time = start_time_number->value; | ||
| 555 | - } | ||
| 556 | - } | ||
| 557 | - | ||
| 558 | - SrsAmf0Any* end_time_any = object->get_property("end_time"); | ||
| 559 | - if (end_time_any && end_time_any->is_number()) { | ||
| 560 | - SrsAmf0Number* end_time_number = dynamic_cast<SrsAmf0Number*> (end_time_any); | ||
| 561 | - if (end_time_number) { | ||
| 562 | - end_time = end_time_number->value; | ||
| 563 | - } | ||
| 564 | - } | ||
| 565 | - | ||
| 566 | - int play_kbps = 0; | ||
| 567 | - int pub_kbps = 0; | ||
| 568 | - SrsAmf0Any* play_kbp_any = object->get_property("play_kbps"); | ||
| 569 | - if (play_kbp_any && play_kbp_any->is_number()) { | ||
| 570 | - SrsAmf0Number* play_kbps_number = dynamic_cast<SrsAmf0Number*> (play_kbp_any); | ||
| 571 | - if (play_kbps_number) { | ||
| 572 | - play_kbps = play_kbps_number->value; | ||
| 573 | - } | ||
| 574 | - } | ||
| 575 | - | ||
| 576 | - SrsAmf0Any* pub_kbp_any = object->get_property("publish_kbps"); | ||
| 577 | - if (pub_kbp_any && pub_kbp_any->is_number()) { | ||
| 578 | - SrsAmf0Number* pub_kbps_number = dynamic_cast<SrsAmf0Number*> (pub_kbp_any); | ||
| 579 | - if (pub_kbps_number) { | ||
| 580 | - pub_kbps = pub_kbps_number->value; | ||
| 581 | - } | ||
| 582 | - } | ||
| 583 | - | ||
| 584 | - float time_elapsed; | ||
| 585 | - if (end_time - start_time > 0) { | ||
| 586 | - time_elapsed = (end_time - start_time) / 1000.00; | ||
| 587 | - } | ||
| 588 | - | ||
| 589 | - srs_trace("result: play %d kbps, publish %d kbps, check time %.4f S\n" | ||
| 590 | - , play_kbps, pub_kbps, time_elapsed); | ||
| 591 | - | ||
| 592 | - break; | ||
| 593 | - } | ||
| 594 | - } | ||
| 595 | - | ||
| 596 | - return ret; | ||
| 597 | -} | ||
| 598 | - | ||
| 599 | -int SrsBandCheckClient::send_stopped_pub() | ||
| 600 | -{ | ||
| 601 | - int ret = ERROR_SUCCESS; | ||
| 602 | - | ||
| 603 | - SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 604 | - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 605 | - pkt->command_name = SRS_BW_CHECK_STOPPED_PUBLISH; | ||
| 606 | - msg->set_packet(pkt, 0); | ||
| 607 | - | ||
| 608 | - if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 609 | - srs_error("send stopped pub msg failed. ret=%d", ret); | ||
| 610 | - return ret; | ||
| 611 | - } | ||
| 612 | - srs_info("send stopped pub msg success."); | ||
| 613 | - | ||
| 614 | - return ret; | ||
| 615 | -} | ||
| 616 | - | ||
| 617 | -int SrsBandCheckClient::send_final() | ||
| 618 | -{ | ||
| 619 | - int ret = ERROR_SUCCESS; | ||
| 620 | - | ||
| 621 | - SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 622 | - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 623 | - pkt->command_name = SRS_BW_CHECK_FLASH_FINAL; | ||
| 624 | - msg->set_packet(pkt, 0); | ||
| 625 | - | ||
| 626 | - if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 627 | - srs_error("send final msg failed. ret=%d", ret); | ||
| 628 | - return ret; | ||
| 629 | - } | ||
| 630 | - srs_info("send final msg success."); | ||
| 631 | - | ||
| 632 | - return ret; | ||
| 633 | -} | ||
| 634 | - | ||
| 635 | -SrsBandCheck::SrsBandCheck() | ||
| 636 | - : bandCheck_Client(0) | ||
| 637 | -{ | ||
| 638 | -} | ||
| 639 | - | ||
| 640 | -SrsBandCheck::~SrsBandCheck() | ||
| 641 | -{ | ||
| 642 | - if (bandCheck_Client) { | ||
| 643 | - srs_freep(bandCheck_Client); | ||
| 644 | - } | ||
| 645 | -} | ||
| 646 | - | ||
| 647 | -int SrsBandCheck::check(const std::string &app, const std::string &tcUrl) | ||
| 648 | -{ | ||
| 649 | - int ret = ERROR_SUCCESS; | ||
| 650 | - | ||
| 651 | - if ((ret = connect_server()) != ERROR_SUCCESS) { | ||
| 652 | - srs_error("connect to server failed. ret = %d", ret); | ||
| 653 | - return ret; | ||
| 654 | - } | ||
| 655 | - | ||
| 656 | - if ((ret = bandCheck_Client->handshake()) != ERROR_SUCCESS) { | ||
| 657 | - srs_error("handshake failed. ret = %d", ret); | ||
| 658 | - return ret; | ||
| 659 | - } | ||
| 660 | - | ||
| 661 | - if ((ret = bandCheck_Client->connect_app(app, tcUrl)) != ERROR_SUCCESS) { | ||
| 662 | - srs_error("handshake failed. ret = %d", ret); | ||
| 663 | - return ret; | ||
| 664 | - } | ||
| 665 | - | ||
| 666 | - if ((ret = bandCheck_Client->check_play()) != ERROR_SUCCESS) { | ||
| 667 | - srs_error("band check play failed."); | ||
| 668 | - return ret; | ||
| 669 | - } | ||
| 670 | - | ||
| 671 | - if ((ret = bandCheck_Client->check_publish()) != ERROR_SUCCESS) { | ||
| 672 | - srs_error("band check publish failed."); | ||
| 673 | - return ret; | ||
| 674 | - } | ||
| 675 | - | ||
| 676 | - return ret; | ||
| 677 | -} | ||
| 678 | - | ||
| 679 | -void SrsBandCheck::set_server(const std::string &server, int port) | ||
| 680 | -{ | ||
| 681 | - server_address = server; | ||
| 682 | - server_port = port; | ||
| 683 | -} | ||
| 684 | - | ||
| 685 | -int SrsBandCheck::connect_server() | ||
| 686 | -{ | ||
| 687 | - int ret = ERROR_SUCCESS; | ||
| 688 | - | ||
| 689 | - int sock = socket(AF_INET, SOCK_STREAM, 0); | ||
| 690 | - if(sock == -1){ | ||
| 691 | - ret = ERROR_SOCKET_CREATE; | ||
| 692 | - srs_error("create socket error. ret=%d", ret); | ||
| 693 | - return ret; | ||
| 694 | - } | ||
| 695 | - | ||
| 696 | - st_netfd_t stfd = st_netfd_open_socket(sock); | ||
| 697 | - if(stfd == NULL){ | ||
| 698 | - ret = ERROR_ST_OPEN_SOCKET; | ||
| 699 | - srs_error("st_netfd_open_socket failed. ret=%d", ret); | ||
| 700 | - return ret; | ||
| 701 | - } | ||
| 702 | - | ||
| 703 | - bandCheck_Client = new SrsBandCheckClient(stfd); | ||
| 704 | - | ||
| 705 | - // connect to server. | ||
| 706 | - std::string ip = srs_dns_resolve(server_address); | ||
| 707 | - if (ip.empty()) { | ||
| 708 | - ret = ERROR_SYSTEM_IP_INVALID; | ||
| 709 | - srs_error("dns resolve server error, ip empty. ret=%d", ret); | ||
| 710 | - return ret; | ||
| 711 | - } | ||
| 712 | - | ||
| 713 | - sockaddr_in addr; | ||
| 714 | - addr.sin_family = AF_INET; | ||
| 715 | - addr.sin_port = htons(server_port); | ||
| 716 | - addr.sin_addr.s_addr = inet_addr(ip.c_str()); | ||
| 717 | - | ||
| 718 | - if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){ | ||
| 719 | - ret = ERROR_ST_CONNECT; | ||
| 720 | - srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), server_port, ret); | ||
| 721 | - return ret; | ||
| 722 | - } | ||
| 723 | - srs_trace("connect to server success. server=%s, ip=%s, port=%d", server_address.c_str(), ip.c_str(), server_port); | ||
| 724 | - | ||
| 725 | - return ret; | ||
| 726 | -} | ||
| 727 | - | ||
| 728 | -int init_st() | ||
| 729 | -{ | ||
| 730 | - int ret = ERROR_SUCCESS; | ||
| 731 | - | ||
| 732 | - if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) { | ||
| 733 | - ret = ERROR_ST_SET_EPOLL; | ||
| 734 | - srs_error("st_set_eventsys use linux epoll failed. ret=%d", ret); | ||
| 735 | - return ret; | ||
| 736 | - } | ||
| 737 | - | ||
| 738 | - if(st_init() != 0){ | ||
| 739 | - ret = ERROR_ST_INITIALIZE; | ||
| 740 | - srs_error("st_init failed. ret=%d", ret); | ||
| 741 | - return ret; | ||
| 742 | - } | ||
| 743 | - | ||
| 744 | - return ret; | ||
| 745 | -} | ||
| 746 | - | ||
| 747 | -void print_help() | ||
| 748 | -{ | ||
| 749 | - const char *help = "Usage: srs-bandcheck [OPTION]...\n" | ||
| 750 | - "test band width from client to rtmp server.\n" | ||
| 751 | - | ||
| 752 | - "Mandatory arguments to long options are mandatory for short options too.\n" | ||
| 753 | - " -i, --ip the ip or domain that to test\n" | ||
| 754 | - " -p, --port the port that server listen \n" | ||
| 755 | - " -k, --key the key used to test \n" | ||
| 756 | - " -v, --vhost the vhost used to test \n" | ||
| 757 | - " -V, --version output version information and exit \n" | ||
| 758 | - " -h, --help display this help and exit \n" | ||
| 759 | - "\n\n\n" | ||
| 760 | - "Exit status:\n" | ||
| 761 | - "0 if OK,\n" | ||
| 762 | - "other if error occured, and the detail should be printed.\n" | ||
| 763 | - "\n\n" | ||
| 764 | - "srs home page: <winlin(winterserver): http://blog.csdn.net/win_lin>\n" | ||
| 765 | - "srs home page: <http://blog.chinaunix.net/uid/25006789.html>\n"; | ||
| 766 | - | ||
| 767 | - printf("%s", help); | ||
| 768 | -} | ||
| 769 | - | ||
| 770 | -void print_version() | ||
| 771 | -{ | ||
| 772 | - const char *version = "" | ||
| 773 | - "srs_bandcheck "BUILD_VERSION"\n" | ||
| 774 | - "Copyright (C) 2013 wenjiegit.\n" | ||
| 775 | - "License MIT\n" | ||
| 776 | - "This is free software: you are free to change and redistribute it.\n" | ||
| 777 | - "There is NO WARRANTY, to the extent permitted by law.\n" | ||
| 778 | - "\n" | ||
| 779 | - "Written by wenjie.\n"; | ||
| 780 | - | ||
| 781 | - printf("%s", version); | ||
| 782 | -} | ||
| 783 | - | ||
| 784 | -int get_opt(int argc, char *argv[]) | ||
| 785 | -{ | ||
| 786 | - int ret = ERROR_SUCCESS; | ||
| 787 | - | ||
| 788 | - int c; | ||
| 789 | - while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) { | ||
| 790 | - switch (c) { | ||
| 791 | - case 'i': | ||
| 792 | - if (optarg) { | ||
| 793 | - g_ip = optarg; | ||
| 794 | - } | ||
| 795 | - break; | ||
| 796 | - case 'p': | ||
| 797 | - if (optarg) { | ||
| 798 | - g_port = atoi(optarg); | ||
| 799 | - } | ||
| 800 | - break; | ||
| 801 | - case 'k': | ||
| 802 | - if (optarg) { | ||
| 803 | - g_key = optarg; | ||
| 804 | - } | ||
| 805 | - break; | ||
| 806 | - case 'v': | ||
| 807 | - if (optarg) { | ||
| 808 | - g_vhost = optarg; | ||
| 809 | - } | ||
| 810 | - break; | ||
| 811 | - case 'V': | ||
| 812 | - print_version(); | ||
| 813 | - exit(0); | ||
| 814 | - break; | ||
| 815 | - case 'h': | ||
| 816 | - print_help(); | ||
| 817 | - exit(0); | ||
| 818 | - break; | ||
| 819 | - default: | ||
| 820 | - printf("see --help or -h\n"); | ||
| 821 | - ret = -1; | ||
| 822 | - } | ||
| 823 | - } | ||
| 824 | - | ||
| 825 | - return ret; | ||
| 826 | -} | 1 | +/* |
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2014 wenjiegit | ||
| 5 | + | ||
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | +this software and associated documentation files (the "Software"), to deal in | ||
| 8 | +the Software without restriction, including without limitation the rights to | ||
| 9 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | +subject to the following conditions: | ||
| 12 | + | ||
| 13 | +The above copyright notice and this permission notice shall be included in all | ||
| 14 | +copies or substantial portions of the Software. | ||
| 15 | + | ||
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | +*/ | ||
| 23 | + | ||
| 24 | +#include <sys/socket.h> | ||
| 25 | +#include <netinet/in.h> | ||
| 26 | +#include <arpa/inet.h> | ||
| 27 | +#include <sstream> | ||
| 28 | +#include <getopt.h> | ||
| 29 | +#include <stdlib.h> | ||
| 30 | + | ||
| 31 | +#include <srs_core_rtmp.hpp> | ||
| 32 | +#include <srs_core_protocol.hpp> | ||
| 33 | +#include <srs_core_error.hpp> | ||
| 34 | +#include <srs_core_amf0.hpp> | ||
| 35 | +#include <srs_core_autofree.hpp> | ||
| 36 | +#include <srs_core_stream.hpp> | ||
| 37 | + | ||
| 38 | +#include <st.h> | ||
| 39 | + | ||
| 40 | +// server play control | ||
| 41 | +#define SRS_BW_CHECK_START_PLAY "onSrsBandCheckStartPlayBytes" | ||
| 42 | +#define SRS_BW_CHECK_STARTING_PLAY "onSrsBandCheckStartingPlayBytes" | ||
| 43 | +#define SRS_BW_CHECK_STOP_PLAY "onSrsBandCheckStopPlayBytes" | ||
| 44 | +#define SRS_BW_CHECK_STOPPED_PLAY "onSrsBandCheckStoppedPlayBytes" | ||
| 45 | + | ||
| 46 | +// server publish control | ||
| 47 | +#define SRS_BW_CHECK_START_PUBLISH "onSrsBandCheckStartPublishBytes" | ||
| 48 | +#define SRS_BW_CHECK_STARTING_PUBLISH "onSrsBandCheckStartingPublishBytes" | ||
| 49 | +#define SRS_BW_CHECK_STOP_PUBLISH "onSrsBandCheckStopPublishBytes" | ||
| 50 | +#define SRS_BW_CHECK_STOPPED_PUBLISH "onSrsBandCheckStoppedPublishBytes" | ||
| 51 | + | ||
| 52 | +// EOF control. | ||
| 53 | +#define SRS_BW_CHECK_FINISHED "onSrsBandCheckFinished" | ||
| 54 | +#define SRS_BW_CHECK_FLASH_FINAL "finalClientPacket" | ||
| 55 | + | ||
| 56 | +// client only | ||
| 57 | +#define SRS_BW_CHECK_PLAYING "onSrsBandCheckPlaying" | ||
| 58 | +#define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing" | ||
| 59 | + | ||
| 60 | +/** | ||
| 61 | +* @brief class of Linux version band check client | ||
| 62 | +* check play and publish speed. | ||
| 63 | +*/ | ||
| 64 | +class SrsBandCheckClient : public SrsRtmpClient | ||
| 65 | +{ | ||
| 66 | +public: | ||
| 67 | + SrsBandCheckClient(st_netfd_t _stfd); | ||
| 68 | + ~SrsBandCheckClient(); | ||
| 69 | + | ||
| 70 | +public: | ||
| 71 | + /** | ||
| 72 | + * @brief test play | ||
| 73 | + * | ||
| 74 | + */ | ||
| 75 | + int check_play(); | ||
| 76 | + /** | ||
| 77 | + * @brief test publish | ||
| 78 | + * | ||
| 79 | + */ | ||
| 80 | + int check_publish(); | ||
| 81 | + | ||
| 82 | +private: | ||
| 83 | + /** | ||
| 84 | + * @brief just return success. | ||
| 85 | + */ | ||
| 86 | + int create_stream(int& stream_id); | ||
| 87 | + /** | ||
| 88 | + * @brief just return success. | ||
| 89 | + */ | ||
| 90 | + int play(std::string stream, int stream_id); | ||
| 91 | + /** | ||
| 92 | + * @brief just return success. | ||
| 93 | + */ | ||
| 94 | + int publish(std::string stream, int stream_id); | ||
| 95 | + | ||
| 96 | +private: | ||
| 97 | + int expect_start_play(); | ||
| 98 | + int send_starting_play(); | ||
| 99 | + int expect_stop_play(); | ||
| 100 | + int send_stopped_play(); | ||
| 101 | + int expect_start_pub(); | ||
| 102 | + int send_starting_pub(); | ||
| 103 | + int send_pub_data(); | ||
| 104 | + int expect_stop_pub(); | ||
| 105 | + /** | ||
| 106 | + * @brief expect result. | ||
| 107 | + * because the core module has no method to decode this packet | ||
| 108 | + * so we must get the internal data and decode it here. | ||
| 109 | + */ | ||
| 110 | + int expect_finished(); | ||
| 111 | + int send_stopped_pub(); | ||
| 112 | + /** | ||
| 113 | + * @brief notify server the check procedure is over. | ||
| 114 | + */ | ||
| 115 | + int send_final(); | ||
| 116 | +}; | ||
| 117 | + | ||
| 118 | +/** | ||
| 119 | +* @brief class of band check | ||
| 120 | +* used to check band width with a client @param bandCheck_Client | ||
| 121 | +*/ | ||
| 122 | +class SrsBandCheck | ||
| 123 | +{ | ||
| 124 | +public: | ||
| 125 | + SrsBandCheck(); | ||
| 126 | + ~SrsBandCheck(); | ||
| 127 | + | ||
| 128 | +public: | ||
| 129 | + /** | ||
| 130 | + * @brief band check method | ||
| 131 | + * | ||
| 132 | + * connect to server------>rtmp handshake------>rtmp connect------>play------>publish | ||
| 133 | + * @retval ERROR_SUCCESS when success. | ||
| 134 | + */ | ||
| 135 | + int check(const std::string& app, const std::string& tcUrl); | ||
| 136 | + | ||
| 137 | + /** | ||
| 138 | + * @brief set the address and port of test server | ||
| 139 | + * | ||
| 140 | + * @param server server address, domain or ip | ||
| 141 | + * @param server listened port ,default is 1935 | ||
| 142 | + */ | ||
| 143 | + void set_server(const std::string& server, int port = 1935); | ||
| 144 | + | ||
| 145 | +private: | ||
| 146 | + int connect_server(); | ||
| 147 | + | ||
| 148 | +private: | ||
| 149 | + SrsBandCheckClient* bandCheck_Client; | ||
| 150 | + std::string server_address; | ||
| 151 | + int server_port; | ||
| 152 | +}; | ||
| 153 | + | ||
| 154 | +/** | ||
| 155 | +* @brief init st lib | ||
| 156 | +*/ | ||
| 157 | +static int init_st(); | ||
| 158 | +static void print_help(char** argv); | ||
| 159 | +static void print_version(); | ||
| 160 | + | ||
| 161 | +/** | ||
| 162 | +* @brief get user option | ||
| 163 | +* @internal ip Mandatory arguments | ||
| 164 | +* @internal key Mandatory arguments | ||
| 165 | +* @internal port default 1935 | ||
| 166 | +* @internal vhost default bandcheck.srs.com | ||
| 167 | +*/ | ||
| 168 | +static int get_opt(int argc ,char* argv[]); | ||
| 169 | + | ||
| 170 | +/** | ||
| 171 | +* global var. | ||
| 172 | +*/ | ||
| 173 | +static struct option long_options[] = | ||
| 174 | +{ | ||
| 175 | + {"ip", required_argument, 0, 'i'}, | ||
| 176 | + {"port", optional_argument, 0, 'p'}, | ||
| 177 | + {"key", required_argument, 0, 'k'}, | ||
| 178 | + {"vhost", optional_argument, 0, 'v'}, | ||
| 179 | + {"help", no_argument, 0, 'h'}, | ||
| 180 | + {"version", no_argument, 0, 'V'}, | ||
| 181 | +}; | ||
| 182 | + | ||
| 183 | +static const char* short_options = "i:p::k:v::hV"; | ||
| 184 | + | ||
| 185 | +static std::string g_ip; | ||
| 186 | +static int g_port = 1935; | ||
| 187 | +static std::string g_key; | ||
| 188 | +static std::string g_vhost = "bandcheck.srs.com"; | ||
| 189 | + | ||
| 190 | +#define BUILD_VERSION "srs band check 0.1" | ||
| 191 | + | ||
| 192 | +int main(int argc ,char* argv[]) | ||
| 193 | +{ | ||
| 194 | + int ret = ERROR_SUCCESS; | ||
| 195 | + | ||
| 196 | + if (argc <= 1) { | ||
| 197 | + print_help(argv); | ||
| 198 | + exit(1); | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | + if ((ret = get_opt(argc, argv)) != ERROR_SUCCESS) { | ||
| 202 | + return -1; | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + // check param | ||
| 206 | + if (g_ip.empty()) { | ||
| 207 | + printf("ip address should not be empty.\n"); | ||
| 208 | + return -1; | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + if (g_key.empty()) { | ||
| 212 | + printf("test key should not be empty.\n"); | ||
| 213 | + return -1; | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + if ((ret = init_st()) != ERROR_SUCCESS) { | ||
| 217 | + srs_error("band check init failed. ret=%d", ret); | ||
| 218 | + return ret; | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + std::string app = "app?key=" + g_key + "&vhost=" + g_vhost; | ||
| 222 | + | ||
| 223 | + char tcUrl_buffer[1024] = {0}; | ||
| 224 | + sprintf(tcUrl_buffer, "rtmp://%s:%d/%s", g_ip.c_str(), g_port, app.c_str()); | ||
| 225 | + std::string tcUrl = tcUrl_buffer; | ||
| 226 | + | ||
| 227 | + SrsBandCheck band_check; | ||
| 228 | + band_check.set_server(g_ip, g_port); | ||
| 229 | + if ((ret = band_check.check(app, tcUrl)) != ERROR_SUCCESS) { | ||
| 230 | + srs_error("band check failed. address=%s ret=%d", "xx.com", ret); | ||
| 231 | + return -1; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + return 0; | ||
| 235 | +} | ||
| 236 | + | ||
| 237 | +SrsBandCheckClient::SrsBandCheckClient(st_netfd_t _stfd) | ||
| 238 | + : SrsRtmpClient(_stfd) | ||
| 239 | +{ | ||
| 240 | +} | ||
| 241 | + | ||
| 242 | +SrsBandCheckClient::~SrsBandCheckClient() | ||
| 243 | +{ | ||
| 244 | +} | ||
| 245 | + | ||
| 246 | +int SrsBandCheckClient::check_play() | ||
| 247 | +{ | ||
| 248 | + int ret = ERROR_SUCCESS; | ||
| 249 | + | ||
| 250 | + if ((ret = expect_start_play()) != ERROR_SUCCESS) { | ||
| 251 | + srs_error("expect_start_play failed. ret=%d", ret); | ||
| 252 | + return ret; | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + if ((ret = send_starting_play()) != ERROR_SUCCESS) { | ||
| 256 | + srs_error("send starting play failed. ret=%d", ret); | ||
| 257 | + return ret; | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + if ((ret = expect_stop_play()) != ERROR_SUCCESS) { | ||
| 261 | + srs_error("expect stop play failed. ret=%d", ret); | ||
| 262 | + return ret; | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + if ((ret = send_stopped_play()) != ERROR_SUCCESS) { | ||
| 266 | + srs_error("send stopped play failed. ret=%d", ret); | ||
| 267 | + return ret; | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + return ret; | ||
| 271 | +} | ||
| 272 | + | ||
| 273 | +int SrsBandCheckClient::check_publish() | ||
| 274 | +{ | ||
| 275 | + int ret = ERROR_SUCCESS; | ||
| 276 | + | ||
| 277 | + if ((ret = expect_start_pub()) != ERROR_SUCCESS) { | ||
| 278 | + srs_error("expect start pub failed. ret=%d", ret); | ||
| 279 | + return ret; | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + if ((ret = send_starting_pub())!= ERROR_SUCCESS) { | ||
| 283 | + srs_error("send starting pub failed. ret=%d", ret); | ||
| 284 | + return ret; | ||
| 285 | + } | ||
| 286 | + | ||
| 287 | + if ((ret = send_pub_data()) != ERROR_SUCCESS) { | ||
| 288 | + srs_error("publish data failed. ret=%d", ret); | ||
| 289 | + return ret; | ||
| 290 | + } | ||
| 291 | + | ||
| 292 | + if ((ret = send_stopped_pub()) != ERROR_SUCCESS) { | ||
| 293 | + srs_error("send stopped pub failed. ret=%d", ret); | ||
| 294 | + return ret; | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + if ((ret = expect_finished()) != ERROR_SUCCESS) { | ||
| 298 | + srs_error("expect finished msg failed. ret=%d", ret); | ||
| 299 | + return ret; | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + if ((ret = send_final()) != ERROR_SUCCESS) { | ||
| 303 | + srs_error("send final msg failed. ret=%d", ret); | ||
| 304 | + return ret; | ||
| 305 | + } | ||
| 306 | + | ||
| 307 | + return ret; | ||
| 308 | +} | ||
| 309 | + | ||
| 310 | +int SrsBandCheckClient::create_stream(int &stream_id) | ||
| 311 | +{ | ||
| 312 | + return ERROR_SUCCESS; | ||
| 313 | +} | ||
| 314 | + | ||
| 315 | +int SrsBandCheckClient::play(std::string stream, int stream_id) | ||
| 316 | +{ | ||
| 317 | + return ERROR_SUCCESS; | ||
| 318 | +} | ||
| 319 | + | ||
| 320 | +int SrsBandCheckClient::publish(std::string stream, int stream_id) | ||
| 321 | +{ | ||
| 322 | + return ERROR_SUCCESS; | ||
| 323 | +} | ||
| 324 | + | ||
| 325 | +int SrsBandCheckClient::expect_start_play() | ||
| 326 | +{ | ||
| 327 | + int ret = ERROR_SUCCESS; | ||
| 328 | + | ||
| 329 | + // expect connect _result | ||
| 330 | + SrsCommonMessage* msg = NULL; | ||
| 331 | + SrsBandwidthPacket* pkt = NULL; | ||
| 332 | + if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 333 | + srs_error("expect bandcheck start play message failed. ret=%d", ret); | ||
| 334 | + return ret; | ||
| 335 | + } | ||
| 336 | + SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 337 | + srs_info("get bandcheck start play message"); | ||
| 338 | + | ||
| 339 | + if (pkt->command_name != SRS_BW_CHECK_START_PLAY) { | ||
| 340 | + srs_error("pkt error. expect=%s, actual=%s", SRS_BW_CHECK_START_PLAY, pkt->command_name.c_str()); | ||
| 341 | + return -1; | ||
| 342 | + } | ||
| 343 | + | ||
| 344 | + return ret; | ||
| 345 | +} | ||
| 346 | + | ||
| 347 | +int SrsBandCheckClient::send_starting_play() | ||
| 348 | +{ | ||
| 349 | + int ret = ERROR_SUCCESS; | ||
| 350 | + | ||
| 351 | + SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 352 | + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 353 | + pkt->command_name = SRS_BW_CHECK_STARTING_PLAY; | ||
| 354 | + msg->set_packet(pkt, 0); | ||
| 355 | + | ||
| 356 | + if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 357 | + srs_error("send starting play msg failed. ret=%d", ret); | ||
| 358 | + return ret; | ||
| 359 | + } | ||
| 360 | + | ||
| 361 | + return ret; | ||
| 362 | +} | ||
| 363 | + | ||
| 364 | +int SrsBandCheckClient::expect_stop_play() | ||
| 365 | +{ | ||
| 366 | + int ret = ERROR_SUCCESS; | ||
| 367 | + | ||
| 368 | + while (true) { | ||
| 369 | + SrsCommonMessage* msg = NULL; | ||
| 370 | + SrsBandwidthPacket* pkt = NULL; | ||
| 371 | + if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 372 | + srs_error("expect stop play message failed. ret=%d", ret); | ||
| 373 | + return ret; | ||
| 374 | + } | ||
| 375 | + SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 376 | + srs_info("get bandcheck stop play message"); | ||
| 377 | + | ||
| 378 | + if (pkt->command_name == SRS_BW_CHECK_STOP_PLAY) { | ||
| 379 | + break; | ||
| 380 | + } | ||
| 381 | + } | ||
| 382 | + | ||
| 383 | + return ret; | ||
| 384 | +} | ||
| 385 | + | ||
| 386 | +int SrsBandCheckClient::send_stopped_play() | ||
| 387 | +{ | ||
| 388 | + int ret = ERROR_SUCCESS; | ||
| 389 | + | ||
| 390 | + SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 391 | + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 392 | + pkt->command_name = SRS_BW_CHECK_STOPPED_PLAY; | ||
| 393 | + msg->set_packet(pkt, 0); | ||
| 394 | + | ||
| 395 | + if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 396 | + srs_error("send stopped play msg failed. ret=%d", ret); | ||
| 397 | + return ret; | ||
| 398 | + } | ||
| 399 | + | ||
| 400 | + return ret; | ||
| 401 | +} | ||
| 402 | + | ||
| 403 | +int SrsBandCheckClient::expect_start_pub() | ||
| 404 | +{ | ||
| 405 | + int ret = ERROR_SUCCESS; | ||
| 406 | + | ||
| 407 | + while (true) { | ||
| 408 | + SrsCommonMessage* msg = NULL; | ||
| 409 | + SrsBandwidthPacket* pkt = NULL; | ||
| 410 | + if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 411 | + srs_error("expect start pub message failed. ret=%d", ret); | ||
| 412 | + return ret; | ||
| 413 | + } | ||
| 414 | + SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 415 | + srs_info("get bandcheck start pub message"); | ||
| 416 | + | ||
| 417 | + if (pkt->command_name == SRS_BW_CHECK_START_PUBLISH) { | ||
| 418 | + break; | ||
| 419 | + } | ||
| 420 | + } | ||
| 421 | + | ||
| 422 | + return ret; | ||
| 423 | +} | ||
| 424 | + | ||
| 425 | +int SrsBandCheckClient::send_starting_pub() | ||
| 426 | +{ | ||
| 427 | + int ret = ERROR_SUCCESS; | ||
| 428 | + | ||
| 429 | + SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 430 | + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 431 | + pkt->command_name = SRS_BW_CHECK_STARTING_PUBLISH; | ||
| 432 | + msg->set_packet(pkt, 0); | ||
| 433 | + | ||
| 434 | + if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 435 | + srs_error("send starting play msg failed. ret=%d", ret); | ||
| 436 | + return ret; | ||
| 437 | + } | ||
| 438 | + srs_info("send starting play msg success."); | ||
| 439 | + | ||
| 440 | + return ret; | ||
| 441 | +} | ||
| 442 | + | ||
| 443 | +int SrsBandCheckClient::send_pub_data() | ||
| 444 | +{ | ||
| 445 | + int ret = ERROR_SUCCESS; | ||
| 446 | + | ||
| 447 | + int data_count = 100; | ||
| 448 | + while (true) { | ||
| 449 | + SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 450 | + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 451 | + pkt->command_name = SRS_BW_CHECK_PUBLISHING; | ||
| 452 | + msg->set_packet(pkt, 0); | ||
| 453 | + | ||
| 454 | + for (int i = 0; i < data_count; ++i) { | ||
| 455 | + std::stringstream seq; | ||
| 456 | + seq << i; | ||
| 457 | + std::string play_data = "SrS band check data from client's publishing......"; | ||
| 458 | + pkt->data->set(seq.str(), new SrsAmf0String(play_data.c_str())); | ||
| 459 | + } | ||
| 460 | + data_count += 100; | ||
| 461 | + | ||
| 462 | + if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 463 | + srs_error("send publish message failed.ret=%d", ret); | ||
| 464 | + return ret; | ||
| 465 | + } | ||
| 466 | + | ||
| 467 | + if ((ret = expect_stop_pub()) == ERROR_SUCCESS) { | ||
| 468 | + break; | ||
| 469 | + } | ||
| 470 | + } | ||
| 471 | + | ||
| 472 | + return ret; | ||
| 473 | +} | ||
| 474 | + | ||
| 475 | +int SrsBandCheckClient::expect_stop_pub() | ||
| 476 | +{ | ||
| 477 | + int ret = ERROR_SUCCESS; | ||
| 478 | + | ||
| 479 | + while (true) { | ||
| 480 | + if ((ret = st_netfd_poll(stfd, POLLIN, 1000)) == ERROR_SUCCESS) { | ||
| 481 | + SrsCommonMessage* msg = 0; | ||
| 482 | + if ((ret = recv_message(&msg)) != ERROR_SUCCESS) | ||
| 483 | + { | ||
| 484 | + srs_error("recv message failed while expect stop pub. ret=%d", ret); | ||
| 485 | + return ret; | ||
| 486 | + } | ||
| 487 | + | ||
| 488 | + if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) { | ||
| 489 | + srs_error("decode packet error while expect stop pub. ret=%d", ret); | ||
| 490 | + return ret; | ||
| 491 | + } | ||
| 492 | + | ||
| 493 | + SrsBandwidthPacket* pkt = dynamic_cast<SrsBandwidthPacket*>(msg->get_packet()); | ||
| 494 | + if (pkt && pkt->command_name == SRS_BW_CHECK_STOP_PUBLISH) { | ||
| 495 | + | ||
| 496 | + return ret; | ||
| 497 | + } | ||
| 498 | + } else { | ||
| 499 | + break; | ||
| 500 | + } | ||
| 501 | + } | ||
| 502 | + | ||
| 503 | + return ret; | ||
| 504 | +} | ||
| 505 | + | ||
| 506 | +int SrsBandCheckClient::expect_finished() | ||
| 507 | +{ | ||
| 508 | + int ret = ERROR_SUCCESS; | ||
| 509 | + | ||
| 510 | + while (true) { | ||
| 511 | + SrsCommonMessage* msg = NULL; | ||
| 512 | + SrsBandwidthPacket* pkt = NULL; | ||
| 513 | + if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { | ||
| 514 | + srs_error("expect finished message failed. ret=%d", ret); | ||
| 515 | + return ret; | ||
| 516 | + } | ||
| 517 | + SrsAutoFree(SrsCommonMessage, msg, false); | ||
| 518 | + srs_info("get bandcheck finished message"); | ||
| 519 | + | ||
| 520 | + if (pkt->command_name == SRS_BW_CHECK_FINISHED) { | ||
| 521 | + SrsStream *stream = new SrsStream; | ||
| 522 | + SrsAutoFree(SrsStream, stream, false); | ||
| 523 | + | ||
| 524 | + if ((ret = stream->initialize((char*)msg->payload, msg->size)) != ERROR_SUCCESS) { | ||
| 525 | + srs_error("initialize stream error. ret=%d", ret); | ||
| 526 | + return ret; | ||
| 527 | + } | ||
| 528 | + | ||
| 529 | + std::string command_name; | ||
| 530 | + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { | ||
| 531 | + srs_error("amfo read string error. ret=%d", ret); | ||
| 532 | + return ret; | ||
| 533 | + } | ||
| 534 | + | ||
| 535 | + double action_id; | ||
| 536 | + if ((ret = srs_amf0_read_number(stream, action_id)) != ERROR_SUCCESS) { | ||
| 537 | + srs_error("amfo read number error. ret=%d", ret); | ||
| 538 | + return ret; | ||
| 539 | + } | ||
| 540 | + | ||
| 541 | + if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { | ||
| 542 | + srs_error("amfo read number error. ret=%d", ret); | ||
| 543 | + return ret; | ||
| 544 | + } | ||
| 545 | + | ||
| 546 | + SrsAmf0Object* object; | ||
| 547 | + if ((ret = srs_amf0_read_object(stream, object)) != ERROR_SUCCESS) { | ||
| 548 | + srs_error("amfo read object error. ret=%d", ret); | ||
| 549 | + return ret; | ||
| 550 | + } | ||
| 551 | + | ||
| 552 | + int64_t start_time = 0; | ||
| 553 | + int64_t end_time = 0; | ||
| 554 | + | ||
| 555 | + SrsAmf0Any* start_time_any = object->get_property("start_time"); | ||
| 556 | + if (start_time_any && start_time_any->is_number()) { | ||
| 557 | + SrsAmf0Number* start_time_number = dynamic_cast<SrsAmf0Number*> (start_time_any); | ||
| 558 | + if (start_time_number) { | ||
| 559 | + start_time = start_time_number->value; | ||
| 560 | + } | ||
| 561 | + } | ||
| 562 | + | ||
| 563 | + SrsAmf0Any* end_time_any = object->get_property("end_time"); | ||
| 564 | + if (end_time_any && end_time_any->is_number()) { | ||
| 565 | + SrsAmf0Number* end_time_number = dynamic_cast<SrsAmf0Number*> (end_time_any); | ||
| 566 | + if (end_time_number) { | ||
| 567 | + end_time = end_time_number->value; | ||
| 568 | + } | ||
| 569 | + } | ||
| 570 | + | ||
| 571 | + int play_kbps = 0; | ||
| 572 | + int pub_kbps = 0; | ||
| 573 | + SrsAmf0Any* play_kbp_any = object->get_property("play_kbps"); | ||
| 574 | + if (play_kbp_any && play_kbp_any->is_number()) { | ||
| 575 | + SrsAmf0Number* play_kbps_number = dynamic_cast<SrsAmf0Number*> (play_kbp_any); | ||
| 576 | + if (play_kbps_number) { | ||
| 577 | + play_kbps = play_kbps_number->value; | ||
| 578 | + } | ||
| 579 | + } | ||
| 580 | + | ||
| 581 | + SrsAmf0Any* pub_kbp_any = object->get_property("publish_kbps"); | ||
| 582 | + if (pub_kbp_any && pub_kbp_any->is_number()) { | ||
| 583 | + SrsAmf0Number* pub_kbps_number = dynamic_cast<SrsAmf0Number*> (pub_kbp_any); | ||
| 584 | + if (pub_kbps_number) { | ||
| 585 | + pub_kbps = pub_kbps_number->value; | ||
| 586 | + } | ||
| 587 | + } | ||
| 588 | + | ||
| 589 | + float time_elapsed; | ||
| 590 | + if (end_time - start_time > 0) { | ||
| 591 | + time_elapsed = (end_time - start_time) / 1000.00; | ||
| 592 | + } | ||
| 593 | + | ||
| 594 | + srs_trace("result: play %d kbps, publish %d kbps, check time %.4f S\n" | ||
| 595 | + , play_kbps, pub_kbps, time_elapsed); | ||
| 596 | + | ||
| 597 | + break; | ||
| 598 | + } | ||
| 599 | + } | ||
| 600 | + | ||
| 601 | + return ret; | ||
| 602 | +} | ||
| 603 | + | ||
| 604 | +int SrsBandCheckClient::send_stopped_pub() | ||
| 605 | +{ | ||
| 606 | + int ret = ERROR_SUCCESS; | ||
| 607 | + | ||
| 608 | + SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 609 | + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 610 | + pkt->command_name = SRS_BW_CHECK_STOPPED_PUBLISH; | ||
| 611 | + msg->set_packet(pkt, 0); | ||
| 612 | + | ||
| 613 | + if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 614 | + srs_error("send stopped pub msg failed. ret=%d", ret); | ||
| 615 | + return ret; | ||
| 616 | + } | ||
| 617 | + srs_info("send stopped pub msg success."); | ||
| 618 | + | ||
| 619 | + return ret; | ||
| 620 | +} | ||
| 621 | + | ||
| 622 | +int SrsBandCheckClient::send_final() | ||
| 623 | +{ | ||
| 624 | + int ret = ERROR_SUCCESS; | ||
| 625 | + | ||
| 626 | + SrsCommonMessage* msg = new SrsCommonMessage; | ||
| 627 | + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; | ||
| 628 | + pkt->command_name = SRS_BW_CHECK_FLASH_FINAL; | ||
| 629 | + msg->set_packet(pkt, 0); | ||
| 630 | + | ||
| 631 | + if ((ret = send_message(msg)) != ERROR_SUCCESS) { | ||
| 632 | + srs_error("send final msg failed. ret=%d", ret); | ||
| 633 | + return ret; | ||
| 634 | + } | ||
| 635 | + srs_info("send final msg success."); | ||
| 636 | + | ||
| 637 | + return ret; | ||
| 638 | +} | ||
| 639 | + | ||
| 640 | +SrsBandCheck::SrsBandCheck() | ||
| 641 | + : bandCheck_Client(0) | ||
| 642 | +{ | ||
| 643 | +} | ||
| 644 | + | ||
| 645 | +SrsBandCheck::~SrsBandCheck() | ||
| 646 | +{ | ||
| 647 | + if (bandCheck_Client) { | ||
| 648 | + srs_freep(bandCheck_Client); | ||
| 649 | + } | ||
| 650 | +} | ||
| 651 | + | ||
| 652 | +int SrsBandCheck::check(const std::string &app, const std::string &tcUrl) | ||
| 653 | +{ | ||
| 654 | + int ret = ERROR_SUCCESS; | ||
| 655 | + | ||
| 656 | + if ((ret = connect_server()) != ERROR_SUCCESS) { | ||
| 657 | + srs_error("connect to server failed. ret = %d", ret); | ||
| 658 | + return ret; | ||
| 659 | + } | ||
| 660 | + | ||
| 661 | + if ((ret = bandCheck_Client->handshake()) != ERROR_SUCCESS) { | ||
| 662 | + srs_error("handshake failed. ret = %d", ret); | ||
| 663 | + return ret; | ||
| 664 | + } | ||
| 665 | + | ||
| 666 | + if ((ret = bandCheck_Client->connect_app(app, tcUrl)) != ERROR_SUCCESS) { | ||
| 667 | + srs_error("handshake failed. ret = %d", ret); | ||
| 668 | + return ret; | ||
| 669 | + } | ||
| 670 | + | ||
| 671 | + if ((ret = bandCheck_Client->check_play()) != ERROR_SUCCESS) { | ||
| 672 | + srs_error("band check play failed."); | ||
| 673 | + return ret; | ||
| 674 | + } | ||
| 675 | + | ||
| 676 | + if ((ret = bandCheck_Client->check_publish()) != ERROR_SUCCESS) { | ||
| 677 | + srs_error("band check publish failed."); | ||
| 678 | + return ret; | ||
| 679 | + } | ||
| 680 | + | ||
| 681 | + return ret; | ||
| 682 | +} | ||
| 683 | + | ||
| 684 | +void SrsBandCheck::set_server(const std::string &server, int port) | ||
| 685 | +{ | ||
| 686 | + server_address = server; | ||
| 687 | + server_port = port; | ||
| 688 | +} | ||
| 689 | + | ||
| 690 | +int SrsBandCheck::connect_server() | ||
| 691 | +{ | ||
| 692 | + int ret = ERROR_SUCCESS; | ||
| 693 | + | ||
| 694 | + int sock = socket(AF_INET, SOCK_STREAM, 0); | ||
| 695 | + if(sock == -1){ | ||
| 696 | + ret = ERROR_SOCKET_CREATE; | ||
| 697 | + srs_error("create socket error. ret=%d", ret); | ||
| 698 | + return ret; | ||
| 699 | + } | ||
| 700 | + | ||
| 701 | + st_netfd_t stfd = st_netfd_open_socket(sock); | ||
| 702 | + if(stfd == NULL){ | ||
| 703 | + ret = ERROR_ST_OPEN_SOCKET; | ||
| 704 | + srs_error("st_netfd_open_socket failed. ret=%d", ret); | ||
| 705 | + return ret; | ||
| 706 | + } | ||
| 707 | + | ||
| 708 | + bandCheck_Client = new SrsBandCheckClient(stfd); | ||
| 709 | + | ||
| 710 | + // connect to server. | ||
| 711 | + std::string ip = srs_dns_resolve(server_address); | ||
| 712 | + if (ip.empty()) { | ||
| 713 | + ret = ERROR_SYSTEM_IP_INVALID; | ||
| 714 | + srs_error("dns resolve server error, ip empty. ret=%d", ret); | ||
| 715 | + return ret; | ||
| 716 | + } | ||
| 717 | + | ||
| 718 | + sockaddr_in addr; | ||
| 719 | + addr.sin_family = AF_INET; | ||
| 720 | + addr.sin_port = htons(server_port); | ||
| 721 | + addr.sin_addr.s_addr = inet_addr(ip.c_str()); | ||
| 722 | + | ||
| 723 | + if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){ | ||
| 724 | + ret = ERROR_ST_CONNECT; | ||
| 725 | + srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), server_port, ret); | ||
| 726 | + return ret; | ||
| 727 | + } | ||
| 728 | + srs_trace("connect to server success. server=%s, ip=%s, port=%d", server_address.c_str(), ip.c_str(), server_port); | ||
| 729 | + | ||
| 730 | + return ret; | ||
| 731 | +} | ||
| 732 | + | ||
| 733 | +int init_st() | ||
| 734 | +{ | ||
| 735 | + int ret = ERROR_SUCCESS; | ||
| 736 | + | ||
| 737 | + if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) { | ||
| 738 | + ret = ERROR_ST_SET_EPOLL; | ||
| 739 | + srs_error("st_set_eventsys use linux epoll failed. ret=%d", ret); | ||
| 740 | + return ret; | ||
| 741 | + } | ||
| 742 | + | ||
| 743 | + if(st_init() != 0){ | ||
| 744 | + ret = ERROR_ST_INITIALIZE; | ||
| 745 | + srs_error("st_init failed. ret=%d", ret); | ||
| 746 | + return ret; | ||
| 747 | + } | ||
| 748 | + | ||
| 749 | + return ret; | ||
| 750 | +} | ||
| 751 | + | ||
| 752 | +void print_help(char** argv) | ||
| 753 | +{ | ||
| 754 | + printf( | ||
| 755 | + "Usage: %s [OPTION]...\n" | ||
| 756 | + "test band width from client to rtmp server.\n" | ||
| 757 | + "Mandatory arguments to long options are mandatory for short options too.\n" | ||
| 758 | + " -i, --ip the ip or domain that to test\n" | ||
| 759 | + " -p, --port the port that server listen \n" | ||
| 760 | + " -k, --key the key used to test \n" | ||
| 761 | + " -v, --vhost the vhost used to test \n" | ||
| 762 | + " -V, --version output version information and exit \n" | ||
| 763 | + " -h, --help display this help and exit \n" | ||
| 764 | + "\n" | ||
| 765 | + "For example:\n" | ||
| 766 | + " %s -i 192.168.1.248 -p 1935 -v bandcheck.srs.com -k 35c9b402c12a7246868752e2878f7e0e" | ||
| 767 | + "\n\n" | ||
| 768 | + "Exit status:\n" | ||
| 769 | + "0 if OK,\n" | ||
| 770 | + "other if error occured, and the detail should be printed.\n" | ||
| 771 | + "\n\n" | ||
| 772 | + "srs home page: <http://blog.chinaunix.net/uid/25006789.html>\n", | ||
| 773 | + argv[0], argv[0]); | ||
| 774 | +} | ||
| 775 | + | ||
| 776 | +void print_version() | ||
| 777 | +{ | ||
| 778 | + const char *version = "" | ||
| 779 | + "srs_bandcheck "BUILD_VERSION"\n" | ||
| 780 | + "Copyright (c) 2013-2014 wenjiegit.\n" | ||
| 781 | + "License MIT\n" | ||
| 782 | + "This is free software: you are free to change and redistribute it.\n" | ||
| 783 | + "There is NO WARRANTY, to the extent permitted by law.\n" | ||
| 784 | + "\n" | ||
| 785 | + "Written by wenjie.\n"; | ||
| 786 | + | ||
| 787 | + printf("%s", version); | ||
| 788 | +} | ||
| 789 | + | ||
| 790 | +int get_opt(int argc, char *argv[]) | ||
| 791 | +{ | ||
| 792 | + int ret = ERROR_SUCCESS; | ||
| 793 | + | ||
| 794 | + int c; | ||
| 795 | + while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) { | ||
| 796 | + switch (c) { | ||
| 797 | + case 'i': | ||
| 798 | + if (optarg) { | ||
| 799 | + g_ip = optarg; | ||
| 800 | + } | ||
| 801 | + break; | ||
| 802 | + case 'p': | ||
| 803 | + if (optarg) { | ||
| 804 | + g_port = atoi(optarg); | ||
| 805 | + } | ||
| 806 | + break; | ||
| 807 | + case 'k': | ||
| 808 | + if (optarg) { | ||
| 809 | + g_key = optarg; | ||
| 810 | + } | ||
| 811 | + break; | ||
| 812 | + case 'v': | ||
| 813 | + if (optarg) { | ||
| 814 | + g_vhost = optarg; | ||
| 815 | + } | ||
| 816 | + break; | ||
| 817 | + case 'V': | ||
| 818 | + print_version(); | ||
| 819 | + exit(0); | ||
| 820 | + break; | ||
| 821 | + case 'h': | ||
| 822 | + print_help(argv); | ||
| 823 | + exit(0); | ||
| 824 | + break; | ||
| 825 | + default: | ||
| 826 | + printf("see --help or -h\n"); | ||
| 827 | + ret = -1; | ||
| 828 | + } | ||
| 829 | + } | ||
| 830 | + | ||
| 831 | + return ret; | ||
| 832 | +} |
| 1 | /* | 1 | /* |
| 2 | The MIT License (MIT) | 2 | The MIT License (MIT) |
| 3 | 3 | ||
| 4 | -Copyright (c) 2013 winlin | 4 | +Copyright (c) 2013-2014 winlin |
| 5 | 5 | ||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 7 | this software and associated documentation files (the "Software"), to deal in | 7 | this software and associated documentation files (the "Software"), to deal in |
| 1 | file | 1 | file |
| 2 | main readonly separator, | 2 | main readonly separator, |
| 3 | ..\main\srs_main_server.cpp, | 3 | ..\main\srs_main_server.cpp, |
| 4 | + ..\main\srs_main_bandcheck.cpp, | ||
| 4 | auto readonly separator, | 5 | auto readonly separator, |
| 5 | ..\..\objs\srs_auto_headers.hpp, | 6 | ..\..\objs\srs_auto_headers.hpp, |
| 6 | core readonly separator, | 7 | core readonly separator, |
| @@ -57,7 +58,7 @@ file | @@ -57,7 +58,7 @@ file | ||
| 57 | ..\core\srs_core_source.hpp, | 58 | ..\core\srs_core_source.hpp, |
| 58 | ..\core\srs_core_source.cpp, | 59 | ..\core\srs_core_source.cpp, |
| 59 | research readonly separator, | 60 | research readonly separator, |
| 60 | - ..\..\research\ts_info.cc; | 61 | + ..\..\research\hls\ts_info.cc; |
| 61 | 62 | ||
| 62 | mainconfig | 63 | mainconfig |
| 63 | "" = "MAIN"; | 64 | "" = "MAIN"; |
-
请 注册 或 登录 后发表评论