Skip to content

Commit

Permalink
warn users about skipped tracks when reading or publishing
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 committed Sep 15, 2024
1 parent 8aedf1a commit d777a7c
Show file tree
Hide file tree
Showing 27 changed files with 584 additions and 55 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ require (
github.com/MicahParks/keyfunc/v3 v3.3.3
github.com/abema/go-mp4 v1.2.0
github.com/alecthomas/kong v1.2.1
github.com/asticode/go-astits v1.13.0
github.com/bluenviron/gohlslib v1.4.0
github.com/bluenviron/gortsplib/v4 v4.10.4
github.com/bluenviron/mediacommon v1.12.3
github.com/bluenviron/mediacommon v1.12.4-0.20240909171423-2f5c038aff08
github.com/datarhei/gosrt v0.7.0
github.com/fsnotify/fsnotify v1.7.0
github.com/gin-gonic/gin v1.10.0
Expand All @@ -36,7 +37,6 @@ require (

require (
github.com/asticode/go-astikit v0.30.0 // indirect
github.com/asticode/go-astits v1.13.0 // indirect
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ github.com/bluenviron/gohlslib v1.4.0 h1:3a9W1x8eqlxJUKt1sJCunPGtti5ALIY2ik4GU0R
github.com/bluenviron/gohlslib v1.4.0/go.mod h1:q5ZElzNw5GRbV1VEI45qkcPbKBco6BP58QEY5HyFsmo=
github.com/bluenviron/gortsplib/v4 v4.10.4 h1:7fDGKRfb7q3Foab6ctfU45BNd8q3G/ln2wwMlhcoyz8=
github.com/bluenviron/gortsplib/v4 v4.10.4/go.mod h1:BsTItHGBtHOPmj3D6AygXaAMXx4+LQlJWNfDAI5PNkg=
github.com/bluenviron/mediacommon v1.12.3 h1:a7O1CzfdWsLJmTLe365KfRoAGeVxJPB/aDaCW4Jm2+U=
github.com/bluenviron/mediacommon v1.12.3/go.mod h1:HDyW2CzjvhYJXtdxstdFPio3G0qSocPhqkhUt/qffec=
github.com/bluenviron/mediacommon v1.12.4-0.20240909171423-2f5c038aff08 h1:8eI9UTEBmq5PSSwCO5fI78kujvGtLPsHApWG9MeDhgg=
github.com/bluenviron/mediacommon v1.12.4-0.20240909171423-2f5c038aff08/go.mod h1:HDyW2CzjvhYJXtdxstdFPio3G0qSocPhqkhUt/qffec=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
Expand Down
43 changes: 27 additions & 16 deletions internal/protocols/hls/from_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import (

// ErrNoSupportedCodecs is returned by FromStream when there are no supported codecs.
var ErrNoSupportedCodecs = errors.New(
"the stream doesn't contain any supported codec, which are currently H265, H264, Opus, MPEG-4 Audio")
"the stream doesn't contain any supported codec, which are currently AV1, VP9, H265, H264, Opus, MPEG-4 Audio")

func setupVideoTrack(
stream *stream.Stream,
writer *asyncwriter.Writer,
muxer *gohlslib.Muxer,
) *gohlslib.Track {
) format.Format {
var videoFormatAV1 *format.AV1
videoMedia := stream.Desc().FindFormat(&videoFormatAV1)

Expand All @@ -42,9 +42,10 @@ func setupVideoTrack(
return nil
})

return &gohlslib.Track{
muxer.VideoTrack = &gohlslib.Track{

Check warning on line 45 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L45

Added line #L45 was not covered by tests
Codec: &codecs.AV1{},
}
return videoFormatAV1

Check warning on line 48 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L48

Added line #L48 was not covered by tests
}

var videoFormatVP9 *format.VP9
Expand All @@ -66,9 +67,10 @@ func setupVideoTrack(
return nil
})

return &gohlslib.Track{
muxer.VideoTrack = &gohlslib.Track{
Codec: &codecs.VP9{},
}
return videoFormatVP9
}

var videoFormatH265 *format.H265
Expand All @@ -92,13 +94,14 @@ func setupVideoTrack(

vps, sps, pps := videoFormatH265.SafeParams()

return &gohlslib.Track{
muxer.VideoTrack = &gohlslib.Track{

Check warning on line 97 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L97

Added line #L97 was not covered by tests
Codec: &codecs.H265{
VPS: vps,
SPS: sps,
PPS: pps,
},
}
return videoFormatH265

Check warning on line 104 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L104

Added line #L104 was not covered by tests
}

var videoFormatH264 *format.H264
Expand All @@ -122,12 +125,13 @@ func setupVideoTrack(

sps, pps := videoFormatH264.SafeParams()

return &gohlslib.Track{
muxer.VideoTrack = &gohlslib.Track{

Check warning on line 128 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L128

Added line #L128 was not covered by tests
Codec: &codecs.H264{
SPS: sps,
PPS: pps,
},
}
return videoFormatH264

Check warning on line 134 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L134

Added line #L134 was not covered by tests
}

return nil
Expand All @@ -138,11 +142,11 @@ func setupAudioTrack(
writer *asyncwriter.Writer,
muxer *gohlslib.Muxer,
l logger.Writer,
) *gohlslib.Track {
) format.Format {
var audioFormatOpus *format.Opus
audioMedia := stream.Desc().FindFormat(&audioFormatOpus)

if audioMedia != nil {
if audioFormatOpus != nil {
stream.AddReader(writer, audioMedia, audioFormatOpus, func(u unit.Unit) error {
tunit := u.(*unit.Opus)

Expand All @@ -157,17 +161,18 @@ func setupAudioTrack(
return nil
})

return &gohlslib.Track{
muxer.AudioTrack = &gohlslib.Track{

Check warning on line 164 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L164

Added line #L164 was not covered by tests
Codec: &codecs.Opus{
ChannelCount: audioFormatOpus.ChannelCount,
},
}
return audioFormatOpus

Check warning on line 169 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L169

Added line #L169 was not covered by tests
}

var audioFormatMPEG4Audio *format.MPEG4Audio
audioMedia = stream.Desc().FindFormat(&audioFormatMPEG4Audio)

if audioMedia != nil {
if audioFormatMPEG4Audio != nil {
co := audioFormatMPEG4Audio.GetConfig()
if co == nil {
l.Log(logger.Warn, "skipping MPEG-4 audio track: tracks without explicit configuration are not supported")
Expand All @@ -190,11 +195,12 @@ func setupAudioTrack(
return nil
})

return &gohlslib.Track{
muxer.AudioTrack = &gohlslib.Track{

Check warning on line 198 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L198

Added line #L198 was not covered by tests
Codec: &codecs.MPEG4Audio{
Config: *co,
},
}
return audioFormatMPEG4Audio

Check warning on line 203 in internal/protocols/hls/from_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/from_stream.go#L203

Added line #L203 was not covered by tests
}
}

Expand All @@ -208,25 +214,30 @@ func FromStream(
muxer *gohlslib.Muxer,
l logger.Writer,
) error {
videoTrack := setupVideoTrack(
videoFormat := setupVideoTrack(
stream,
writer,
muxer,
)

audioTrack := setupAudioTrack(
audioFormat := setupAudioTrack(
stream,
writer,
muxer,
l,
)

if videoTrack == nil && audioTrack == nil {
if videoFormat == nil && audioFormat == nil {
return ErrNoSupportedCodecs
}

muxer.VideoTrack = videoTrack
muxer.AudioTrack = audioTrack
for _, media := range stream.Desc().Medias {
for _, forma := range media.Formats {
if forma != videoFormat && forma != audioFormat {
l.Log(logger.Warn, "skipping track with codec %s", forma.Codec())
}
}
}

return nil
}
81 changes: 81 additions & 0 deletions internal/protocols/hls/from_stream_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package hls

import (
"fmt"
"testing"

"github.com/bluenviron/gohlslib"
"github.com/bluenviron/gortsplib/v4/pkg/description"
"github.com/bluenviron/gortsplib/v4/pkg/format"
"github.com/bluenviron/mediamtx/internal/asyncwriter"
"github.com/bluenviron/mediamtx/internal/logger"
"github.com/bluenviron/mediamtx/internal/stream"
"github.com/bluenviron/mediamtx/internal/test"
"github.com/stretchr/testify/require"
)

func TestFromStreamNoSupportedCodecs(t *testing.T) {
stream, err := stream.New(
1460,
&description.Session{Medias: []*description.Media{{
Type: description.MediaTypeVideo,
Formats: []format.Format{&format.VP8{}},
}}},
true,
test.NilLogger,
)
require.NoError(t, err)

writer := asyncwriter.New(0, nil)

l := test.Logger(func(logger.Level, string, ...interface{}) {
t.Error("should not happen")
})

err = FromStream(stream, writer, nil, l)
require.Equal(t, ErrNoSupportedCodecs, err)
}

func TestFromStreamSkipUnsupportedTracks(t *testing.T) {
stream, err := stream.New(
1460,
&description.Session{Medias: []*description.Media{
{
Type: description.MediaTypeVideo,
Formats: []format.Format{&format.VP9{}},
},
{
Type: description.MediaTypeVideo,
Formats: []format.Format{&format.VP8{}},
},
{
Type: description.MediaTypeAudio,
Formats: []format.Format{&format.MPEG1Audio{}},
},
}},
true,
test.NilLogger,
)
require.NoError(t, err)

writer := asyncwriter.New(0, nil)

m := &gohlslib.Muxer{}

n := 0

l := test.Logger(func(l logger.Level, format string, args ...interface{}) {
require.Equal(t, logger.Warn, l)
switch n {
case 0:
require.Equal(t, "skipping track with codec VP8", fmt.Sprintf(format, args...))
case 1:
require.Equal(t, "skipping track with codec MPEG-1/2 Audio", fmt.Sprintf(format, args...))
}
n++
})

err = FromStream(stream, writer, m, l)
require.NoError(t, err)
require.Equal(t, 2, n)
}
7 changes: 5 additions & 2 deletions internal/protocols/hls/to_stream.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package hls

import (
"fmt"
"time"

"github.com/bluenviron/gohlslib"
Expand Down Expand Up @@ -144,11 +143,15 @@ func ToStream(
})

default:
return nil, fmt.Errorf("unsupported track: %T", track.Codec)
panic("should not happen")

Check warning on line 146 in internal/protocols/hls/to_stream.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/hls/to_stream.go#L146

Added line #L146 was not covered by tests
}

medias = append(medias, medi)
}

if len(medias) == 0 {
return nil, ErrNoSupportedCodecs
}

return medias, nil
}
16 changes: 16 additions & 0 deletions internal/protocols/hls/to_stream_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package hls

import (
"testing"

"github.com/bluenviron/gohlslib"
"github.com/stretchr/testify/require"
)

func TestToStreamNoSupportedCodecs(t *testing.T) {
_, err := ToStream(nil, []*gohlslib.Track{}, nil)
require.Equal(t, ErrNoSupportedCodecs, err)
}

// this is impossible to test since currently we support all gohlslib.Tracks.
// func TestToStreamSkipUnsupportedTracks(t *testing.T)
12 changes: 11 additions & 1 deletion internal/protocols/mpegts/from_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
srt "github.com/datarhei/gosrt"

"github.com/bluenviron/mediamtx/internal/asyncwriter"
"github.com/bluenviron/mediamtx/internal/logger"
"github.com/bluenviron/mediamtx/internal/stream"
"github.com/bluenviron/mediamtx/internal/unit"
)
Expand All @@ -28,9 +29,11 @@ func FromStream(
bw *bufio.Writer,
sconn srt.Conn,
writeTimeout time.Duration,
l logger.Writer,
) error {
var w *mcmpegts.Writer
var tracks []*mcmpegts.Track
var skippedFormats []format.Format

addTrack := func(codec mcmpegts.Codec) *mcmpegts.Track {
track := &mcmpegts.Track{
Expand Down Expand Up @@ -246,12 +249,19 @@ func FromStream(
}
return bw.Flush()
})

default:
skippedFormats = append(skippedFormats, forma)
}
}
}

if len(tracks) == 0 {
return ErrNoTracks
return errNoSupportedCodecs
}

for _, forma := range skippedFormats {
l.Log(logger.Warn, "skipping track with codec %s", forma.Codec())
}

w = mcmpegts.NewWriter(bw, tracks)
Expand Down
Loading

0 comments on commit d777a7c

Please sign in to comment.