Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

warn users about skipped tracks when reading or publishing #3753

Merged
merged 1 commit into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@

// 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 @@
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 @@
return nil
})

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

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

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 @@

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 @@
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 @@
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 @@
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 @@
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 @@
})

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
Loading