mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-06 00:37:00 +08:00
Fix RTMP to WebRTC
This commit is contained in:
60
pkg/h264/avc.go
Normal file
60
pkg/h264/avc.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package h264
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
||||||
|
"github.com/pion/rtp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const PayloadTypeAVC = 255
|
||||||
|
|
||||||
|
func IsAVC(codec *streamer.Codec) bool {
|
||||||
|
return codec.PayloadType == PayloadTypeAVC
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeAVC(raw []byte) (avc []byte) {
|
||||||
|
avc = make([]byte, len(raw)+4)
|
||||||
|
binary.BigEndian.PutUint32(avc, uint32(len(raw)))
|
||||||
|
copy(avc[4:], raw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func RepairAVC(track *streamer.Track) streamer.WrapperFunc {
|
||||||
|
sps, pps := GetParameterSet(track.Codec.FmtpLine)
|
||||||
|
sps = EncodeAVC(sps)
|
||||||
|
pps = EncodeAVC(pps)
|
||||||
|
|
||||||
|
return func(push streamer.WriterFunc) streamer.WriterFunc {
|
||||||
|
return func(packet *rtp.Packet) (err error) {
|
||||||
|
naluType := NALUType(packet.Payload)
|
||||||
|
switch naluType {
|
||||||
|
case NALUTypeSPS:
|
||||||
|
sps = packet.Payload
|
||||||
|
return
|
||||||
|
case NALUTypePPS:
|
||||||
|
pps = packet.Payload
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var clone rtp.Packet
|
||||||
|
|
||||||
|
if naluType == NALUTypeIFrame {
|
||||||
|
clone = *packet
|
||||||
|
clone.Payload = sps
|
||||||
|
if err = push(&clone); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
clone = *packet
|
||||||
|
clone.Payload = pps
|
||||||
|
if err = push(&clone); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clone = *packet
|
||||||
|
clone.Payload = packet.Payload
|
||||||
|
return push(&clone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,6 @@ package h264
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/binary"
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -12,25 +11,12 @@ const (
|
|||||||
NALUTypeIFrame = 5
|
NALUTypeIFrame = 5
|
||||||
NALUTypeSPS = 7
|
NALUTypeSPS = 7
|
||||||
NALUTypePPS = 8
|
NALUTypePPS = 8
|
||||||
|
|
||||||
PayloadTypeAVC = 255
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NALUType(b []byte) byte {
|
func NALUType(b []byte) byte {
|
||||||
return b[4] & 0x1F
|
return b[4] & 0x1F
|
||||||
}
|
}
|
||||||
|
|
||||||
func EncodeAVC(raw []byte) (avc []byte) {
|
|
||||||
avc = make([]byte, len(raw)+4)
|
|
||||||
binary.BigEndian.PutUint32(avc, uint32(len(raw)))
|
|
||||||
copy(avc[4:], raw)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsAVC(codec *streamer.Codec) bool {
|
|
||||||
return codec.PayloadType == PayloadTypeAVC
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetParameterSet(fmtp string) (sps, pps []byte) {
|
func GetParameterSet(fmtp string) (sps, pps []byte) {
|
||||||
if fmtp == "" {
|
if fmtp == "" {
|
||||||
return
|
return
|
||||||
|
@@ -55,10 +55,12 @@ func (c *Conn) AddTrack(media *streamer.Media, track *streamer.Track) *streamer.
|
|||||||
wrapper := h264.RTPPay(1200)
|
wrapper := h264.RTPPay(1200)
|
||||||
push = wrapper(push)
|
push = wrapper(push)
|
||||||
|
|
||||||
if !h264.IsAVC(codec) {
|
if h264.IsAVC(codec) {
|
||||||
|
wrapper = h264.RepairAVC(track)
|
||||||
|
} else {
|
||||||
wrapper = h264.RTPDepay(track)
|
wrapper = h264.RTPDepay(track)
|
||||||
push = wrapper(push)
|
|
||||||
}
|
}
|
||||||
|
push = wrapper(push)
|
||||||
}
|
}
|
||||||
|
|
||||||
track = track.Bind(push)
|
track = track.Bind(push)
|
||||||
|
Reference in New Issue
Block a user