package rtmp import ( "net" "time" "encoding/binary" ) // see adobe specs for RTMP func DoHandshake(conn net.Conn) (hs_success bool) { C0C1C2 := make([]byte, 1536*2 + 1) S0S1S2 := make([]byte, 1536*2 + 1) S0S1S2[0] = 3 binary.BigEndian.PutUint32(S0S1S2[1:1+4], uint32(time.Now().UnixMilli())) // force handshake to finish in under 15 seconds (aribtrary) or throw an error conn.SetDeadline(time.Now().Add(15 * time.Second)) if _, err := conn.Read(C0C1C2); err != nil || C0C1C2[0] != 3 { return } copy(C0C1C2[1:1536], S0S1S2[1+1536:]) binary.BigEndian.PutUint32(S0S1S2[1+1536+4:1+1536+8], uint32(time.Now().UnixMilli())) if _, err := conn.Write(S0S1S2); err != nil { // specs say only send S0S1 and wait for C2 before sending S2, obs doesn't care apparently return } if _, err := conn.Read(C0C1C2[1+1536:]); err != nil { return } hs_success = true conn.SetDeadline(time.Time{}) // remove deadline for next function return }