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

muxer: fix discontinuity in part ID #107

Merged
merged 1 commit into from
Nov 10, 2023
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
20 changes: 13 additions & 7 deletions muxer_segment_fmp4.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ type muxerSegmentFMP4 struct {
audioTimeScale uint32
prefix string
forceSwitched bool
genPartID func() uint64
takePartID func() uint64
givePartID func()
publishPart func(*muxerPart)

name string
Expand All @@ -42,7 +43,8 @@ func newMuxerSegmentFMP4(
prefix string,
forceSwitched bool,
factory storage.Factory,
genPartID func() uint64,
takePartID func() uint64,
givePartID func(),
publishPart func(*muxerPart),
) (*muxerSegmentFMP4, error) {
s := &muxerSegmentFMP4{
Expand All @@ -56,7 +58,8 @@ func newMuxerSegmentFMP4(
audioTimeScale: audioTimeScale,
prefix: prefix,
forceSwitched: forceSwitched,
genPartID: genPartID,
takePartID: takePartID,
givePartID: givePartID,
publishPart: publishPart,
name: segmentName(prefix, id, true),
}
Expand All @@ -73,7 +76,7 @@ func newMuxerSegmentFMP4(
s.audioTrack,
s.audioTimeScale,
prefix,
s.genPartID(),
s.takePartID(),
s.storage.NewPart(),
)

Expand Down Expand Up @@ -111,9 +114,12 @@ func (s *muxerSegmentFMP4) finalize(nextDTS time.Duration) error {
return err
}

s.publishPart(s.currentPart)
s.parts = append(s.parts, s.currentPart)
s.publishPart(s.currentPart)
} else {
s.givePartID()
}

s.currentPart = nil

s.storage.Finalize()
Expand Down Expand Up @@ -153,7 +159,7 @@ func (s *muxerSegmentFMP4) writeVideo(
s.audioTrack,
s.audioTimeScale,
s.prefix,
s.genPartID(),
s.takePartID(),
s.storage.NewPart(),
)
}
Expand Down Expand Up @@ -191,7 +197,7 @@ func (s *muxerSegmentFMP4) writeAudio(
s.audioTrack,
s.audioTimeScale,
s.prefix,
s.genPartID(),
s.takePartID(),
s.storage.NewPart(),
)
}
Expand Down
28 changes: 18 additions & 10 deletions muxer_segmenter_fmp4.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,18 +159,22 @@ func (m *muxerSegmenterFMP4) close() {
}
}

func (m *muxerSegmenterFMP4) genSegmentID() uint64 {
func (m *muxerSegmenterFMP4) takeSegmentID() uint64 {
id := m.nextSegmentID
m.nextSegmentID++
return id
}

func (m *muxerSegmenterFMP4) genPartID() uint64 {
func (m *muxerSegmenterFMP4) takePartID() uint64 {
id := m.nextPartID
m.nextPartID++
return id
}

func (m *muxerSegmenterFMP4) givePartID() {
m.nextPartID--
}

// iPhone iOS fails if part durations are less than 85% of maximum part duration.
// find a part duration that is compatible with all received sample durations
func (m *muxerSegmenterFMP4) adjustPartDuration(sampleDuration time.Duration) {
Expand Down Expand Up @@ -322,7 +326,7 @@ func (m *muxerSegmenterFMP4) writeVideo(
var err error
m.currentSegment, err = newMuxerSegmentFMP4(
m.lowLatency,
m.genSegmentID(),
m.takeSegmentID(),
sample.ntp,
sample.dts,
m.segmentMaxSize,
Expand All @@ -332,7 +336,8 @@ func (m *muxerSegmenterFMP4) writeVideo(
m.prefix,
false,
m.factory,
m.genPartID,
m.takePartID,
m.givePartID,
m.publishPart,
)
if err != nil {
Expand Down Expand Up @@ -365,7 +370,7 @@ func (m *muxerSegmenterFMP4) writeVideo(

m.currentSegment, err = newMuxerSegmentFMP4(
m.lowLatency,
m.genSegmentID(),
m.takeSegmentID(),
m.nextVideoSample.ntp,
m.nextVideoSample.dts,
m.segmentMaxSize,
Expand All @@ -375,7 +380,8 @@ func (m *muxerSegmenterFMP4) writeVideo(
m.prefix,
forceSwitch,
m.factory,
m.genPartID,
m.takePartID,
m.givePartID,
m.publishPart,
)
if err != nil {
Expand Down Expand Up @@ -455,7 +461,7 @@ func (m *muxerSegmenterFMP4) writeAudio(ntp time.Time, dts time.Duration, au []b
var err error
m.currentSegment, err = newMuxerSegmentFMP4(
m.lowLatency,
m.genSegmentID(),
m.takeSegmentID(),
sample.ntp,
sample.dts,
m.segmentMaxSize,
Expand All @@ -465,7 +471,8 @@ func (m *muxerSegmenterFMP4) writeAudio(ntp time.Time, dts time.Duration, au []b
m.prefix,
false,
m.factory,
m.genPartID,
m.takePartID,
m.givePartID,
m.publishPart,
)
if err != nil {
Expand Down Expand Up @@ -501,7 +508,7 @@ func (m *muxerSegmenterFMP4) writeAudio(ntp time.Time, dts time.Duration, au []b

m.currentSegment, err = newMuxerSegmentFMP4(
m.lowLatency,
m.genSegmentID(),
m.takeSegmentID(),
m.nextAudioSample.ntp,
m.nextAudioSample.dts,
m.segmentMaxSize,
Expand All @@ -511,7 +518,8 @@ func (m *muxerSegmenterFMP4) writeAudio(ntp time.Time, dts time.Duration, au []b
m.prefix,
false,
m.factory,
m.genPartID,
m.takePartID,
m.givePartID,
m.publishPart,
)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions muxer_segmenter_mpegts.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (m *muxerSegmenterMPEGTS) close() {
}
}

func (m *muxerSegmenterMPEGTS) genSegmentID() uint64 {
func (m *muxerSegmenterMPEGTS) takeSegmentID() uint64 {
id := m.nextSegmentID
m.nextSegmentID++
return id
Expand Down Expand Up @@ -142,7 +142,7 @@ func (m *muxerSegmenterMPEGTS) writeH26x(

// create first segment
m.currentSegment, err = newMuxerSegmentMPEGTS(
m.genSegmentID(),
m.takeSegmentID(),
ntp,
m.segmentMaxSize,
m.writerVideoTrack,
Expand Down Expand Up @@ -176,7 +176,7 @@ func (m *muxerSegmenterMPEGTS) writeH26x(
}

m.currentSegment, err = newMuxerSegmentMPEGTS(
m.genSegmentID(),
m.takeSegmentID(),
ntp,
m.segmentMaxSize,
m.writerVideoTrack,
Expand Down Expand Up @@ -214,7 +214,7 @@ func (m *muxerSegmenterMPEGTS) writeMPEG4Audio(ntp time.Time, pts time.Duration,
// create first segment
var err error
m.currentSegment, err = newMuxerSegmentMPEGTS(
m.genSegmentID(),
m.takeSegmentID(),
ntp,
m.segmentMaxSize,
m.writerVideoTrack,
Expand All @@ -240,7 +240,7 @@ func (m *muxerSegmenterMPEGTS) writeMPEG4Audio(ntp time.Time, pts time.Duration,
}

m.currentSegment, err = newMuxerSegmentMPEGTS(
m.genSegmentID(),
m.takeSegmentID(),
ntp,
m.segmentMaxSize,
m.writerVideoTrack,
Expand Down
4 changes: 2 additions & 2 deletions muxer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,10 @@ func TestMuxerVideoAudio(t *testing.T) {
`#EXTINF:4.00000,\n` +
`(.*?_seg7\.mp4)\n` +
`#EXT-X-PROGRAM-DATE-TIME:2010-01-01T01:01:06Z\n` +
`#EXT-X-PART:DURATION=1.00000,URI="(.*?_part3\.mp4)",INDEPENDENT=YES\n` +
`#EXT-X-PART:DURATION=1.00000,URI="(.*?_part2\.mp4)",INDEPENDENT=YES\n` +
`#EXTINF:1.00000,\n` +
`(.*?_seg8\.mp4)\n` +
`#EXT-X-PRELOAD-HINT:TYPE=PART,URI="(.*?_part4\.mp4)"\n$`)
`#EXT-X-PRELOAD-HINT:TYPE=PART,URI="(.*?_part3\.mp4)"\n$`)
require.Regexp(t, re, string(byts))
ma := re.FindStringSubmatch(string(byts))

Expand Down