func main() { log.Println(os.Args) flag.Usage = func() { flag.PrintDefaults() } flag.Parse() if *showHelp { flag.PrintDefaults() os.Exit(0) } if *streamNameCode == "" { flag.PrintDefaults() log.Fatal("specify the stream name") } inputFs = getInputFs() l := rtmpLog.NewLogger("", "", nil, 60, 3600*24, true) rtmp.InitLogger(l) defer l.Close() createStreamChan = make(chan rtmp.OutboundStream) connHandler := &ConnHandler{} log.Println("Dialing") var err error obConn, err = rtmp.Dial(*url, connHandler, 100) if err != nil { log.Fatal("Dial error", err) } defer obConn.Close() log.Println("Connecting") err = obConn.Connect() if err != nil { log.Fatalf("Connect error: %s", err.Error()) } for { select { case stream := <-createStreamChan: stream.Attach(connHandler) err = stream.Publish(*streamNameCode, "live") if err != nil { log.Fatalf("Publish error: %s", err.Error()) } case <-time.After(5 * time.Second): log.Printf("Audio size: %d bytes; Vedio size: %d bytes; Current tag index: %d\n", audioDataSize, videoDataSize, input.curPos) } } }
func NewRtmpSink(url, name string) *RtmpSink { sink := &RtmpSink{ InputChan: make(chan interface{}), } go func() { var err error l := log.NewLogger("logs", "publisher", nil, 60, 3600*24, true) rtmp.InitLogger(l) handler := &RtmpSinkHandler{} handler.createStreamChan = make(chan rtmp.OutboundStream) handler.flvChan = sink.InputChan handler.obConn, err = rtmp.Dial(url, handler, 100) if err != nil { fmt.Println("Rtmp dial error", err) return } err = handler.obConn.Connect() if err != nil { fmt.Printf("Connect error: %s", err.Error()) return } for { select { case stream := <-handler.createStreamChan: // Publish stream.Attach(handler) err = stream.Publish(name, "live") if err != nil { fmt.Printf("Publish error: %s", err.Error()) return } case <-time.After(1 * time.Second): fmt.Printf("Audio size: %d bytes; Video size: %d bytes\n", handler.audioDataSize, handler.videoDataSize) } } }() return sink }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s version[%s]\r\nUsage: %s [OPTIONS]\r\n", programName, version, os.Args[0]) flag.PrintDefaults() } flag.Parse() l := log.NewLogger(".", "publisher", nil, 60, 3600*24, true) rtmp.InitLogger(l) defer l.Close() createStreamChan = make(chan rtmp.OutboundStream) testHandler := &TestOutboundConnHandler{} fmt.Println("to dial") var err error obConn, err = rtmp.Dial(*url, testHandler, 100) if err != nil { fmt.Println("Dial error", err) os.Exit(-1) } defer obConn.Close() fmt.Println("to connect") err = obConn.Connect() if err != nil { fmt.Printf("Connect error: %s", err.Error()) os.Exit(-1) } for { select { case stream := <-createStreamChan: // Publish stream.Attach(testHandler) err = stream.Publish(*streamName, "live") if err != nil { fmt.Printf("Publish error: %s", err.Error()) os.Exit(-1) } case <-time.After(1 * time.Second): fmt.Printf("Audio size: %d bytes; Vedio size: %d bytes\n", audioDataSize, videoDataSize) } } }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s version[%s]\r\nUsage: %s [OPTIONS]\r\n", programName, version, os.Args[0]) flag.PrintDefaults() } flag.Parse() l := log.NewLogger(".", "server", nil, 60, 3600*24, true) l.SetMainLevel(log.LOG_LEVEL_DEBUG) rtmp.InitLogger(l) defer l.Close() handler := &ServerHandler{} server, err := rtmp.NewServer("tcp", *address, handler) if err != nil { fmt.Println("NewServer error", err) os.Exit(-1) } defer server.Close() ch := make(chan os.Signal) signal.Notify(ch, syscall.SIGINT) sig := <-ch fmt.Printf("Signal received: %v\n", sig) }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s version[%s]\r\nUsage: %s [OPTIONS]\r\n", programName, version, os.Args[0]) flag.PrintDefaults() } flag.Parse() l := log.NewLogger(".", "proxy", nil, 60, 3600*24, true) rtmp.InitLogger(l) defer l.Close() // listen listen, err := net.Listen("tcp", ":1935") if err != nil { fmt.Println("Listen error", err) os.Exit(-1) } defer listen.Close() for { iconn, err := listen.Accept() if err != nil { fmt.Println("Accept error", err) os.Exit(-1) } if iconn == nil { fmt.Println("iconn is nil") os.Exit(-1) } defer iconn.Close() // Handshake // C>>>P: C0+C1 ibr := bufio.NewReader(iconn) ibw := bufio.NewWriter(iconn) c0, err := ibr.ReadByte() if c0 != 0x03 { fmt.Printf("C>>>P: C0(0x%2x) != 0x03\n", c0) os.Exit(-1) } c1 := make([]byte, rtmp.RTMP_SIG_SIZE) _, err = io.ReadAtLeast(ibr, c1, rtmp.RTMP_SIG_SIZE) // Check C1 var clientDigestOffset uint32 if clientDigestOffset, err = CheckC1(c1, true); err != nil { fmt.Println("C>>>P: Test C1 err:", err) os.Exit(-1) } // P>>>S: Connect Server oconn, err := net.Dial("tcp", "192.168.20.111:1935") if err != nil { fmt.Println("P>>>S: Dial server err:", err) os.Exit(-1) } defer oconn.Close() obr := bufio.NewReader(oconn) obw := bufio.NewWriter(oconn) // P>>>S: C0+C1 if err = obw.WriteByte(c0); err != nil { fmt.Println("P>>>S: Write C0 err:", err) os.Exit(-1) } if _, err = obw.Write(c1); err != nil { fmt.Println("P>>>S: Write C1 err:", err) os.Exit(-1) } if err = obw.Flush(); err != nil { fmt.Println("P>>>S: Flush err:", err) os.Exit(-1) } // P<<<S: Read S0+S1+S2 s0, err := obr.ReadByte() if err != nil { fmt.Println("P<<<S: Read S0 err:", err) os.Exit(-1) } if c0 != 0x03 { fmt.Printf("P<<<S: S0(0x%2x) != 0x03\n", s0) os.Exit(-1) } s1 := make([]byte, rtmp.RTMP_SIG_SIZE) _, err = io.ReadAtLeast(obr, s1, rtmp.RTMP_SIG_SIZE) if err != nil { fmt.Println("P<<<S: Read S1 err:", err) os.Exit(-1) } s2 := make([]byte, rtmp.RTMP_SIG_SIZE) _, err = io.ReadAtLeast(obr, s2, rtmp.RTMP_SIG_SIZE) if err != nil { fmt.Println("P<<<S: Read S2 err:", err) os.Exit(-1) } // C<<<P: Send S0+S1+S2 if err = ibw.WriteByte(s0); err != nil { fmt.Println("C<<<P: Write S0 err:", err) os.Exit(-1) } if _, err = ibw.Write(s1); err != nil { fmt.Println("C<<<P: Write S1 err:", err) os.Exit(-1) } if _, err = ibw.Write(s2); err != nil { fmt.Println("C<<<P: Write S2 err:", err) os.Exit(-1) } if err = ibw.Flush(); err != nil { fmt.Println("C<<<P: Flush err:", err) os.Exit(-1) } // C>>>P: Read C2 c2 := make([]byte, rtmp.RTMP_SIG_SIZE) _, err = io.ReadAtLeast(ibr, c2, rtmp.RTMP_SIG_SIZE) // Check S2 server_pos := rtmp.ValidateDigest(s1, 8, rtmp.GENUINE_FP_KEY[:30]) if server_pos == 0 { server_pos = rtmp.ValidateDigest(s1, 772, rtmp.GENUINE_FP_KEY[:30]) if server_pos == 0 { fmt.Println("P<<<S: S1 position check error") os.Exit(-1) } } digest, err := rtmp.HMACsha256(c1[clientDigestOffset:clientDigestOffset+rtmp.SHA256_DIGEST_LENGTH], rtmp.GENUINE_FMS_KEY) rtmp.CheckError(err, "Get digest from c1 error") signature, err := rtmp.HMACsha256(s2[:rtmp.RTMP_SIG_SIZE-rtmp.SHA256_DIGEST_LENGTH], digest) rtmp.CheckError(err, "Get signature from s2 error") if bytes.Compare(signature, s2[rtmp.RTMP_SIG_SIZE-rtmp.SHA256_DIGEST_LENGTH:]) != 0 { fmt.Println("Server signature mismatch") os.Exit(-1) } digestResp, err := rtmp.HMACsha256(s1[server_pos:server_pos+rtmp.SHA256_DIGEST_LENGTH], rtmp.GENUINE_FP_KEY) rtmp.CheckError(err, "Generate C2 HMACsha256 digestResp") signatureResp, err := rtmp.HMACsha256(c2[:rtmp.RTMP_SIG_SIZE-rtmp.SHA256_DIGEST_LENGTH], digestResp) if bytes.Compare(signatureResp, c2[rtmp.RTMP_SIG_SIZE-rtmp.SHA256_DIGEST_LENGTH:]) != 0 { fmt.Println("C2 mismatch") os.Exit(-1) } // P>>>S: Send C2 if _, err = obw.Write(c2); err != nil { fmt.Println("P>>>S: Write C2 err:", err) os.Exit(-1) } if err = obw.Flush(); err != nil { fmt.Println("P>>>S: Flush err:", err) os.Exit(-1) } // Proxy go io.Copy(iconn, oconn) go io.Copy(oconn, iconn) } }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s version[%s]\r\nUsage: %s [OPTIONS]\r\n", programName, version, os.Args[0]) flag.PrintDefaults() } flag.Parse() l := log.NewLogger(".", "player", nil, 60, 3600*24, true) rtmp.InitLogger(l) defer l.Close() // Create flv file if len(*dumpFlv) > 0 { var err error flvFile, err = flv.CreateFile(*dumpFlv) if err != nil { fmt.Println("Create FLV dump file error:", err) return } } defer func() { if flvFile != nil { flvFile.Close() } }() createStreamChan = make(chan rtmp.OutboundStream) testHandler := &TestOutboundConnHandler{} fmt.Println("to dial") var err error obConn, err = rtmp.Dial(*url, testHandler, 100) /* conn := TryHandshakeByVLC() obConn, err = rtmp.NewOutbounConn(conn, *url, testHandler, 100) */ if err != nil { fmt.Println("Dial error", err) os.Exit(-1) } defer obConn.Close() fmt.Printf("obConn: %+v\n", obConn) fmt.Printf("obConn.URL(): %s\n", obConn.URL()) fmt.Println("to connect") // err = obConn.Connect("33abf6e996f80e888b33ef0ea3a32bfd", "131228035", "161114738", "play", "", "", "1368083579") err = obConn.Connect() if err != nil { fmt.Printf("Connect error: %s", err.Error()) os.Exit(-1) } for { select { case stream := <-createStreamChan: // Play err = stream.Play(*streamName, nil, nil, nil) if err != nil { fmt.Printf("Play error: %s", err.Error()) os.Exit(-1) } // Set Buffer Length case <-time.After(1 * time.Second): fmt.Printf("Audio size: %d bytes; Vedio size: %d bytes\n", audioDataSize, videoDataSize) } } }
func InitTestLogger() { if logger == nil { l := log.NewLogger(".", "test", nil, 60, 3600*24, true) InitLogger(l) } }