2021-07-24 16:31:54 +00:00
|
|
|
package hls
|
|
|
|
|
|
|
|
import (
|
2022-01-30 16:36:42 +00:00
|
|
|
"fmt"
|
2021-07-24 16:31:54 +00:00
|
|
|
"io"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/aler9/gortsplib"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Muxer is a HLS muxer.
|
|
|
|
type Muxer struct {
|
2021-09-07 10:02:44 +00:00
|
|
|
primaryPlaylist *muxerPrimaryPlaylist
|
|
|
|
streamPlaylist *muxerStreamPlaylist
|
|
|
|
tsGenerator *muxerTSGenerator
|
2021-07-24 16:31:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewMuxer allocates a Muxer.
|
|
|
|
func NewMuxer(
|
|
|
|
hlsSegmentCount int,
|
|
|
|
hlsSegmentDuration time.Duration,
|
2022-01-29 15:10:08 +00:00
|
|
|
hlsSegmentMaxSize uint64,
|
2022-01-30 16:36:42 +00:00
|
|
|
videoTrack *gortsplib.TrackH264,
|
|
|
|
audioTrack *gortsplib.TrackAAC) (*Muxer, error) {
|
2021-08-14 13:39:29 +00:00
|
|
|
if videoTrack != nil {
|
2022-01-30 16:36:42 +00:00
|
|
|
if videoTrack.SPS() == nil || videoTrack.PPS() == nil {
|
|
|
|
return nil, fmt.Errorf("invalid H264 track: SPS or PPS not provided into the SDP")
|
2021-08-14 13:39:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-30 16:36:42 +00:00
|
|
|
primaryPlaylist := newMuxerPrimaryPlaylist(videoTrack, audioTrack)
|
2021-09-07 10:02:44 +00:00
|
|
|
|
|
|
|
streamPlaylist := newMuxerStreamPlaylist(hlsSegmentCount)
|
|
|
|
|
|
|
|
tsGenerator := newMuxerTSGenerator(
|
|
|
|
hlsSegmentCount,
|
|
|
|
hlsSegmentDuration,
|
2022-01-29 15:10:08 +00:00
|
|
|
hlsSegmentMaxSize,
|
2021-09-07 10:02:44 +00:00
|
|
|
videoTrack,
|
|
|
|
audioTrack,
|
|
|
|
streamPlaylist)
|
|
|
|
|
2021-07-24 16:31:54 +00:00
|
|
|
m := &Muxer{
|
2021-09-07 10:02:44 +00:00
|
|
|
primaryPlaylist: primaryPlaylist,
|
|
|
|
streamPlaylist: streamPlaylist,
|
|
|
|
tsGenerator: tsGenerator,
|
2021-07-24 16:31:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close closes a Muxer.
|
|
|
|
func (m *Muxer) Close() {
|
2021-08-23 10:26:06 +00:00
|
|
|
m.streamPlaylist.close()
|
2021-07-24 16:31:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// WriteH264 writes H264 NALUs, grouped by PTS, into the muxer.
|
|
|
|
func (m *Muxer) WriteH264(pts time.Duration, nalus [][]byte) error {
|
2021-09-07 10:02:44 +00:00
|
|
|
return m.tsGenerator.writeH264(pts, nalus)
|
2021-07-24 16:31:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// WriteAAC writes AAC AUs, grouped by PTS, into the muxer.
|
|
|
|
func (m *Muxer) WriteAAC(pts time.Duration, aus [][]byte) error {
|
2021-09-07 10:02:44 +00:00
|
|
|
return m.tsGenerator.writeAAC(pts, aus)
|
2021-07-24 16:31:54 +00:00
|
|
|
}
|
|
|
|
|
2021-09-07 10:02:44 +00:00
|
|
|
// PrimaryPlaylist returns a reader to read the primary playlist.
|
2021-08-16 16:07:10 +00:00
|
|
|
func (m *Muxer) PrimaryPlaylist() io.Reader {
|
2021-08-23 10:26:06 +00:00
|
|
|
return m.primaryPlaylist.reader()
|
2021-08-16 16:07:10 +00:00
|
|
|
}
|
2021-07-24 16:31:54 +00:00
|
|
|
|
2021-08-16 16:07:10 +00:00
|
|
|
// StreamPlaylist returns a reader to read the stream playlist.
|
|
|
|
func (m *Muxer) StreamPlaylist() io.Reader {
|
2021-08-23 10:26:06 +00:00
|
|
|
return m.streamPlaylist.reader()
|
2021-07-24 16:31:54 +00:00
|
|
|
}
|
|
|
|
|
2021-09-07 10:02:44 +00:00
|
|
|
// Segment returns a reader to read a segment listed in the stream playlist.
|
2021-08-23 10:26:06 +00:00
|
|
|
func (m *Muxer) Segment(fname string) io.Reader {
|
|
|
|
return m.streamPlaylist.segment(fname)
|
2021-07-24 16:31:54 +00:00
|
|
|
}
|