mirror of
https://github.com/aler9/rtsp-simple-server
synced 2025-09-27 03:56:15 +08:00
90 lines
1.9 KiB
Go
90 lines
1.9 KiB
Go
// Package rtsp provides RTSP utilities.
|
|
package rtsp
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/bluenviron/gortsplib/v4"
|
|
"github.com/bluenviron/gortsplib/v4/pkg/description"
|
|
"github.com/bluenviron/gortsplib/v4/pkg/format"
|
|
"github.com/bluenviron/mediamtx/internal/conf"
|
|
"github.com/bluenviron/mediamtx/internal/logger"
|
|
"github.com/bluenviron/mediamtx/internal/stream"
|
|
"github.com/pion/rtp"
|
|
)
|
|
|
|
type ntpState int
|
|
|
|
const (
|
|
ntpStateInitial ntpState = iota
|
|
ntpStateReplace
|
|
ntpStateAvailable
|
|
)
|
|
|
|
type rtspSource interface {
|
|
PacketPTS2(*description.Media, *rtp.Packet) (int64, bool)
|
|
PacketNTP(*description.Media, *rtp.Packet) (time.Time, bool)
|
|
OnPacketRTP(*description.Media, format.Format, gortsplib.OnPacketRTPFunc)
|
|
}
|
|
|
|
// ToStream maps a RTSP stream to a MediaMTX stream.
|
|
func ToStream(
|
|
source rtspSource,
|
|
medias []*description.Media,
|
|
pathConf *conf.Path,
|
|
stream *stream.Stream,
|
|
log logger.Writer,
|
|
) {
|
|
for _, medi := range medias {
|
|
for _, forma := range medi.Formats {
|
|
cmedi := medi
|
|
cforma := forma
|
|
|
|
var ntpStat ntpState
|
|
|
|
if !pathConf.RTSPAbsoluteTimestamp {
|
|
ntpStat = ntpStateReplace
|
|
}
|
|
|
|
handleNTP := func(pkt *rtp.Packet) (time.Time, bool) {
|
|
switch ntpStat {
|
|
case ntpStateReplace:
|
|
return time.Now(), true
|
|
|
|
case ntpStateInitial:
|
|
ntp, avail := source.PacketNTP(cmedi, pkt)
|
|
if !avail {
|
|
log.Log(logger.Warn, "received RTP packet without absolute time, skipping it")
|
|
return time.Time{}, false
|
|
}
|
|
|
|
ntpStat = ntpStateAvailable
|
|
return ntp, true
|
|
|
|
default: // ntpStateAvailable
|
|
ntp, avail := source.PacketNTP(cmedi, pkt)
|
|
if !avail {
|
|
panic("should not happen")
|
|
}
|
|
|
|
return ntp, true
|
|
}
|
|
}
|
|
|
|
source.OnPacketRTP(cmedi, cforma, func(pkt *rtp.Packet) {
|
|
pts, ok := source.PacketPTS2(cmedi, pkt)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
ntp, ok := handleNTP(pkt)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
stream.WriteRTPPacket(cmedi, cforma, pkt, ntp, pts)
|
|
})
|
|
}
|
|
}
|
|
}
|