@@ -175,17 +175,17 @@ func (w *Channel) resolveSource(body string) (string, string, error) {
175
175
if variant == nil {
176
176
return "" , "" , fmt .Errorf ("no available resolution" )
177
177
}
178
- w .log (logTypeInfo , "resolution %dp is used" , variant .width )
178
+ w .log (LogTypeInfo , "resolution %dp is used" , variant .width )
179
179
180
180
url , ok := variant .framerate [w .Framerate ]
181
181
// If the framerate is not found, fallback to the first found framerate, this block pretends there're only 30 and 60 fps.
182
182
// no complex logic here, im lazy.
183
183
if ok {
184
- w .log (logTypeInfo , "framerate %dfps is used" , w .Framerate )
184
+ w .log (LogTypeInfo , "framerate %dfps is used" , w .Framerate )
185
185
} else {
186
186
for k , v := range variant .framerate {
187
187
url = v
188
- w .log (logTypeWarning , "framerate %dfps not found, fallback to %dfps" , w .Framerate , k )
188
+ w .log (LogTypeWarning , "framerate %dfps not found, fallback to %dfps" , w .Framerate , k )
189
189
w .Framerate = k
190
190
break
191
191
}
@@ -196,66 +196,86 @@ func (w *Channel) resolveSource(body string) (string, string, error) {
196
196
return rootURL , sourceURL , nil
197
197
}
198
198
199
- // mergeSegments is a async function that runs in background for the channel,
200
- // and it merges the segments from buffer to the file.
199
+ // mergeSegments runs in the background and merges segments from the buffer to the file.
201
200
func (w * Channel ) mergeSegments () {
202
201
var segmentRetries int
202
+ startTime := time .Now () // Track the start time of the current segment.
203
203
204
204
for {
205
205
if w .IsPaused || w .isStopped {
206
206
break
207
207
}
208
+
209
+ // Handle segment retries if not found.
208
210
if segmentRetries > 5 {
209
- w .log (logTypeWarning , "segment #%d not found in buffer, skipped" , w .bufferIndex )
211
+ w .log (LogTypeWarning , "segment #%d not found in buffer, skipped" , w .bufferIndex )
210
212
w .bufferIndex ++
211
213
segmentRetries = 0
212
214
continue
213
215
}
216
+
217
+ // If buffer is empty, wait and retry.
214
218
if len (w .buffer ) == 0 {
215
- <- time .After (1 * time .Second )
219
+ time .Sleep (1 * time .Second )
216
220
continue
217
221
}
222
+
223
+ // Retrieve segment from buffer.
218
224
w .bufferLock .Lock ()
219
225
buf , ok := w .buffer [w .bufferIndex ]
220
226
w .bufferLock .Unlock ()
227
+
221
228
if ! ok {
222
229
segmentRetries ++
223
- <- time .After (time .Duration (segmentRetries ) * time .Second )
230
+ time .Sleep (time .Duration (segmentRetries ) * time .Second )
224
231
continue
225
232
}
233
+
234
+ // Write the segment to the file.
226
235
lens , err := w .file .Write (buf )
227
236
if err != nil {
228
- w .log (logTypeError , "segment #%d written error: %v" , w .bufferIndex , err )
237
+ w .log (LogTypeError , "segment #%d written error: %v" , w .bufferIndex , err )
229
238
w .retries ++
230
239
continue
231
240
}
232
- w .log (logTypeInfo , "segment #%d written" , w .bufferIndex )
233
- w .log (logTypeDebug , "duration: %s, size: %s" , DurationStr (w .SegmentDuration ), ByteStr (w .SegmentFilesize ))
234
241
242
+ // Update segment size and log progress.
235
243
w .SegmentFilesize += lens
236
- segmentRetries = 0
244
+ w .log (LogTypeInfo , "segment #%d written" , w .bufferIndex )
245
+ w .log (LogTypeDebug , "duration: %s, size: %s" , DurationStr (w .SegmentDuration ), ByteStr (w .SegmentFilesize ))
237
246
247
+ // Check if the file size limit has been reached.
238
248
if w .SplitFilesize > 0 && w .SegmentFilesize >= w .SplitFilesize * 1024 * 1024 {
239
- w .log (logTypeInfo , "filesize exceeded, creating new file" )
249
+ w .log (LogTypeInfo , "filesize exceeded, creating new file" )
240
250
241
- if err := w .nextFile (); err != nil {
242
- w .log (logTypeError , "next file error: %v" , err )
251
+ if err := w .nextFile (startTime ); err != nil {
252
+ w .log (LogTypeError , "next file error: %v" , err )
243
253
break
244
254
}
245
- } else if w .SplitDuration > 0 && w .SegmentDuration >= w .SplitDuration * 60 {
246
- w .log (logTypeInfo , "duration exceeded, creating new file" )
247
255
248
- if err := w .nextFile (); err != nil {
249
- w .log (logTypeError , "next file error: %v" , err )
256
+ startTime = time .Now () // Reset start time for the new segment.
257
+ }
258
+
259
+ // Check if the duration limit has been reached.
260
+ elapsed := int (time .Since (startTime ).Minutes ())
261
+ if w .SplitDuration > 0 && elapsed >= w .SplitDuration {
262
+ w .log (LogTypeInfo , "duration exceeded, creating new file" )
263
+
264
+ if err := w .nextFile (startTime ); err != nil {
265
+ w .log (LogTypeError , "next file error: %v" , err )
250
266
break
251
267
}
268
+
269
+ startTime = time .Now () // Reset start time for the new segment.
252
270
}
253
271
272
+ // Remove the processed segment from the buffer.
254
273
w .bufferLock .Lock ()
255
274
delete (w .buffer , w .bufferIndex )
256
275
w .bufferLock .Unlock ()
257
276
258
- w .bufferIndex ++
277
+ w .bufferIndex ++ // Move to the next segment.
278
+ segmentRetries = 0 // Reset retries for the next segment.
259
279
}
260
280
}
261
281
@@ -276,15 +296,15 @@ func (w *Channel) fetchSegments() {
276
296
break
277
297
}
278
298
279
- w .log (logTypeError , "segment list error, will try again [%d/10]: %v" , disconnectRetries , err )
299
+ w .log (LogTypeError , "segment list error, will try again [%d/10]: %v" , disconnectRetries , err )
280
300
disconnectRetries ++
281
301
282
302
<- time .After (time .Duration (wait ) * time .Second )
283
303
continue
284
304
}
285
305
286
306
if disconnectRetries > 0 {
287
- w .log (logTypeInfo , "channel is back online!" )
307
+ w .log (LogTypeInfo , "channel is back online!" )
288
308
w .IsOnline = true
289
309
disconnectRetries = 0
290
310
}
@@ -296,7 +316,7 @@ func (w *Channel) fetchSegments() {
296
316
297
317
go func (index int , uri string ) {
298
318
if err := w .requestSegment (uri , index ); err != nil {
299
- w .log (logTypeError , "segment #%d request error, ignored: %v" , index , err )
319
+ w .log (LogTypeError , "segment #%d request error, ignored: %v" , index , err )
300
320
return
301
321
}
302
322
}(w .segmentIndex , v .URI )
@@ -379,7 +399,7 @@ func (w *Channel) requestSegment(url string, index int) error {
379
399
return fmt .Errorf ("read body: %w" , err )
380
400
}
381
401
382
- w .log (logTypeDebug , "segment #%d fetched" , index )
402
+ w .log (LogTypeDebug , "segment #%d fetched" , index )
383
403
384
404
w .bufferLock .Lock ()
385
405
w .buffer [index ] = body
0 commit comments