前提:
給客戶在做流媒體服務的時候,定了一個非常簡陋的協議,如下:
0x01 1直播/2點播/3抓拍 0x01/0x02 開啟/關閉 0x01 線路字段長度 string 線路data 0x01 設備名稱字段長度 string 設備名稱data 0x01 流地址字段長度 string 流地址data
比較簡單的自定義協議
我寫了一個通知服務器拉流並發送給srs的程序,代碼如下:
package main import ( "bytes" "fmt" "net" "os" "strconv" ) type icmd struct { cmd1 int cmd2 int cmd3 int cmd4 byte cmd5 byte len_name int name string len_url int url string } func sender(conn net.Conn, words string) { conn.Write([]byte(words)) fmt.Println("send ed") } /*general a string to send*/ func genc(icmd *icmd, name string, url string) string { var buffer bytes.Buffer buffer.WriteString(string(icmd.cmd1)) buffer.WriteString(string(icmd.cmd2)) buffer.WriteString(string(icmd.cmd3)) buffer.WriteString(string(icmd.cmd4)) buffer.WriteString(string(icmd.cmd5)) buffer.WriteString(string(len([]rune(name)))) buffer.WriteString(string(name)) buffer.WriteString(string(len([]rune(url)))) buffer.WriteString(string(url)) return buffer.String() } func main() { // url := "rtsp://admin:admin@172.16.11.203:554/" // url := "rtsp://admin:admin@172.16.11.202:554/" // url := "rtsp://127.0.0.1:554/2.264" // url := "rtsp://127.0.0.1:8554/2.264" // url := "rtsp://172.16.11.12:554/user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?real_stream" openStream(40, "172.16.11.78:5566", "rtsp://127.0.0.1:554/2.264", "camnm") openStream(40, "172.16.11.78:5566", "rtsp://127.0.0.1:18554/2.264", "camno") var n byte fmt.Println("按任意鍵結束,釋放video的推流") fmt.Scanf("%s", n) fmt.Printf("%q\n", n) defer closeStream(40, "172.16.11.78:5566", "rtsp://127.0.0.1:554/2.264", "camnm") defer closeStream(40, "172.16.11.78:5566", "rtsp://127.0.0.1:18554/2.264", "camno") } func openStream(m int, server string, url string, camerName string) { for i := 0; i < m; i++ { // server := "172.16.11.81:5566" tcpAddr, err := net.ResolveTCPAddr("tcp4", server) if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) } conn, err := net.DialTCP("tcp", nil, tcpAddr) if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) } fmt.Println("connect success") opencmd := icmd{1, 1, 2, '2', '1', 3, "addd", 10, "ffff"} res := camerName + strconv.Itoa(i) cmd := genc(&opencmd, res, url) fmt.Printf("%q\n", cmd) sender(conn, cmd) buffer := make([]byte, 2048) n, _ := conn.Read(buffer) fmt.Println(string(buffer[:n])) } } func closeStream(m int, server string, url string, camerName string) { for i := 0; i < m; i++ { // server := "172.16.11.81:5566" tcpAddr, err := net.ResolveTCPAddr("tcp4", server) if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) } conn, err := net.DialTCP("tcp", nil, tcpAddr) if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) } fmt.Println("connect success") opencmd := icmd{1, 2, 2, '2', '1', 3, "addd", 10, "ffff"} res := camerName + strconv.Itoa(i) cmd := genc(&opencmd, res, url) fmt.Printf("%q\n", cmd) sender(conn, cmd) buffer := make([]byte, 2048) n, _ := conn.Read(buffer) fmt.Println(string(buffer[:n])) } }
說明,這個程序,沒有做過多的優化,只為了壓力測試的需要。
最后一次,是推了80路的1080P,機器還不賴,為了分流live555的壓力,部署了兩個live555的rtsp服務,每一路40路,live555都達峰值都到cpu占用100%了
說明:我此處測試的重點是,是看ffmpeg在取流推hls到srs這里,至於並發取hls流的,在之前的博客中已經測試過了
好了,現在去看看解碼出來的flv流
打開瀏覽器輸入地址 : http://bilibili.github.io/flv.js/demo/
輸入我們的播放流地址:xxxx
圖下次補上