winlin

ingest rtmp to rtmp by srs-librtmp

@@ -30,20 +30,154 @@ gcc srs_ingest_rtmp.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_ingest @@ -30,20 +30,154 @@ gcc srs_ingest_rtmp.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_ingest
30 30
31 #include "../../objs/include/srs_librtmp.h" 31 #include "../../objs/include/srs_librtmp.h"
32 32
  33 +#define trace(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n")
  34 +#define verbose(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n")
  35 +#if 1
  36 +#undef verbose
  37 +#define verbose(msg, ...) (void)0
  38 +#endif
  39 +
  40 +int connect_ic(srs_rtmp_t irtmp);
  41 +int connect_oc(srs_rtmp_t ortmp);
  42 +int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp);
  43 +
33 int main(int argc, char** argv) 44 int main(int argc, char** argv)
34 { 45 {
  46 + int ret = 0;
  47 + // user option parse index.
  48 + int opt = 0;
  49 + // user options.
  50 + char* in_rtmp_url; char* out_rtmp_url;
  51 + // rtmp handler
  52 + srs_rtmp_t irtmp, ortmp;
  53 +
35 if (argc <= 2) { 54 if (argc <= 2) {
36 printf("ingest RTMP and publish to RTMP server\n" 55 printf("ingest RTMP and publish to RTMP server\n"
37 - "Usage: %s <in_rtmp_url> <out_rtmp_url>\n" 56 + "Usage: %s <-i in_rtmp_url> <-y out_rtmp_url>\n"
38 " in_rtmp_url input rtmp url, ingest from this url.\n" 57 " in_rtmp_url input rtmp url, ingest from this url.\n"
39 - " out_rtmp_url output rtmp url, publish to this url.\n", 58 + " out_rtmp_url output rtmp url, publish to this url.\n"
  59 + "For example:\n"
  60 + " %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo\n",
40 argv[0]); 61 argv[0]);
41 - exit(1); 62 + ret = 1;
  63 + exit(ret);
  64 + return ret;
  65 + }
  66 +
  67 + // parse options in FFMPEG format.
  68 + while ((opt = getopt(argc, argv, "i:y:")) != -1) {
  69 + switch (opt) {
  70 + case 'i':
  71 + in_rtmp_url = optarg;
  72 + break;
  73 + case 'y':
  74 + out_rtmp_url = optarg;
  75 + break;
  76 + default:
  77 + break;
  78 + }
  79 + }
  80 +
  81 + trace("ingest RTMP and publish to RTMP server like edge.");
  82 + trace("srs(simple-rtmp-server) client librtmp library.");
  83 + trace("version: %d.%d.%d", srs_version_major(), srs_version_minor(), srs_version_revision());
  84 + trace("input: %s", in_rtmp_url);
  85 + trace("output: %s", out_rtmp_url);
  86 +
  87 + irtmp = srs_rtmp_create(in_rtmp_url);
  88 + ortmp = srs_rtmp_create(out_rtmp_url);
  89 +
  90 + ret = proxy(irtmp, ortmp);
  91 + trace("proxy completed");
  92 +
  93 + srs_rtmp_destroy(irtmp);
  94 + srs_rtmp_destroy(ortmp);
  95 +
  96 + return ret;
  97 +}
  98 +
  99 +int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp)
  100 +{
  101 + int ret = 0;
  102 +
  103 + // packet data
  104 + int type, size;
  105 + u_int32_t timestamp = 0;
  106 + char* data = NULL;
  107 +
  108 + if ((ret = connect_ic(irtmp)) != 0) {
  109 + return ret;
  110 + }
  111 + if ((ret = connect_oc(ortmp)) != 0) {
  112 + return ret;
  113 + }
  114 +
  115 + trace("start proxy RTMP stream");
  116 + for (;;) {
  117 + if ((ret = srs_read_packet(irtmp, &type, &timestamp, &data, &size)) != 0) {
  118 + trace("irtmp get packet failed. ret=%d", ret);
  119 + return ret;
  120 + }
  121 + verbose("irtmp got packet: type=%s, time=%d, size=%d",
  122 + srs_type2string(type), timestamp, size);
  123 +
  124 + if ((ret = srs_write_packet(ortmp, type, timestamp, data, size)) != 0) {
  125 + trace("irtmp get packet failed. ret=%d", ret);
  126 + return ret;
  127 + }
  128 + verbose("ortmp sent packet: type=%s, time=%d, size=%d",
  129 + srs_type2string(type), timestamp, size);
42 } 130 }
43 131
44 - printf("ingest RTMP and publish to RTMP server like edge.\n");  
45 - printf("srs(simple-rtmp-server) client librtmp library.\n");  
46 - printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); 132 + return ret;
  133 +}
  134 +
  135 +int connect_ic(srs_rtmp_t irtmp)
  136 +{
  137 + int ret = 0;
  138 +
  139 + if ((ret = srs_simple_handshake(irtmp)) != 0) {
  140 + trace("irtmp simple handshake failed. ret=%d", ret);
  141 + return ret;
  142 + }
  143 + trace("irtmp simple handshake success");
  144 +
  145 + if ((ret = srs_connect_app(irtmp)) != 0) {
  146 + trace("irtmp connect vhost/app failed. ret=%d", ret);
  147 + return ret;
  148 + }
  149 + trace("irtmp connect vhost/app success");
  150 +
  151 + if ((ret = srs_play_stream(irtmp)) != 0) {
  152 + trace("irtmp play stream failed. ret=%d", ret);
  153 + return ret;
  154 + }
  155 + trace("irtmp play stream success");
  156 +
  157 + return ret;
  158 +}
  159 +
  160 +int connect_oc(srs_rtmp_t ortmp)
  161 +{
  162 + int ret = 0;
  163 +
  164 + if ((ret = srs_simple_handshake(ortmp)) != 0) {
  165 + trace("ortmp simple handshake failed. ret=%d", ret);
  166 + return ret;
  167 + }
  168 + trace("ortmp simple handshake success");
  169 +
  170 + if ((ret = srs_connect_app(ortmp)) != 0) {
  171 + trace("ortmp connect vhost/app failed. ret=%d", ret);
  172 + return ret;
  173 + }
  174 + trace("ortmp connect vhost/app success");
  175 +
  176 + if ((ret = srs_publish_stream(ortmp)) != 0) {
  177 + trace("ortmp publish stream failed. ret=%d", ret);
  178 + return ret;
  179 + }
  180 + trace("ortmp publish stream success");
47 181
48 - return 0; 182 + return ret;
49 } 183 }