go语言对接TCP接口,通知服务器取流转发
前提:
给客户在做流媒体服务的时候,定了一个非常简陋的协议,如下:
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
图下次补上
浙公网安备 33010602011771号