Jump to content

HLS fMP4 remux restarts ffmpeg on every segment after a mid-file start (segmentGap ignores -start_number)


Recommended Posts

yoyoyopop40
Posted

Server: Emby Server 4.10.2.0, Linux x86_64 (Docker)
Client: third-party Apple client using AVPlayer (AppleCoreMedia), videos/{id}/master.m3u8 with video stream copy, SegmentLength=2, fMP4 segments (hls1/main/N.m4s).

Summary

When playback starts mid-file (StartTimeTicks on master.m3u8), the server correctly starts ffmpeg with -ss <start> -start_number <N>. Sometimes, after the job has served 2–5 strictly sequential segments, the next sequential request is treated as a large seek:

GET .../hls1/main/2400.m4s   Starting transcoding because currentTranscodingIndex=null
GET .../hls1/main/2401.m4s   (served by the running job)
GET .../hls1/main/2402.m4s   (served by the running job)
GET .../hls1/main/2403.m4s   Starting transcoding because segmentGap is 2399 and max allowed gap is 12. requestedIndex=2403
                             Stopping ffmpeg process with q command ... _2400.m4s
                             Execute: ffmpeg ... -ss 01:20:06.000 ... -start_number 2403 ...
GET .../hls1/main/2404.m4s   Starting transcoding because segmentGap is 2402 and max allowed gap is 12. requestedIndex=2404
GET .../hls1/main/2405.m4s   Starting transcoding because segmentGap is 2403 and max allowed gap is 12. requestedIndex=2405
... (repeats for every following segment)

The reported gap is always about requestedIndex − (segments written by this job). So the server's current transcoding index looks as if it is counted from 0 rather than from the job's -start_number. Once that happens, every later segment restarts ffmpeg, so the server never recovers for the rest of the session. On the client this shows up as audio dropouts and resyncs, about one per segment.

Reproduction

  1. Pick a long MKV that is remuxed with video copy into fMP4 HLS.
  2. Request master.m3u8 with StartTimeTicks 10–80 minutes into the file, then play the media playlist sequentially from the segment covering that position. The client never requests out of order and never skips segments.
  3. Watch the server log for segmentGap is ... requestedIndex=... on sequential requests.

In an automated soak, 20 mid-file starts at positions from 10 to 80 minutes (StartTimeTicks 600–4800 s) on one file, with one client, gave:

  • 11 runs: one ffmpeg start per position, served sequentially (expected).
  • 5 runs: one to three isolated segmentGap restarts, after which the new job kept up.
  • 4 runs: the restart loop above, beginning 2–5 segments after the start (12–31 ffmpeg starts within about 40 s).

The same start position can behave either way across runs (for example 4800 s was clean once and looped once), so it is not tied to a particular keyframe or position. It also happened on the first mid-file start after a fresh client launch, so an earlier seek job is not required.

Relevant ffmpeg arguments (from the server log, identical in good and bad runs)

-copyts -start_at_zero -f matroska,webm -ss 01:20:00.000 -max_delay 5000000
-avoid_negative_ts disabled -f hls -start_number 2400 -hls_time 00:00:02.000
-hls_list_size 0 -hls_segment_type fmp4 -hls_flags +temp_file -hls_playlist_type vod

Expected

Sequential requests N+1, N+2, … after a job started at -start_number N should be served by that job, and the gap should be measured from the job's actual latest segment index.

I can provide redacted full server logs for the good and bad runs if useful.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...