From 4c0833664dfe97c1d083b8a4736636957150dcc0 Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Sat, 27 Aug 2022 16:14:49 +0200 Subject: [PATCH] hls: fix blocking playlists when hlsVariant is lowLatency and hlsSegmentCount is not 7, segment IDs where assigned erroneously. --- internal/hls/muxer_test.go | 12 ++++++------ internal/hls/muxer_variant_fmp4_playlist.go | 6 +++--- internal/hls/muxer_variant_fmp4_segment.go | 6 ++---- internal/hls/muxer_variant_fmp4_segmenter.go | 10 ++++++++-- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/internal/hls/muxer_test.go b/internal/hls/muxer_test.go index 3e44c5d7..9a6f8c9a 100644 --- a/internal/hls/muxer_test.go +++ b/internal/hls/muxer_test.go @@ -173,10 +173,10 @@ func TestMuxerVideoAudio(t *testing.T) { `\n` + `#EXT-X-PROGRAM-DATE-TIME:(.*?)\n` + `#EXTINF:4.00000,\n` + - `(.+?\.mp4)\n` + + `(seg0\.mp4)\n` + `#EXT-X-PROGRAM-DATE-TIME:(.*?)\n` + `#EXTINF:1.00000,\n` + - `(.+?\.mp4)\n$`) + `(seg1\.mp4)\n$`) ma = re.FindStringSubmatch(string(byts)) } require.NotEqual(t, 0, len(ma)) @@ -507,10 +507,10 @@ func TestMuxerVideoOnly(t *testing.T) { `\n` + `#EXT-X-PROGRAM-DATE-TIME:(.*?)\n` + `#EXTINF:4.00000,\n` + - `(.+?\.mp4)\n` + + `(seg0\.mp4)\n` + `#EXT-X-PROGRAM-DATE-TIME:(.*?)\n` + `#EXTINF:1.00000,\n` + - `(.+?\.mp4)\n$`) + `(seg1\.mp4)\n$`) ma = re.FindStringSubmatch(string(byts)) } require.NotEqual(t, 0, len(ma)) @@ -731,10 +731,10 @@ func TestMuxerAudioOnly(t *testing.T) { `\n` + `#EXT-X-PROGRAM-DATE-TIME:(.*?)\n` + `#EXTINF:2.32200,\n` + - `(.+?\.mp4)\n` + + `(seg0\.mp4)\n` + `#EXT-X-PROGRAM-DATE-TIME:(.*?)\n` + `#EXTINF:0.02322,\n` + - `(.+?\.mp4)\n$`) + `(seg1\.mp4)\n$`) ma = re.FindStringSubmatch(string(byts)) } require.NotEqual(t, 0, len(ma)) diff --git a/internal/hls/muxer_variant_fmp4_playlist.go b/internal/hls/muxer_variant_fmp4_playlist.go index ff14f54f..d932538b 100644 --- a/internal/hls/muxer_variant_fmp4_playlist.go +++ b/internal/hls/muxer_variant_fmp4_playlist.go @@ -333,7 +333,7 @@ func (p *muxerVariantFMP4Playlist) fullPlaylist(isDeltaUpdate bool) io.Reader { } cnt += "#EXTINF:" + strconv.FormatFloat(seg.renderedDuration.Seconds(), 'f', 5, 64) + ",\n" + - seg.name() + ".mp4\n" + seg.name + ".mp4\n" case *muxerVariantFMP4Gap: cnt += "#EXT-X-GAP\n" + @@ -449,7 +449,7 @@ func (p *muxerVariantFMP4Playlist) onSegmentFinalized(segment *muxerVariantFMP4S } } - p.segmentsByName[segment.name()] = segment + p.segmentsByName[segment.name] = segment p.segments = append(p.segments, segment) p.nextSegmentID = segment.id + 1 p.nextSegmentParts = p.nextSegmentParts[:0] @@ -463,7 +463,7 @@ func (p *muxerVariantFMP4Playlist) onSegmentFinalized(segment *muxerVariantFMP4S } p.parts = p.parts[len(toDeleteSeg.parts):] - delete(p.segmentsByName, toDeleteSeg.name()) + delete(p.segmentsByName, toDeleteSeg.name) } p.segments = p.segments[1:] diff --git a/internal/hls/muxer_variant_fmp4_segment.go b/internal/hls/muxer_variant_fmp4_segment.go index 687af22a..926644f4 100644 --- a/internal/hls/muxer_variant_fmp4_segment.go +++ b/internal/hls/muxer_variant_fmp4_segment.go @@ -52,6 +52,7 @@ type muxerVariantFMP4Segment struct { genPartID func() uint64 onPartFinalized func(*muxerVariantFMP4Part) + name string size uint64 parts []*muxerVariantFMP4Part currentPart *muxerVariantFMP4Part @@ -79,6 +80,7 @@ func newMuxerVariantFMP4Segment( audioTrack: audioTrack, genPartID: genPartID, onPartFinalized: onPartFinalized, + name: "seg" + strconv.FormatUint(id, 10), } s.currentPart = newMuxerVariantFMP4Part( @@ -90,10 +92,6 @@ func newMuxerVariantFMP4Segment( return s } -func (s *muxerVariantFMP4Segment) name() string { - return "seg" + strconv.FormatUint(s.id, 10) -} - func (s *muxerVariantFMP4Segment) reader() io.Reader { return &partsReader{parts: s.parts} } diff --git a/internal/hls/muxer_variant_fmp4_segmenter.go b/internal/hls/muxer_variant_fmp4_segmenter.go index db348f1f..145fcd34 100644 --- a/internal/hls/muxer_variant_fmp4_segmenter.go +++ b/internal/hls/muxer_variant_fmp4_segmenter.go @@ -80,7 +80,7 @@ func newMuxerVariantFMP4Segmenter( onSegmentFinalized func(*muxerVariantFMP4Segment), onPartFinalized func(*muxerVariantFMP4Part), ) *muxerVariantFMP4Segmenter { - return &muxerVariantFMP4Segmenter{ + m := &muxerVariantFMP4Segmenter{ lowLatency: lowLatency, segmentDuration: segmentDuration, partDuration: partDuration, @@ -89,9 +89,15 @@ func newMuxerVariantFMP4Segmenter( audioTrack: audioTrack, onSegmentFinalized: onSegmentFinalized, onPartFinalized: onPartFinalized, - nextSegmentID: uint64(segmentCount), sampleDurations: make(map[time.Duration]struct{}), } + + // add initial gaps, required by iOS LL-HLS + if m.lowLatency { + m.nextSegmentID = 7 + } + + return m } func (m *muxerVariantFMP4Segmenter) genSegmentID() uint64 {