-
Notifications
You must be signed in to change notification settings - Fork 28
/
muxer_segment_mpegts.go
145 lines (120 loc) · 2.66 KB
/
muxer_segment_mpegts.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package gohlslib
import (
"bufio"
"fmt"
"io"
"time"
"github.com/bluenviron/gohlslib/v2/pkg/storage"
"github.com/bluenviron/mediacommon/pkg/formats/mpegts"
)
type muxerSegmentMPEGTS struct {
segmentMaxSize uint64
prefix string
storageFactory storage.Factory
streamID string
mpegtsWriter *mpegts.Writer
id uint64
startNTP time.Time
startDTS time.Duration
storage storage.File
storagePart storage.Part
bw *bufio.Writer
size uint64
path string
endDTS time.Duration
audioAUCount int
}
func (s *muxerSegmentMPEGTS) initialize() error {
s.path = segmentPath(s.prefix, s.streamID, s.id, false)
var err error
s.storage, err = s.storageFactory.NewFile(s.path)
if err != nil {
return err
}
s.storagePart = s.storage.NewPart()
s.bw = bufio.NewWriter(s.storagePart.Writer())
return nil
}
func (s *muxerSegmentMPEGTS) close() {
s.storage.Remove()
}
func (s *muxerSegmentMPEGTS) getPath() string {
return s.path
}
func (s *muxerSegmentMPEGTS) getDuration() time.Duration {
return s.endDTS - s.startDTS
}
func (s *muxerSegmentMPEGTS) getSize() uint64 {
return s.storage.Size()
}
func (*muxerSegmentMPEGTS) isFromForcedRotation() bool {
return false
}
func (s *muxerSegmentMPEGTS) reader() (io.ReadCloser, error) {
return s.storage.Reader()
}
func (s *muxerSegmentMPEGTS) finalize(endDTS time.Duration) error {
err := s.bw.Flush()
if err != nil {
return err
}
s.bw = nil
s.storage.Finalize()
s.endDTS = endDTS
return nil
}
func (s *muxerSegmentMPEGTS) writeH264(
track *muxerTrack,
pts int64,
dts int64,
idrPresent bool,
au [][]byte,
) error {
size := uint64(0)
for _, nalu := range au {
size += uint64(len(nalu))
}
if (s.size + size) > s.segmentMaxSize {
return fmt.Errorf("reached maximum segment size")
}
s.size += size
err := s.mpegtsWriter.WriteH264(
track.mpegtsTrack,
multiplyAndDivide(pts, 90000, int64(track.ClockRate)),
multiplyAndDivide(dts, 90000, int64(track.ClockRate)),
idrPresent,
au,
)
if err != nil {
return err
}
s.endDTS = timestampToDuration(dts, track.ClockRate)
return nil
}
func (s *muxerSegmentMPEGTS) writeMPEG4Audio(
track *muxerTrack,
pts int64,
aus [][]byte,
) error {
size := uint64(0)
for _, au := range aus {
size += uint64(len(au))
}
if (s.size + size) > s.segmentMaxSize {
return fmt.Errorf("reached maximum segment size")
}
s.size += size
err := s.mpegtsWriter.WriteMPEG4Audio(
track.mpegtsTrack,
multiplyAndDivide(pts, 90000, int64(track.ClockRate)),
aus,
)
if err != nil {
return err
}
if track.isLeading {
s.audioAUCount++
s.endDTS = timestampToDuration(pts, track.ClockRate)
}
return nil
}