Support codecs negotiation for MSE
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/cmd/streams"
|
"github.com/AlexxIT/go2rtc/cmd/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/mp4"
|
"github.com/AlexxIT/go2rtc/pkg/mp4"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MsgTypeMSE = "mse" // fMP4
|
const MsgTypeMSE = "mse" // fMP4
|
||||||
@@ -22,6 +23,10 @@ func handlerWS(ctx *api.Context, msg *streamer.Message) {
|
|||||||
cons.UserAgent = ctx.Request.UserAgent()
|
cons.UserAgent = ctx.Request.UserAgent()
|
||||||
cons.RemoteAddr = ctx.Request.RemoteAddr
|
cons.RemoteAddr = ctx.Request.RemoteAddr
|
||||||
|
|
||||||
|
if codecs, ok := msg.Value.(string); ok {
|
||||||
|
cons.Medias = parseMedias(codecs)
|
||||||
|
}
|
||||||
|
|
||||||
cons.Listen(func(msg interface{}) {
|
cons.Listen(func(msg interface{}) {
|
||||||
if data, ok := msg.([]byte); ok {
|
if data, ok := msg.([]byte); ok {
|
||||||
for len(data) > packetSize {
|
for len(data) > packetSize {
|
||||||
@@ -55,3 +60,42 @@ func handlerWS(ctx *api.Context, msg *streamer.Message) {
|
|||||||
|
|
||||||
cons.Start()
|
cons.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseMedias(codecs string) (medias []*streamer.Media) {
|
||||||
|
var videos []*streamer.Codec
|
||||||
|
var audios []*streamer.Codec
|
||||||
|
|
||||||
|
for _, name := range strings.Split(codecs, ",") {
|
||||||
|
switch name {
|
||||||
|
case "avc1.640029":
|
||||||
|
codec := &streamer.Codec{Name: streamer.CodecH264}
|
||||||
|
videos = append(videos, codec)
|
||||||
|
case "hvc1.1.6.L153.B0":
|
||||||
|
codec := &streamer.Codec{Name: streamer.CodecH265}
|
||||||
|
videos = append(videos, codec)
|
||||||
|
case "mp4a.40.2":
|
||||||
|
codec := &streamer.Codec{Name: streamer.CodecAAC}
|
||||||
|
audios = append(audios, codec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if videos != nil {
|
||||||
|
media := &streamer.Media{
|
||||||
|
Kind: streamer.KindVideo,
|
||||||
|
Direction: streamer.DirectionRecvonly,
|
||||||
|
Codecs: videos,
|
||||||
|
}
|
||||||
|
medias = append(medias, media)
|
||||||
|
}
|
||||||
|
|
||||||
|
if audios != nil {
|
||||||
|
media := &streamer.Media{
|
||||||
|
Kind: streamer.KindAudio,
|
||||||
|
Direction: streamer.DirectionRecvonly,
|
||||||
|
Codecs: audios,
|
||||||
|
}
|
||||||
|
medias = append(medias, media)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
type Consumer struct {
|
type Consumer struct {
|
||||||
streamer.Element
|
streamer.Element
|
||||||
|
|
||||||
|
Medias []*streamer.Media
|
||||||
UserAgent string
|
UserAgent string
|
||||||
RemoteAddr string
|
RemoteAddr string
|
||||||
|
|
||||||
@@ -23,6 +24,11 @@ type Consumer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Consumer) GetMedias() []*streamer.Media {
|
func (c *Consumer) GetMedias() []*streamer.Media {
|
||||||
|
if c.Medias != nil {
|
||||||
|
return c.Medias
|
||||||
|
}
|
||||||
|
|
||||||
|
// default medias
|
||||||
return []*streamer.Media{
|
return []*streamer.Media{
|
||||||
{
|
{
|
||||||
Kind: streamer.KindVideo,
|
Kind: streamer.KindVideo,
|
||||||
|
|||||||
+3
-2
@@ -35,8 +35,9 @@ func (m *Muxer) MimeType(codecs []*streamer.Codec) string {
|
|||||||
case streamer.CodecH264:
|
case streamer.CodecH264:
|
||||||
s += "avc1." + h264.GetProfileLevelID(codec.FmtpLine)
|
s += "avc1." + h264.GetProfileLevelID(codec.FmtpLine)
|
||||||
case streamer.CodecH265:
|
case streamer.CodecH265:
|
||||||
// +Safari +Chrome +Edge -iOS15 -Android13
|
// H.265 profile=main level=5.1
|
||||||
s += "hvc1.1.6.L93.B0" // hev1.1.6.L93.B0
|
// hvc1 - supported in Safari, hev1 - doesn't, both supported in Chrome
|
||||||
|
s += "hvc1.1.6.L153.B0"
|
||||||
case streamer.CodecAAC:
|
case streamer.CodecAAC:
|
||||||
s += "mp4a.40.2"
|
s += "mp4a.40.2"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user