diff --git a/trunk/research/librtmp/srs_ingest_rtmp.c b/trunk/research/librtmp/srs_ingest_rtmp.c index adf47f9d1..ddf0b6856 100644 --- a/trunk/research/librtmp/srs_ingest_rtmp.c +++ b/trunk/research/librtmp/srs_ingest_rtmp.c @@ -30,20 +30,154 @@ gcc srs_ingest_rtmp.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_ingest #include "../../objs/include/srs_librtmp.h" +#define trace(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n") +#define verbose(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n") +#if 1 +#undef verbose +#define verbose(msg, ...) (void)0 +#endif + +int connect_ic(srs_rtmp_t irtmp); +int connect_oc(srs_rtmp_t ortmp); +int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp); + int main(int argc, char** argv) { + int ret = 0; + // user option parse index. + int opt = 0; + // user options. + char* in_rtmp_url; char* out_rtmp_url; + // rtmp handler + srs_rtmp_t irtmp, ortmp; + if (argc <= 2) { printf("ingest RTMP and publish to RTMP server\n" - "Usage: %s \n" + "Usage: %s <-i in_rtmp_url> <-y out_rtmp_url>\n" " in_rtmp_url input rtmp url, ingest from this url.\n" - " out_rtmp_url output rtmp url, publish to this url.\n", + " out_rtmp_url output rtmp url, publish to this url.\n" + "For example:\n" + " %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo\n", argv[0]); - exit(1); + ret = 1; + exit(ret); + return ret; } - printf("ingest RTMP and publish to RTMP server like edge.\n"); - printf("srs(simple-rtmp-server) client librtmp library.\n"); - printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); + // parse options in FFMPEG format. + while ((opt = getopt(argc, argv, "i:y:")) != -1) { + switch (opt) { + case 'i': + in_rtmp_url = optarg; + break; + case 'y': + out_rtmp_url = optarg; + break; + default: + break; + } + } - return 0; + trace("ingest RTMP and publish to RTMP server like edge."); + trace("srs(simple-rtmp-server) client librtmp library."); + trace("version: %d.%d.%d", srs_version_major(), srs_version_minor(), srs_version_revision()); + trace("input: %s", in_rtmp_url); + trace("output: %s", out_rtmp_url); + + irtmp = srs_rtmp_create(in_rtmp_url); + ortmp = srs_rtmp_create(out_rtmp_url); + + ret = proxy(irtmp, ortmp); + trace("proxy completed"); + + srs_rtmp_destroy(irtmp); + srs_rtmp_destroy(ortmp); + + return ret; +} + +int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp) +{ + int ret = 0; + + // packet data + int type, size; + u_int32_t timestamp = 0; + char* data = NULL; + + if ((ret = connect_ic(irtmp)) != 0) { + return ret; + } + if ((ret = connect_oc(ortmp)) != 0) { + return ret; + } + + trace("start proxy RTMP stream"); + for (;;) { + if ((ret = srs_read_packet(irtmp, &type, ×tamp, &data, &size)) != 0) { + trace("irtmp get packet failed. ret=%d", ret); + return ret; + } + verbose("irtmp got packet: type=%s, time=%d, size=%d", + srs_type2string(type), timestamp, size); + + if ((ret = srs_write_packet(ortmp, type, timestamp, data, size)) != 0) { + trace("irtmp get packet failed. ret=%d", ret); + return ret; + } + verbose("ortmp sent packet: type=%s, time=%d, size=%d", + srs_type2string(type), timestamp, size); + } + + return ret; +} + +int connect_ic(srs_rtmp_t irtmp) +{ + int ret = 0; + + if ((ret = srs_simple_handshake(irtmp)) != 0) { + trace("irtmp simple handshake failed. ret=%d", ret); + return ret; + } + trace("irtmp simple handshake success"); + + if ((ret = srs_connect_app(irtmp)) != 0) { + trace("irtmp connect vhost/app failed. ret=%d", ret); + return ret; + } + trace("irtmp connect vhost/app success"); + + if ((ret = srs_play_stream(irtmp)) != 0) { + trace("irtmp play stream failed. ret=%d", ret); + return ret; + } + trace("irtmp play stream success"); + + return ret; +} + +int connect_oc(srs_rtmp_t ortmp) +{ + int ret = 0; + + if ((ret = srs_simple_handshake(ortmp)) != 0) { + trace("ortmp simple handshake failed. ret=%d", ret); + return ret; + } + trace("ortmp simple handshake success"); + + if ((ret = srs_connect_app(ortmp)) != 0) { + trace("ortmp connect vhost/app failed. ret=%d", ret); + return ret; + } + trace("ortmp connect vhost/app success"); + + if ((ret = srs_publish_stream(ortmp)) != 0) { + trace("ortmp publish stream failed. ret=%d", ret); + return ret; + } + trace("ortmp publish stream success"); + + return ret; }