@@ -5,23 +5,44 @@ import (
55 "fmt"
66 "io"
77 "os"
8+ "path/filepath"
89 "time"
910
10- "github.com/abema/go-mp4"
11+ amp4 "github.com/abema/go-mp4"
12+ "github.com/google/uuid"
13+
1114 "github.com/bluenviron/mediacommon/v2/pkg/formats/fmp4"
1215 "github.com/bluenviron/mediacommon/v2/pkg/formats/fmp4/seekablebuffer"
13-
1416 "github.com/bluenviron/mediamtx/internal/logger"
17+ "github.com/bluenviron/mediamtx/internal/recordstore"
1518)
1619
17- func writeInit (f io.Writer , tracks []* formatFMP4Track ) error {
20+ func writeInit (
21+ f io.Writer ,
22+ streamID uuid.UUID ,
23+ segmentNumber uint64 ,
24+ dts time.Duration ,
25+ ntp time.Time ,
26+ tracks []* formatFMP4Track ,
27+ ) error {
1828 fmp4Tracks := make ([]* fmp4.InitTrack , len (tracks ))
1929 for i , track := range tracks {
2030 fmp4Tracks [i ] = track .initTrack
2131 }
2232
2333 init := fmp4.Init {
2434 Tracks : fmp4Tracks ,
35+ UserData : []amp4.IBox {
36+ & recordstore.Mtxi {
37+ FullBox : amp4.FullBox {
38+ Version : 0 ,
39+ },
40+ StreamID : streamID ,
41+ SegmentNumber : segmentNumber ,
42+ DTS : int64 (dts ),
43+ NTP : ntp .UnixNano (),
44+ },
45+ },
2546 }
2647
2748 var buf seekablebuffer.Buffer
@@ -77,8 +98,8 @@ func writeDuration(f io.ReadWriteSeeker, d time.Duration) error {
7798 return err
7899 }
79100
80- var mvhd mp4 .Mvhd
81- _ , err = mp4 .Unmarshal (f , uint64 (moovSize - 8 ), & mvhd , mp4 .Context {})
101+ var mvhd amp4 .Mvhd
102+ _ , err = amp4 .Unmarshal (f , uint64 (moovSize - 8 ), & mvhd , amp4 .Context {})
82103 if err != nil {
83104 return err
84105 }
@@ -90,7 +111,7 @@ func writeDuration(f io.ReadWriteSeeker, d time.Duration) error {
90111 return err
91112 }
92113
93- _ , err = mp4 .Marshal (f , & mvhd , mp4 .Context {})
114+ _ , err = amp4 .Marshal (f , & mvhd , amp4 .Context {})
94115 if err != nil {
95116 return err
96117 }
@@ -102,12 +123,13 @@ type formatFMP4Segment struct {
102123 f * formatFMP4
103124 startDTS time.Duration
104125 startNTP time.Time
126+ number uint64
105127
106- path string
107- fi * os.File
108- curPart * formatFMP4Part
109- endDTS time.Duration
110- nextSequenceNumber uint32
128+ path string
129+ fi * os.File
130+ curPart * formatFMP4Part
131+ endDTS time.Duration
132+ nextPartNumber uint32
111133}
112134
113135func (s * formatFMP4Segment ) initialize () {
@@ -118,7 +140,7 @@ func (s *formatFMP4Segment) close() error {
118140 var err error
119141
120142 if s .curPart != nil {
121- err = s .curPart . close ()
143+ err = s .closeCurPart ()
122144 }
123145
124146 if s .fi != nil {
@@ -144,6 +166,41 @@ func (s *formatFMP4Segment) close() error {
144166 return err
145167}
146168
169+ func (s * formatFMP4Segment ) closeCurPart () error {
170+ if s .fi == nil {
171+ s .path = recordstore.Path {Start : s .startNTP }.Encode (s .f .ri .pathFormat2 )
172+ s .f .ri .Log (logger .Debug , "creating segment %s" , s .path )
173+
174+ err := os .MkdirAll (filepath .Dir (s .path ), 0o755 )
175+ if err != nil {
176+ return err
177+ }
178+
179+ fi , err := os .Create (s .path )
180+ if err != nil {
181+ return err
182+ }
183+
184+ s .f .ri .onSegmentCreate (s .path )
185+
186+ err = writeInit (
187+ fi ,
188+ s .f .ri .streamID ,
189+ s .number ,
190+ s .startDTS ,
191+ s .startNTP ,
192+ s .f .tracks )
193+ if err != nil {
194+ fi .Close ()
195+ return err
196+ }
197+
198+ s .fi = fi
199+ }
200+
201+ return s .curPart .close (s .fi )
202+ }
203+
147204func (s * formatFMP4Segment ) write (track * formatFMP4Track , sample * sample , dts time.Duration ) error {
148205 endDTS := dts + timestampToDuration (int64 (sample .Duration ), int (track .initTrack .TimeScale ))
149206 if endDTS > s .endDTS {
@@ -152,27 +209,29 @@ func (s *formatFMP4Segment) write(track *formatFMP4Track, sample *sample, dts ti
152209
153210 if s .curPart == nil {
154211 s .curPart = & formatFMP4Part {
155- s : s ,
156- sequenceNumber : s .nextSequenceNumber ,
157- startDTS : dts ,
212+ maxPartSize : s .f .ri .maxPartSize ,
213+ segmentStartDTS : s .startDTS ,
214+ number : s .nextPartNumber ,
215+ startDTS : dts ,
158216 }
159217 s .curPart .initialize ()
160- s .nextSequenceNumber ++
218+ s .nextPartNumber ++
161219 } else if s .curPart .duration () >= s .f .ri .partDuration {
162- err := s .curPart . close ()
220+ err := s .closeCurPart ()
163221 s .curPart = nil
164222
165223 if err != nil {
166224 return err
167225 }
168226
169227 s .curPart = & formatFMP4Part {
170- s : s ,
171- sequenceNumber : s .nextSequenceNumber ,
172- startDTS : dts ,
228+ maxPartSize : s .f .ri .maxPartSize ,
229+ segmentStartDTS : s .startDTS ,
230+ number : s .nextPartNumber ,
231+ startDTS : dts ,
173232 }
174233 s .curPart .initialize ()
175- s .nextSequenceNumber ++
234+ s .nextPartNumber ++
176235 }
177236
178237 return s .curPart .write (track , sample , dts )
0 commit comments