2021-08-23 10:26:06 +00:00
|
|
|
package hls
|
|
|
|
|
|
|
|
import (
|
2022-05-31 17:17:26 +00:00
|
|
|
"bytes"
|
2021-08-23 10:26:06 +00:00
|
|
|
"encoding/hex"
|
|
|
|
"io"
|
2022-05-31 17:17:26 +00:00
|
|
|
"net/http"
|
2022-01-30 10:32:20 +00:00
|
|
|
"strconv"
|
2021-08-23 10:26:06 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/aler9/gortsplib"
|
|
|
|
)
|
|
|
|
|
2021-09-07 10:02:44 +00:00
|
|
|
type muxerPrimaryPlaylist struct {
|
2022-05-31 17:17:26 +00:00
|
|
|
fmp4 bool
|
2022-01-30 16:36:42 +00:00
|
|
|
videoTrack *gortsplib.TrackH264
|
2022-08-05 21:50:45 +00:00
|
|
|
audioTrack *gortsplib.TrackMPEG4Audio
|
2021-08-23 10:26:06 +00:00
|
|
|
}
|
|
|
|
|
2021-09-07 10:02:44 +00:00
|
|
|
func newMuxerPrimaryPlaylist(
|
2022-05-31 17:17:26 +00:00
|
|
|
fmp4 bool,
|
2022-01-30 16:36:42 +00:00
|
|
|
videoTrack *gortsplib.TrackH264,
|
2022-08-05 21:50:45 +00:00
|
|
|
audioTrack *gortsplib.TrackMPEG4Audio,
|
2021-09-07 10:02:44 +00:00
|
|
|
) *muxerPrimaryPlaylist {
|
2022-04-24 11:01:27 +00:00
|
|
|
return &muxerPrimaryPlaylist{
|
2022-05-31 17:17:26 +00:00
|
|
|
fmp4: fmp4,
|
2021-08-23 10:26:06 +00:00
|
|
|
videoTrack: videoTrack,
|
|
|
|
audioTrack: audioTrack,
|
|
|
|
}
|
2022-04-24 11:01:27 +00:00
|
|
|
}
|
2021-08-23 10:26:06 +00:00
|
|
|
|
2022-05-31 17:17:26 +00:00
|
|
|
func (p *muxerPrimaryPlaylist) file() *MuxerFileResponse {
|
|
|
|
return &MuxerFileResponse{
|
|
|
|
Status: http.StatusOK,
|
|
|
|
Header: map[string]string{
|
|
|
|
"Content-Type": `audio/mpegURL`,
|
|
|
|
},
|
|
|
|
Body: func() io.Reader {
|
|
|
|
var codecs []string
|
2022-04-24 11:01:27 +00:00
|
|
|
|
2022-05-31 17:17:26 +00:00
|
|
|
if p.videoTrack != nil {
|
2022-06-23 11:54:48 +00:00
|
|
|
sps := p.videoTrack.SafeSPS()
|
2022-05-31 17:17:26 +00:00
|
|
|
if len(sps) >= 4 {
|
|
|
|
codecs = append(codecs, "avc1."+hex.EncodeToString(sps[1:4]))
|
|
|
|
}
|
2022-04-24 11:01:27 +00:00
|
|
|
}
|
2022-05-31 17:17:26 +00:00
|
|
|
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/codecs_parameter
|
|
|
|
if p.audioTrack != nil {
|
2022-06-24 15:00:28 +00:00
|
|
|
codecs = append(codecs, "mp4a.40."+strconv.FormatInt(int64(p.audioTrack.Config.Type), 10))
|
2022-05-31 17:17:26 +00:00
|
|
|
}
|
|
|
|
|
2022-08-27 14:00:08 +00:00
|
|
|
var version int
|
|
|
|
if !p.fmp4 {
|
|
|
|
version = 3
|
|
|
|
} else {
|
|
|
|
version = 9
|
2022-05-31 17:17:26 +00:00
|
|
|
}
|
2022-08-27 14:00:08 +00:00
|
|
|
|
|
|
|
return bytes.NewReader([]byte("#EXTM3U\n" +
|
|
|
|
"#EXT-X-VERSION:" + strconv.FormatInt(int64(version), 10) + "\n" +
|
|
|
|
"#EXT-X-INDEPENDENT-SEGMENTS\n" +
|
|
|
|
"\n" +
|
|
|
|
"#EXT-X-STREAM-INF:BANDWIDTH=200000,CODECS=\"" + strings.Join(codecs, ",") + "\"\n" +
|
|
|
|
"stream.m3u8\n"))
|
2022-05-31 17:17:26 +00:00
|
|
|
}(),
|
|
|
|
}
|
2021-08-23 10:26:06 +00:00
|
|
|
}
|