golang实现纯Go语言RTSP服务器与客户端开发插件库gortsplib的使用

golang实现纯Go语言RTSP服务器与客户端开发插件库gortsplib的使用

gortsplib是一个用于Go编程语言的RTSP客户端和服务器库,最初是为MediaMTX项目开发的。该库需要Go ≥ 1.23版本。

主要特性

客户端功能

  • 支持安全协议变体(RTSPS、TLS、SRTP、MIKEY)
  • 查询服务器可用的媒体流
  • 从服务器读取媒体流(“播放”)
    • 支持UDP、UDP多播或TCP传输协议
    • 自动切换传输协议
    • 读取选定的媒体流
    • 暂停或搜索而不断开与服务器的连接
    • 写入ONVIF反向通道
    • 获取传入数据包的PTS(呈现时间戳)
    • 获取传入数据包的NTP(绝对时间戳)
  • 向服务器写入媒体流(“录制”)
    • 支持UDP或TCP传输协议
    • 自动切换传输协议
    • 暂停而不断开与服务器的连接

服务器功能

  • 支持安全协议变体(RTSPS、TLS、SRTP、MIKEY)
  • 处理客户端请求
  • 验证客户端凭据
  • 从客户端读取媒体流(“录制”)
    • 支持UDP或TCP传输协议
    • 获取传入数据包的PTS(呈现时间戳)
    • 获取传入数据包的NTP(绝对时间戳)
  • 向客户端提供媒体流(“播放”)
    • 支持UDP、UDP多播或TCP传输协议
    • 计算并提供SSRC、RTP-Info给客户端
    • 读取ONVIF反向通道

实用工具

  • 解析RTSP元素
  • 将RTP数据包编码/解码为特定编解码器的帧

示例代码

基本RTSP服务器示例

package main

import (
	"log"
	"time"

	"github.com/bluenviron/gortsplib/v4"
	"github.com/bluenviron/gortsplib/v4/pkg/base"
	"github.com/bluenviron/gortsplib/v4/pkg/description"
	"github.com/bluenviron/gortsplib/v4/pkg/format"
	"github.com/bluenviron/gortsplib/v4/pkg/headers"
	"github.com/pion/rtp"
)

// 这是一个RTSP服务器示例,它接收H264视频流
type server struct{}

func (s *server) OnDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx) (*base.Response, *gortsplib.ServerStream, error) {
	// 创建流描述
	h264Format := &format.H264{
		PayloadTyp:        96,
		SPS:              []byte{0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02, 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9, 0x20},
		PPS:              []byte{0x68, 0xce, 0x38, 0x80},
		PacketizationMode: 1,
	}
	
	desc := &description.Session{
		Medias: []*description.Media{
			{
				Type:    description.MediaTypeVideo,
				Formats: []format.Format{h264Format},
			},
		},
	}
	
	// 创建流
	stream := gortsplib.NewServerStream(desc)
	return &base.Response{
		StatusCode: base.StatusOK,
	}, stream, nil
}

func (s *server) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response, *gortsplib.ServerStream, error) {
	// 这里可以添加验证逻辑
	return &base.Response{
		StatusCode: base.StatusOK,
	}, ctx.Stream, nil
}

func (s *server) OnPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base.Response, error) {
	// 这里可以添加播放控制逻辑
	return &base.Response{
		StatusCode: base.StatusOK,
	}, nil
}

func main() {
	// 创建服务器
	s := &gortsplib.Server{
		Handler:     &server{},
		RTSPAddress: ":8554",
	}

	// 启动服务器
	err := s.Start()
	if err != nil {
		panic(err)
	}
	defer s.Close()

	log.Println("Server is running")
	
	// 等待退出
	select {}
}

基本RTSP客户端示例

package main

import (
	"log"
	"time"

	"github.com/bluenviron/gortsplib/v4"
	"github.com/bluenviron/gortsplib/v4/pkg/base"
	"github.com/bluenviron/gortsplib/v4/pkg/description"
	"github.com/bluenviron/gortsplib/v4/pkg/format"
	"github.com/bluenviron/gortsplib/v4/pkg/url"
)

// 这是一个RTSP客户端示例,它连接到RTSP服务器并播放视频流
func main() {
	// 解析URL
	url, err := url.Parse("rtsp://localhost:8554/mystream")
	if err != nil {
		panic(err)
	}

	// 创建客户端
	c := gortsplib.Client{}

	// 连接到服务器
	err = c.Start(url.Scheme, url.Host)
	if err != nil {
		panic(err)
	}
	defer c.Close()

	// 查找可用媒体流
	desc, _, err := c.Describe(url)
	if err != nil {
		panic(err)
	}

	// 找到H264视频流
	var h264Format *format.H264
	media := desc.FindFormat(&h264Format)
	if media == nil {
		panic("media not found")
	}

	// 设置传输协议
	_, err = c.Setup(desc.BaseURL, media, base.TransportTCP)
	if err != nil {
		panic(err)
	}

	// 设置回调函数处理收到的RTP包
	h264Format.OnPacketRTP = func(pkt *rtp.Packet) {
		log.Printf("received H264 packet with payload size %d\n", len(pkt.Payload))
	}

	// 开始播放
	_, err = c.Play(nil)
	if err != nil {
		panic(err)
	}

	// 等待一段时间
	time.Sleep(30 * time.Second)
}

支持的RTP有效载荷格式

视频格式

格式 编码器和解码器是否可用
AV1 ✔️
VP9 ✔️
VP8 ✔️
H265 ✔️
H264 ✔️
MPEG-4 Video (H263) ✔️
MPEG-1/2 Video ✔️
M-JPEG ✔️

音频格式

格式 编码器和解码器是否可用
Opus ✔️
Vorbis ✖️
MPEG-4 Audio (AAC) ✔️
MPEG-4 Audio LATM ✔️
MPEG-1/2 Audio (MP3) ✔️
AC-3 ✔️
Speex ✖️
G726 ✖️
G722 ✔️
G711 (PCMA, PCMU) ✔️
LPCM ✔️

其他格式

格式 编码器和解码器是否可用
MPEG-TS ✖️
KLV ✔️

更多关于golang实现纯Go语言RTSP服务器与客户端开发插件库gortsplib的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现纯Go语言RTSP服务器与客户端开发插件库gortsplib的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用gortsplib实现Go语言RTSP服务器与客户端

gortsplib是一个纯Go语言实现的RTSP协议库,可以用于开发RTSP服务器和客户端。下面我将介绍如何使用这个库来实现基本的RTSP功能。

安装gortsplib

首先安装gortsplib库:

go get github.com/aler9/gortsplib/v2

RTSP服务器实现

下面是一个简单的RTSP服务器实现示例:

package main

import (
	"log"
	"time"

	"github.com/aler9/gortsplib/v2"
	"github.com/aler9/gortsplib/v2/pkg/base"
	"github.com/aler9/gortsplib/v2/pkg/format"
	"github.com/aler9/gortsplib/v2/pkg/media"
	"github.com/pion/rtp"
)

type customMedia struct {
	medias []*media.Media
}

func (m *customMedia) Medias() []*media.Media {
	return m.medias
}

func (m *customMedia) OnSetup(*gortsplib.ServerHandlerOnSetupCtx) (*base.Response, error) {
	return &base.Response{
		StatusCode: base.StatusOK,
	}, nil
}

func (m *customMedia) OnPlay(*gortsplib.ServerHandlerOnPlayCtx) (*base.Response, error) {
	return &base.Response{
		StatusCode: base.StatusOK,
	}, nil
}

func main() {
	// 创建H264视频格式
	h264Format := &format.H264{
		PayloadTyp:        96,
		SPS:               []byte{0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02, 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9, 0x20},
		PPS:               []byte{0x68, 0xce, 0x38, 0x80},
		PacketizationMode: 1,
	}
	
	// 创建媒体流
	medi := &media.Media{
		Type:    media.TypeVideo,
		Formats: []format.Format{h264Format},
	}
	
	// 创建服务器
	s := &gortsplib.Server{
		Handler: &customMedia{
			medias: []*media.Media{medi},
		},
		RTSPAddress: ":8554",
	}
	
	// 启动服务器
	log.Println("RTSP server is running on rtsp://localhost:8554")
	err := s.Start()
	if err != nil {
		panic(err)
	}
	defer s.Close()

	// 模拟发送RTP包
	track := &gortsplib.TrackH264{
		PayloadType: 96,
		SPS:         h264Format.SPS,
		PPS:         h264Format.PPS,
	}
	
	// 创建会话
	session := gortsplib.NewServerSession(s, &gortsplib.Track{Media: medi})
	
	// 定期发送RTP包
	ticker := time.NewTicker(time.Millisecond * 33)
	defer ticker.Stop()
	
	for range ticker.C {
		pkt := &rtp.Packet{
			Header: rtp.Header{
				Version:        2,
				PayloadType:    96,
				SequenceNumber: 12345,
				Timestamp:      54321,
				SSRC:           uint32(time.Now().UnixNano()),
			},
			Payload: []byte{0x05, 0x00, 0x00, 0x00}, // 模拟H264 NALU
		}
		
		err := session.WritePacketRTP(medi, pkt)
		if err != nil {
			log.Println("write packet error:", err)
			break
		}
	}
}

RTSP客户端实现

下面是一个简单的RTSP客户端实现示例:

package main

import (
	"log"
	"time"

	"github.com/aler9/gortsplib/v2"
	"github.com/aler9/gortsplib/v2/pkg/base"
	"github.com/aler9/gortsplib/v2/pkg/format"
	"github.com/pion/rtp"
)

type clientHandler struct {
	client *gortsplib.Client
}

func (h *clientHandler) OnPacketRTP(medi *media.Media, forma format.Format, pkt *rtp.Packet) {
	log.Printf("RTP packet: media=%v format=%v packet=%v\n", medi, forma, pkt)
}

func main() {
	// RTSP服务器地址
	address := "rtsp://localhost:8554"

	// 创建客户端
	client := &gortsplib.Client{
		OnPacketRTP: (&clientHandler{}).OnPacketRTP,
	}

	// 连接到服务器
	u, err := base.ParseURL(address)
	if err != nil {
		panic(err)
	}

	err = client.Start(u.Scheme, u.Host)
	if err != nil {
		panic(err)
	}
	defer client.Close()

	// 获取可用的媒体描述
	desc, _, err := client.Describe(u)
	if err != nil {
		panic(err)
	}

	// 设置媒体格式
	err = client.SetupAll(desc.BaseURL, desc.Medias)
	if err != nil {
		panic(err)
	}

	// 开始播放
	_, err = client.Play(nil)
	if err != nil {
		panic(err)
	}

	log.Println("Client is receiving RTP packets...")

	// 保持运行
	time.Sleep(time.Minute)
}

高级功能

1. 认证支持

服务器端可以添加认证:

s := &gortsplib.Server{
	Handler: &customMedia{
		medias: []*media.Media{medi},
	},
	RTSPAddress: ":8554",
	AuthMethods: []base.AuthMethod{base.AuthBasic},
	AuthUser:    "admin",
	AuthPass:    "password",
}

客户端连接时需要提供认证信息:

client := &gortsplib.Client{
	OnPacketRTP: (&clientHandler{}).OnPacketRTP,
	AnyAuth: &base.Auth{
		Method: base.AuthBasic,
		User:   "admin",
		Pass:   "password",
	},
}

2. 支持TCP传输

默认情况下,gortsplib使用UDP传输RTP数据。如果需要使用TCP:

client := &gortsplib.Client{
	Transport: gortsplib.TransportTCP,
	OnPacketRTP: (&clientHandler{}).OnPacketRTP,
}

3. 录制RTSP流

可以将接收到的RTP包保存到文件:

type recorderHandler struct {
	file *os.File
}

func (h *recorderHandler) OnPacketRTP(medi *media.Media, forma format.Format, pkt *rtp.Packet) {
	// 写入RTP包头
	h.file.Write(pkt.Header.Marshal())
	// 写入RTP负载
	h.file.Write(pkt.Payload)
}

func main() {
	// 创建文件
	file, err := os.Create("stream.rtp")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	// 创建客户端
	client := &gortsplib.Client{
		OnPacketRTP: (&recorderHandler{file: file}).OnPacketRTP,
	}
	
	// ...其余客户端代码...
}

总结

gortsplib是一个功能强大且易于使用的RTSP库,完全用Go语言实现。通过上面的示例,你可以快速实现RTSP服务器和客户端的基本功能。该库支持:

  1. RTSP协议的核心功能(DESCRIBE, SETUP, PLAY, TEARDOWN等)
  2. 多种传输协议(UDP, TCP)
  3. 多种媒体格式(H264, H265, MPEG-4, AAC等)
  4. 认证支持

对于更复杂的需求,你可以参考gortsplib的官方文档和示例代码进行扩展。

回到顶部