forked from Monibuca/plugin-gb28181
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpublisher.go
83 lines (80 loc) · 2.01 KB
/
publisher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package gb28181
import (
"github.com/Monibuca/engine/v3"
"github.com/Monibuca/plugin-gb28181/v3/utils"
. "github.com/Monibuca/utils/v3"
"github.com/pion/rtp"
)
type Publisher struct {
*engine.Stream
parser utils.DecPSPackage
pushVideo func(uint32, uint32, []byte)
pushAudio func(uint32, []byte)
lastSeq uint16
}
func (p *Publisher) PushVideo(ts uint32, cts uint32, payload []byte) {
p.pushVideo(ts, cts, payload)
}
func (p *Publisher) PushAudio(ts uint32, payload []byte) {
p.pushAudio(ts, payload)
}
func (p *Publisher) Publish() (result bool) {
if result = p.Stream.Publish(); result {
p.pushVideo = func(ts uint32, cts uint32, payload []byte) {
var vt *engine.VideoTrack
switch p.parser.VideoStreamType {
case utils.StreamTypeH264:
vt = p.Stream.NewVideoTrack(7)
case utils.StreamTypeH265:
vt = p.Stream.NewVideoTrack(12)
default:
return
}
vt.PushAnnexB(ts, cts, payload)
p.pushVideo = vt.PushAnnexB
}
p.pushAudio = func(ts uint32, payload []byte) {
switch p.parser.AudioStreamType {
case utils.G711A:
at := p.Stream.NewAudioTrack(7)
at.SoundRate = 8000
at.SoundSize = 16
at.Channels = 1
at.ExtraData = []byte{(at.CodecID << 4) | (1 << 1)}
at.PushRaw(ts, payload)
p.pushAudio = at.PushRaw
// case utils.G711U:
// at := p.Stream.NewAudioTrack(8)
// at.SoundRate = 8000
// at.SoundSize = 16
// asc := at.CodecID << 4
// asc = asc + 1<<1
// at.ExtraData = []byte{asc}
// at.PushRaw(pack)
// p.pushAudio = at.PushRaw
}
}
}
return
}
func (p *Publisher) PushPS(rtp *rtp.Packet) {
ps := rtp.Payload
if p.lastSeq != 0 {
// rtp序号不连续,丢弃PS
if p.lastSeq+1 != rtp.SequenceNumber {
p.parser.Reset()
}
}
p.lastSeq = rtp.SequenceNumber
p.Update()
if len(ps) >= 4 && BigEndian.Uint32(ps) == utils.StartCodePS {
if p.parser.Len() > 0 {
p.parser.Uint32()
p.parser.Read(rtp.Timestamp, p)
p.parser.Reset()
}
p.parser.Write(ps)
} else if p.parser.Len() > 0 {
p.parser.Write(ps)
}
}