Vinny Glennon
Vinny Glennon

Reputation: 149

HLS on nginx, not stopping as expected

Using https://gist.github.com/45sound/bd2a5ee699e428d63bcd as http://54.204.158.100/1.m3u8 (you also can download it directly)

http://54.204.158.100/hls/clock.mp4 is the source mp4.

http://54.204.158.100/hls/clock.mp4.ts?start=0.0&end=4.99 is the segment to play.

In the osmfhls.kutu.ru player, this plays for 6.99 seconds instead of 4.99.

Why is this?

Upvotes: 0

Views: 743

Answers (1)

aergistal
aergistal

Reputation: 31209

Your Nginx HLS module is configured to server 7s fragments. The actual duration is 7.180s:

curl "http://<ip_address>/hls/clock.mp4.m3u8"

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:7
#EXT-X-PLAYLIST-TYPE:VOD

#EXTINF:7.200,
clock.mp4.ts?start=0.000&end=7.200
#EXTINF:7.200,
clock.mp4.ts?start=7.200&end=14.400
#EXTINF:5.400,
clock.mp4.ts?start=14.400&end=19.800
...

In the case of http://<ip_address>/hls/clock.mp4.ts?start=0.0&end=4.99 request, if the player ignores the query string after the .ts then it will play just the first segment for a total duration of 7.180s as configured in the module. Check the Nginx access.log to see what it requested.

Update

After checking the specs of the mp4 file I noticed you use a GOP size of 60 at a frame rate of 25. This means 1 keyframe every 60 / 25 = 2.4 seconds. When you pass the URL with the start and end query string to Nginx it apparently tries to return the full portion between two keyframes and it doesn't cut on the exact timestamp.

In case of start = 1.0 and end = 2.2 this doesn't work because the first full interval is between 0.0 and 2.4. For start = 0 and end = 4.99 it will play from 0.0 to 7.2 since 2.4 x 2 = 4.8 which is smaller than 4.99.

The documentation doesn't say if this is the desired behavior. In general, to avoid issues, you have to set a target duration equal to a multiple of your keyframe interval.

Upvotes: 1

Related Questions