ref: 09b812b49d237cfdcd53273b33dea9ccc355fe9a
dir: /main.c/
#include <u.h> #include <libc.h> #include <thread.h> #include <bio.h> #include "ivf.h" #include "rtmp.h" #include "util.h" int mainstacksize = 65536; int debug = 0; static void usage(void) { fprint(2, "usage: %s [-a AUDIO] -v VIDEO [URL]\n", argv0); threadexitsall("usage"); } void threadmain(int argc, char **argv) { u64int ns, ons; Biobuf *a, *v; IVFrame f; IVF ivf; RTMP *r; a = nil; v = nil; ARGBEGIN{ case 'd': debug++; break; case 'a': if((a = Bopen(EARGF(usage()), OREAD)) == nil) sysfatal("%r"); break; case 'v': if((v = Bopen(EARGF(usage()), OREAD)) == nil) sysfatal("%r"); break; default: usage(); }ARGEND if(argc != 1) usage(); if(v == nil) sysfatal("no video specified"); if(ivfopen(v, &ivf) != 0) sysfatal("%r"); if(strcmp(ivf.type, "AVC1") != 0) sysfatal("not H.264"); srand(time(nil)); if((r = rtmpdial(argv[0])) == nil) sysfatal("%r"); ulong sid; fprint(2, "asking for a stream\n"); if(rtmpstream(r, &sid) == 0){ fprint(2, "stream: %lud\n", sid); if(rtmppublish(r, sid, PubLive, "???") == 0){ fprint(2, "stream published\n"); if(rtmpmeta(r, sid, VcodecH264, 1920, 1088, -1) == 0) fprint(2, "metadata sent\n"); else fprint(2, "metadata failed: %r\n"); }else fprint(2, "stream publish failed: %r\n"); }else{ fprint(2, "stream failed\n"); } ons = 0; memset(&f, 0, sizeof(f)); for(;;){ if(ivfread(v, &f) != 0) sysfatal("%r"); if(f.sz == 0) break; ns = ivfns(&ivf, f.ts); if(rtmpdata(r, sid, (ns - ons) / 1000000ULL, Tvideo, f.buf, f.sz) != 0) sysfatal("video: flvdata: %r"); ons = ns; } threadexitsall(nil); }