Jump to content

HLS segment list is computed from the container's declared duration and is never checked against the media.


Recommended Posts

vdatanet
Posted

Emby Server 4.9.5.0 (Linux, .NET 8).

The claim: the HLS segment list is computed from the container's declared duration and is never checked against the media. For any file whose declared duration runs past its last frame, the list therefore always contains one trailing segment that cannot be produced.

It reproduces in one request

No playback, no transcoding session to watch, no waiting for the end of a file — just fetch the variant playlist and count:

curl -s "<server>/emby/videos/<id>/main.m3u8?<params>" | grep -c '#EXTINF'

curl -s "<server>/emby/videos/<id>/main.m3u8?<params>" \
  | grep -o '#EXTINF:[0-9.]*' | cut -d: -f2 | awk '{s+=$1} END {print s}'

For a 22-minute MKV here (RunTimeTicks 13263360000 = 1326.336 s), 6-second segments:

Segments in the list 222 (0–221)
Distinct #EXTINF values one  6.0000, all 222 times
Sum of declared durations 1332.000 s
Declared container duration 1326.336 s
End of the written media 1325.365 s

That last figure is the server's own, from SegmentComplete=video:0 Index=220 Start=0.000000 End=1325.365000. So the playlist advertises 6.635 s of video that does not exist, and the trailing segment is declared 6.0000 rather than the 0.336 s it would nominally cover. #EXT-X-TARGETDURATION is 7 while every segment says 6.

What follows from it

When a client asks for that trailing segment, ffmpeg is started with -ss 00:22:06.000, which is past the last frame. What happens next depends on the path:

  • Copy / remux (-c:v copy -c:a copy😞 ffmpeg exits 0 having written nothing, and the request is answered 500. Clients retry indefinitely; each retry starts a new ffmpeg process.
  • Transcode (hevc_vaapi😞 the encoder gets no frames and segfaults  Process exited with code 139 - Failed. The request is never answered at all; the connection is held open until the client disconnects.

Either way the stream never terminates, so no client on the HLS path ever reaches end-of-stream. Direct play is unaffected, because it never reads the segment list.

Why this is posted here

This is not a configuration issue and it does not depend on the client. The symptom side — sessions stuck on the dashboard, next episode not starting — is already reported at 145772, with the playback-side measurements. This post is only about the arithmetic that builds the list.

Deriving the segment count and the final #EXTINF from the actual end of the media rather than from RunTimeTicks would remove the phantom segment, and would also make the last segment's declared duration honest. Happy to provide the full playlist, the server log or the sample file.

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...