golanggohlsrtmpwebrtcmedia-serverobs-studiortcprtmp-proxyrtmp-serverrtprtsprtsp-proxyrtsp-relayrtsp-serversrtstreamingwebrtc-proxy
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
2.2 KiB
118 lines
2.2 KiB
package hls |
|
|
|
import ( |
|
"bytes" |
|
"fmt" |
|
"io" |
|
"strconv" |
|
"time" |
|
|
|
"github.com/aler9/gortsplib/v2/pkg/format" |
|
|
|
"github.com/aler9/rtsp-simple-server/internal/hls/mpegts" |
|
) |
|
|
|
type muxerVariantMPEGTSSegment struct { |
|
segmentMaxSize uint64 |
|
videoTrack *format.H264 |
|
audioTrack *format.MPEG4Audio |
|
writer *mpegts.Writer |
|
|
|
size uint64 |
|
startTime time.Time |
|
name string |
|
startDTS *time.Duration |
|
endDTS time.Duration |
|
audioAUCount int |
|
content []byte |
|
} |
|
|
|
func newMuxerVariantMPEGTSSegment( |
|
id uint64, |
|
startTime time.Time, |
|
segmentMaxSize uint64, |
|
videoTrack *format.H264, |
|
audioTrack *format.MPEG4Audio, |
|
writer *mpegts.Writer, |
|
) *muxerVariantMPEGTSSegment { |
|
t := &muxerVariantMPEGTSSegment{ |
|
segmentMaxSize: segmentMaxSize, |
|
videoTrack: videoTrack, |
|
audioTrack: audioTrack, |
|
writer: writer, |
|
startTime: startTime, |
|
name: "seg" + strconv.FormatUint(id, 10), |
|
} |
|
|
|
return t |
|
} |
|
|
|
func (t *muxerVariantMPEGTSSegment) duration() time.Duration { |
|
return t.endDTS - *t.startDTS |
|
} |
|
|
|
func (t *muxerVariantMPEGTSSegment) reader() io.Reader { |
|
return bytes.NewReader(t.content) |
|
} |
|
|
|
func (t *muxerVariantMPEGTSSegment) finalize(endDTS time.Duration) { |
|
t.endDTS = endDTS |
|
t.content = t.writer.GenerateSegment() |
|
} |
|
|
|
func (t *muxerVariantMPEGTSSegment) writeH264( |
|
pcr time.Duration, |
|
dts time.Duration, |
|
pts time.Duration, |
|
idrPresent bool, |
|
nalus [][]byte, |
|
) error { |
|
size := uint64(0) |
|
for _, nalu := range nalus { |
|
size += uint64(len(nalu)) |
|
} |
|
if (t.size + size) > t.segmentMaxSize { |
|
return fmt.Errorf("reached maximum segment size") |
|
} |
|
t.size += size |
|
|
|
err := t.writer.WriteH264(pcr, dts, pts, idrPresent, nalus) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
if t.startDTS == nil { |
|
t.startDTS = &dts |
|
} |
|
t.endDTS = dts |
|
|
|
return nil |
|
} |
|
|
|
func (t *muxerVariantMPEGTSSegment) writeAAC( |
|
pcr time.Duration, |
|
pts time.Duration, |
|
au []byte, |
|
) error { |
|
size := uint64(len(au)) |
|
if (t.size + size) > t.segmentMaxSize { |
|
return fmt.Errorf("reached maximum segment size") |
|
} |
|
t.size += size |
|
|
|
err := t.writer.WriteAAC(pcr, pts, au) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
if t.videoTrack == nil { |
|
t.audioAUCount++ |
|
|
|
if t.startDTS == nil { |
|
t.startDTS = &pts |
|
} |
|
t.endDTS = pts |
|
} |
|
|
|
return nil |
|
}
|
|
|