正在显示
4 个修改的文件
包含
182 行增加
和
15 行删除
| @@ -33,35 +33,77 @@ int main(int argc, char** argv) | @@ -33,35 +33,77 @@ int main(int argc, char** argv) | ||
| 33 | { | 33 | { |
| 34 | srs_rtmp_t rtmp; | 34 | srs_rtmp_t rtmp; |
| 35 | 35 | ||
| 36 | + // time | ||
| 37 | + int64_t time_startup = srs_get_time_ms(); | ||
| 38 | + int64_t time_dns_resolve = 0; | ||
| 39 | + int64_t time_socket_connect = 0; | ||
| 40 | + int64_t time_play_stream = 0; | ||
| 41 | + int64_t time_first_packet = 0; | ||
| 42 | + int64_t time_cleanup = 0; | ||
| 43 | + // delay = actual - expect time when quit. | ||
| 44 | + int delay = 0; | ||
| 45 | + | ||
| 36 | // packet data | 46 | // packet data |
| 37 | int type, size; | 47 | int type, size; |
| 38 | u_int32_t timestamp = 0; | 48 | u_int32_t timestamp = 0; |
| 39 | char* data; | 49 | char* data; |
| 40 | 50 | ||
| 41 | - if (argc <= 1) { | 51 | + // user options |
| 52 | + const char* rtmp_url = NULL; | ||
| 53 | + int duration = 0; | ||
| 54 | + int timeout = 0; | ||
| 55 | + | ||
| 56 | + if (argc <= 3) { | ||
| 42 | printf("detect stream on RTMP server\n" | 57 | printf("detect stream on RTMP server\n" |
| 43 | - "Usage: %s <rtmp_url>\n" | 58 | + "Usage: %s <rtmp_url> <duration> <timeout>\n" |
| 44 | " rtmp_url RTMP stream url to play\n" | 59 | " rtmp_url RTMP stream url to play\n" |
| 60 | + " duration how long to play, in seconds, stream time.\n" | ||
| 61 | + " timeout how long to timeout, in seconds, system time.\n" | ||
| 45 | "For example:\n" | 62 | "For example:\n" |
| 46 | - " %s rtmp://127.0.0.1:1935/live/livestream\n", | 63 | + " %s rtmp://127.0.0.1:1935/live/livestream 3 10\n", |
| 47 | argv[0]); | 64 | argv[0]); |
| 48 | int ret = 1; | 65 | int ret = 1; |
| 49 | exit(ret); | 66 | exit(ret); |
| 50 | return ret; | 67 | return ret; |
| 51 | } | 68 | } |
| 52 | 69 | ||
| 53 | - rtmp = srs_rtmp_create(argv[1]); | 70 | + rtmp_url = argv[1]; |
| 71 | + duration = atoi(argv[2]); | ||
| 72 | + timeout = atoi(argv[3]); | ||
| 54 | 73 | ||
| 55 | printf("detect rtmp stream\n"); | 74 | printf("detect rtmp stream\n"); |
| 56 | printf("srs(simple-rtmp-server) client librtmp library.\n"); | 75 | printf("srs(simple-rtmp-server) client librtmp library.\n"); |
| 57 | printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); | 76 | printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); |
| 58 | - printf("rtmp url: %s\n", rtmp); | 77 | + printf("rtmp url: %s\n", rtmp_url); |
| 78 | + printf("duration: %ds, timeout:%ds\n", duration, timeout); | ||
| 79 | + | ||
| 80 | + if (duration <= 0 || timeout <= 0) { | ||
| 81 | + printf("duration and timeout must be positive.\n"); | ||
| 82 | + exit(1); | ||
| 83 | + return 1; | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + rtmp = srs_rtmp_create(rtmp_url); | ||
| 87 | + | ||
| 88 | + if (__srs_dns_resolve(rtmp) != 0) { | ||
| 89 | + printf("dns resolve failed.\n"); | ||
| 90 | + goto rtmp_destroy; | ||
| 91 | + } | ||
| 92 | + printf("dns resolve success\n"); | ||
| 93 | + time_dns_resolve = srs_get_time_ms(); | ||
| 94 | + | ||
| 95 | + if (__srs_connect_server(rtmp) != 0) { | ||
| 96 | + printf("socket connect failed.\n"); | ||
| 97 | + goto rtmp_destroy; | ||
| 98 | + } | ||
| 99 | + printf("socket connect success\n"); | ||
| 100 | + time_socket_connect = srs_get_time_ms(); | ||
| 59 | 101 | ||
| 60 | - if (srs_simple_handshake(rtmp) != 0) { | ||
| 61 | - printf("simple handshake failed.\n"); | 102 | + if (__srs_do_simple_handshake(rtmp) != 0) { |
| 103 | + printf("do simple handshake failed.\n"); | ||
| 62 | goto rtmp_destroy; | 104 | goto rtmp_destroy; |
| 63 | } | 105 | } |
| 64 | - printf("simple handshake success\n"); | 106 | + printf("do simple handshake success\n"); |
| 65 | 107 | ||
| 66 | if (srs_connect_app(rtmp) != 0) { | 108 | if (srs_connect_app(rtmp) != 0) { |
| 67 | printf("connect vhost/app failed.\n"); | 109 | printf("connect vhost/app failed.\n"); |
| @@ -74,6 +116,7 @@ int main(int argc, char** argv) | @@ -74,6 +116,7 @@ int main(int argc, char** argv) | ||
| 74 | goto rtmp_destroy; | 116 | goto rtmp_destroy; |
| 75 | } | 117 | } |
| 76 | printf("play stream success\n"); | 118 | printf("play stream success\n"); |
| 119 | + time_play_stream = srs_get_time_ms(); | ||
| 77 | 120 | ||
| 78 | for (;;) { | 121 | for (;;) { |
| 79 | if (srs_read_packet(rtmp, &type, ×tamp, &data, &size) != 0) { | 122 | if (srs_read_packet(rtmp, &type, ×tamp, &data, &size) != 0) { |
| @@ -81,11 +124,52 @@ int main(int argc, char** argv) | @@ -81,11 +124,52 @@ int main(int argc, char** argv) | ||
| 81 | } | 124 | } |
| 82 | printf("got packet: type=%s, time=%d, size=%d\n", srs_type2string(type), timestamp, size); | 125 | printf("got packet: type=%s, time=%d, size=%d\n", srs_type2string(type), timestamp, size); |
| 83 | 126 | ||
| 127 | + if (time_first_packet <= 0) { | ||
| 128 | + time_first_packet = srs_get_time_ms(); | ||
| 129 | + } | ||
| 130 | + | ||
| 84 | free(data); | 131 | free(data); |
| 132 | + | ||
| 133 | + if (srs_get_time_ms() - time_startup > timeout * 1000) { | ||
| 134 | + printf("timeout, terminate.\n"); | ||
| 135 | + goto rtmp_destroy; | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + if (timestamp > duration * 1000) { | ||
| 139 | + printf("duration exceed, terminate.\n"); | ||
| 140 | + goto rtmp_destroy; | ||
| 141 | + } | ||
| 85 | } | 142 | } |
| 86 | 143 | ||
| 87 | rtmp_destroy: | 144 | rtmp_destroy: |
| 88 | srs_rtmp_destroy(rtmp); | 145 | srs_rtmp_destroy(rtmp); |
| 146 | + time_cleanup = srs_get_time_ms(); | ||
| 147 | + | ||
| 148 | + // print result to stderr. | ||
| 149 | + fprintf(stderr, "{" | ||
| 150 | + "\"%s\":%d, " //#1 | ||
| 151 | + "\"%s\":%d, " // #2 | ||
| 152 | + "\"%s\":%d, " // #3 | ||
| 153 | + "\"%s\":%d, " // #4 | ||
| 154 | + "\"%s\":%d, " // #5 | ||
| 155 | + "\"%s\":%d, " // #6 | ||
| 156 | + "\"%s\":%d, " // #7 | ||
| 157 | + "%s}", | ||
| 158 | + // total = dns + tcp_connect + start_play + first_packet + last_packet | ||
| 159 | + "total", (int)(time_cleanup - time_startup), //#1 | ||
| 160 | + "dns", (int)(time_dns_resolve - time_startup), //#2 | ||
| 161 | + "tcp_connect", (int)(time_socket_connect - time_dns_resolve), //#3 | ||
| 162 | + "start_play", (int)(time_play_stream - time_socket_connect), //#4 | ||
| 163 | + "first_packet", (int)(time_first_packet - time_play_stream), //#5 | ||
| 164 | + "last_packet", (int)(time_cleanup - time_first_packet), //#6 | ||
| 165 | + // expect = time_cleanup - time_first_packet | ||
| 166 | + // actual = timestamp | ||
| 167 | + // delay = actual - expect | ||
| 168 | + "delay", (int)(timestamp - (time_cleanup - time_first_packet)), //#7 | ||
| 169 | + // unit in ms. | ||
| 170 | + "\"unit\": \"ms\"" | ||
| 171 | + ); | ||
| 172 | + printf("\n"); | ||
| 89 | 173 | ||
| 90 | return 0; | 174 | return 0; |
| 91 | } | 175 | } |
| @@ -55,7 +55,7 @@ int main(int argc, char** argv) | @@ -55,7 +55,7 @@ int main(int argc, char** argv) | ||
| 55 | printf("suck rtmp stream like rtmpdump\n"); | 55 | printf("suck rtmp stream like rtmpdump\n"); |
| 56 | printf("srs(simple-rtmp-server) client librtmp library.\n"); | 56 | printf("srs(simple-rtmp-server) client librtmp library.\n"); |
| 57 | printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); | 57 | printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); |
| 58 | - printf("rtmp url: %s\n", rtmp); | 58 | + printf("rtmp url: %s\n", argv[1]); |
| 59 | 59 | ||
| 60 | if (srs_simple_handshake(rtmp) != 0) { | 60 | if (srs_simple_handshake(rtmp) != 0) { |
| 61 | printf("simple handshake failed.\n"); | 61 | printf("simple handshake failed.\n"); |
| @@ -57,6 +57,7 @@ struct Context | @@ -57,6 +57,7 @@ struct Context | ||
| 57 | std::string url; | 57 | std::string url; |
| 58 | std::string tcUrl; | 58 | std::string tcUrl; |
| 59 | std::string host; | 59 | std::string host; |
| 60 | + std::string ip; | ||
| 60 | std::string port; | 61 | std::string port; |
| 61 | std::string vhost; | 62 | std::string vhost; |
| 62 | std::string app; | 63 | std::string app; |
| @@ -77,7 +78,7 @@ struct Context | @@ -77,7 +78,7 @@ struct Context | ||
| 77 | } | 78 | } |
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 80 | -int srs_librtmp_context_connect(Context* context) | 81 | +int srs_librtmp_context_parse_uri(Context* context) |
| 81 | { | 82 | { |
| 82 | int ret = ERROR_SUCCESS; | 83 | int ret = ERROR_SUCCESS; |
| 83 | 84 | ||
| @@ -123,6 +124,13 @@ int srs_librtmp_context_connect(Context* context) | @@ -123,6 +124,13 @@ int srs_librtmp_context_connect(Context* context) | ||
| 123 | } | 124 | } |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 127 | + return ret; | ||
| 128 | +} | ||
| 129 | + | ||
| 130 | +int srs_librtmp_context_resolve_host(Context* context) | ||
| 131 | +{ | ||
| 132 | + int ret = ERROR_SUCCESS; | ||
| 133 | + | ||
| 126 | // create socket | 134 | // create socket |
| 127 | srs_freep(context->skt); | 135 | srs_freep(context->skt); |
| 128 | context->skt = new SimpleSocketStream(); | 136 | context->skt = new SimpleSocketStream(); |
| @@ -132,11 +140,24 @@ int srs_librtmp_context_connect(Context* context) | @@ -132,11 +140,24 @@ int srs_librtmp_context_connect(Context* context) | ||
| 132 | } | 140 | } |
| 133 | 141 | ||
| 134 | // connect to server:port | 142 | // connect to server:port |
| 135 | - string server = srs_dns_resolve(context->host); | ||
| 136 | - if (server.empty()) { | 143 | + context->ip = srs_dns_resolve(context->host); |
| 144 | + if (context->ip.empty()) { | ||
| 137 | return -1; | 145 | return -1; |
| 138 | } | 146 | } |
| 139 | - if ((ret = context->skt->connect(server.c_str(), ::atoi(context->port.c_str()))) != ERROR_SUCCESS) { | 147 | + |
| 148 | + return ret; | ||
| 149 | +} | ||
| 150 | + | ||
| 151 | +int srs_librtmp_context_connect(Context* context) | ||
| 152 | +{ | ||
| 153 | + int ret = ERROR_SUCCESS; | ||
| 154 | + | ||
| 155 | + srs_assert(context->skt); | ||
| 156 | + | ||
| 157 | + std::string ip = context->ip; | ||
| 158 | + int port = ::atoi(context->port.c_str()); | ||
| 159 | + | ||
| 160 | + if ((ret = context->skt->connect(ip.c_str(), port)) != ERROR_SUCCESS) { | ||
| 140 | return ret; | 161 | return ret; |
| 141 | } | 162 | } |
| 142 | 163 | ||
| @@ -166,14 +187,63 @@ int srs_simple_handshake(srs_rtmp_t rtmp) | @@ -166,14 +187,63 @@ int srs_simple_handshake(srs_rtmp_t rtmp) | ||
| 166 | { | 187 | { |
| 167 | int ret = ERROR_SUCCESS; | 188 | int ret = ERROR_SUCCESS; |
| 168 | 189 | ||
| 190 | + if ((ret = __srs_dns_resolve(rtmp)) != ERROR_SUCCESS) { | ||
| 191 | + return ret; | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + if ((ret = __srs_connect_server(rtmp)) != ERROR_SUCCESS) { | ||
| 195 | + return ret; | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + if ((ret = __srs_do_simple_handshake(rtmp)) != ERROR_SUCCESS) { | ||
| 199 | + return ret; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + return ret; | ||
| 203 | +} | ||
| 204 | + | ||
| 205 | +int __srs_dns_resolve(srs_rtmp_t rtmp) | ||
| 206 | +{ | ||
| 207 | + int ret = ERROR_SUCCESS; | ||
| 208 | + | ||
| 209 | + srs_assert(rtmp != NULL); | ||
| 210 | + Context* context = (Context*)rtmp; | ||
| 211 | + | ||
| 212 | + // parse uri | ||
| 213 | + if ((ret = srs_librtmp_context_parse_uri(context)) != ERROR_SUCCESS) { | ||
| 214 | + return ret; | ||
| 215 | + } | ||
| 216 | + // resolve host | ||
| 217 | + if ((ret = srs_librtmp_context_resolve_host(context)) != ERROR_SUCCESS) { | ||
| 218 | + return ret; | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + return ret; | ||
| 222 | +} | ||
| 223 | + | ||
| 224 | +int __srs_connect_server(srs_rtmp_t rtmp) | ||
| 225 | +{ | ||
| 226 | + int ret = ERROR_SUCCESS; | ||
| 227 | + | ||
| 169 | srs_assert(rtmp != NULL); | 228 | srs_assert(rtmp != NULL); |
| 170 | Context* context = (Context*)rtmp; | 229 | Context* context = (Context*)rtmp; |
| 171 | 230 | ||
| 172 | - // parse uri, resolve host, connect to server:port | ||
| 173 | if ((ret = srs_librtmp_context_connect(context)) != ERROR_SUCCESS) { | 231 | if ((ret = srs_librtmp_context_connect(context)) != ERROR_SUCCESS) { |
| 174 | return ret; | 232 | return ret; |
| 175 | } | 233 | } |
| 176 | 234 | ||
| 235 | + return ret; | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | +int __srs_do_simple_handshake(srs_rtmp_t rtmp) | ||
| 239 | +{ | ||
| 240 | + int ret = ERROR_SUCCESS; | ||
| 241 | + | ||
| 242 | + srs_assert(rtmp != NULL); | ||
| 243 | + Context* context = (Context*)rtmp; | ||
| 244 | + | ||
| 245 | + srs_assert(context->skt != NULL); | ||
| 246 | + | ||
| 177 | // simple handshake | 247 | // simple handshake |
| 178 | srs_freep(context->rtmp); | 248 | srs_freep(context->rtmp); |
| 179 | context->rtmp = new SrsRtmpClient(context->skt); | 249 | context->rtmp = new SrsRtmpClient(context->skt); |
| @@ -55,7 +55,7 @@ srs_rtmp_t srs_rtmp_create(const char* url); | @@ -55,7 +55,7 @@ srs_rtmp_t srs_rtmp_create(const char* url); | ||
| 55 | void srs_rtmp_destroy(srs_rtmp_t rtmp); | 55 | void srs_rtmp_destroy(srs_rtmp_t rtmp); |
| 56 | 56 | ||
| 57 | /** | 57 | /** |
| 58 | -* handshake with server | 58 | +* connect and handshake with server |
| 59 | * category: publish/play | 59 | * category: publish/play |
| 60 | * previous: rtmp-create | 60 | * previous: rtmp-create |
| 61 | * next: connect-app | 61 | * next: connect-app |
| @@ -65,7 +65,20 @@ void srs_rtmp_destroy(srs_rtmp_t rtmp); | @@ -65,7 +65,20 @@ void srs_rtmp_destroy(srs_rtmp_t rtmp); | ||
| 65 | * simple handshake specifies in rtmp 1.0, | 65 | * simple handshake specifies in rtmp 1.0, |
| 66 | * not depends on ssl. | 66 | * not depends on ssl. |
| 67 | */ | 67 | */ |
| 68 | +/** | ||
| 69 | +* srs_simple_handshake equals to invoke: | ||
| 70 | +* __srs_dns_resolve() | ||
| 71 | +* __srs_connect_server() | ||
| 72 | +* __srs_do_simple_handshake() | ||
| 73 | +* user can use these functions if needed. | ||
| 74 | +*/ | ||
| 68 | int srs_simple_handshake(srs_rtmp_t rtmp); | 75 | int srs_simple_handshake(srs_rtmp_t rtmp); |
| 76 | +// parse uri, create socket, resolve host | ||
| 77 | +int __srs_dns_resolve(srs_rtmp_t rtmp); | ||
| 78 | +// connect socket to server | ||
| 79 | +int __srs_connect_server(srs_rtmp_t rtmp); | ||
| 80 | +// do simple handshake over socket. | ||
| 81 | +int __srs_do_simple_handshake(srs_rtmp_t rtmp); | ||
| 69 | 82 | ||
| 70 | /** | 83 | /** |
| 71 | * connect to rtmp vhost/app | 84 | * connect to rtmp vhost/app |
-
请 注册 或 登录 后发表评论