Created
March 4, 2024 14:41
-
-
Save 0x5e/dfb03f2ae7335bf03bb4b9cf59971597 to your computer and use it in GitHub Desktop.
bambu-go2rtc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// golang version of https://github.com/synman/bambu-go2rtc | |
// usage: ./camera-stream <accessCode> <hostname> | |
// with ffplay: ./camera-stream <accessCode> <hostname> | ffplay -hide_banner -fflags nobuffer -analyzeduration 10 -probesize 32 -i - | |
// tested on bambu lab a1 mini, the fps is really low for this device :( | |
package main | |
import ( | |
"bytes" | |
"crypto/tls" | |
"encoding/binary" | |
"fmt" | |
"io" | |
"net" | |
"os" | |
) | |
const username = "bblp" | |
const port = 6000 | |
func main() { | |
if len(os.Args) != 3 { | |
fmt.Println("Usage: <executable> <accessCode> <hostname>") | |
os.Exit(1) | |
} | |
accessCode := os.Args[1] | |
hostname := os.Args[2] | |
authData := []byte{ | |
0x40, 0x00, 0x00, 0x00, // '@'\0\0\0 | |
0x00, 0x30, 0x00, 0x00, // \0'0'\0\0 | |
0x00, 0x00, 0x00, 0x00, // \0\0\0\0 | |
0x00, 0x00, 0x00, 0x00, // \0\0\0\0 | |
} | |
authData = append(authData, []byte(username)...) | |
authData = append(authData, make([]byte, 32-len(username))...) | |
authData = append(authData, []byte(accessCode)...) | |
authData = append(authData, make([]byte, 32-len(accessCode))...) | |
// fmt.Fprintf(os.Stderr, "authData: %q\n", authData) | |
connect(hostname, port, authData) | |
} | |
func connect(hostname string, port int, authData []byte) error { | |
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", hostname, port)) | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "Connection attempt failed: %s\n", err) | |
return err | |
} | |
defer conn.Close() | |
tlsConn := tls.Client(conn, &tls.Config{ | |
InsecureSkipVerify: true, | |
}) | |
err = tlsConn.Handshake() | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "TLS handshake failed: %s\n", err) | |
return err | |
} | |
defer tlsConn.Close() | |
_, err = tlsConn.Write(authData) | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "Write to socket failed: %s\n", err) | |
return err | |
} | |
for true { | |
header := make([]byte, 16) | |
_, err = io.ReadFull(tlsConn, header) | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "Read error: %s\n", err) | |
return err | |
} | |
length := binary.LittleEndian.Uint32(header[0:4]) | |
// fmt.Fprintf(os.Stderr, "packet header: %v\n", header) | |
if !bytes.Equal(header[4:], []byte{ | |
0x00, 0x00, 0x00, 0x00, | |
0x01, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, | |
}) { | |
// skip invalid packet | |
continue | |
} | |
img := make([]byte, length) | |
_, err = io.ReadFull(tlsConn, img) | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "Read error: %s\n", err) | |
return err | |
} | |
if bytes.Equal([]byte{0xff, 0xd8, 0xff, 0xe0}, img[0:4]) && | |
bytes.Equal([]byte{0xff, 0xd9}, img[length-2:]) { | |
// fmt.Fprintf(os.Stderr, "Img size: %d\n", len(img)) | |
os.Stdout.Write(img) | |
} | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment