Latency is the time lag between when something is recorded in real life and when it is seen in a video player. There is, of course, some real time required to transmit a signal from the source through the internet to a viewer's player. Latency is aggravated by the fact that online video is transmitted in discrete chunks, called segments.
Latency can be reduced by shortening the length of the video segments, and the following sections will detail how you can do this in NextGen Live.
Be aware that there is a tradeoff when reducing segment duration: to ensure uninterrupted playback, the player downloads a few video segments ahead of the current playback position (this is called buffering), so that they are ready when needed.
If you shorten the length of segments, keep the following in mind:
In NextGen Live, latency reduction is achieved by configuring the segment_duration_seconds
parameter within the manifest configuration when creating a live channel via the Live API or by creating a custom ingest profile.
To create NextGen Live channels with reduced latency, you need to create a custom ingest profile that includes the manifest configuration with reduced segment duration. This profile can then be used when creating live events or channels.
Create a custom ingest profile with the manifest block configured for reduced latency:
{
"model_version": 2,
"name": "Low Latency NextGen Live Profile",
"description": "Custom profile for reduced latency NextGen Live streams with 2-second segments",
"account_id": "your_account_id",
"renditions": [
{
"media_type": "video",
"label": "hls360p",
"video_codec": "h264",
"video_bitrate": 780,
"decoder_bitrate_cap": 936,
"decoder_buffer_size": 1170,
"frame_rate": 30,
"keyframe_rate": 0.5,
"width": 640,
"height": 360,
"video_bframes": 3,
"sample_aspect_ratio": "1:1",
"deinterlace": "detect",
"video_codec_profile": "main",
"video_codec_level": "3",
"video_reference_frames": 4,
"allowed_frame_rates": [
{
"as_float": 23.97,
"as_fraction": "24000/1001"
},
{
"as_float": 24,
"as_fraction": "24/1"
},
{
"as_float": 25,
"as_fraction": "25/1"
},
{
"as_float": 29.97,
"as_fraction": "30000/1001"
},
{
"as_float": 30,
"as_fraction": "30/1"
}
]
},
{
"media_type": "video",
"label": "hls540p",
"video_codec": "h264",
"video_bitrate": 1500,
"decoder_bitrate_cap": 1800,
"decoder_buffer_size": 2250,
"frame_rate": 30,
"keyframe_rate": 0.5,
"width": 960,
"height": 540,
"video_bframes": 3,
"sample_aspect_ratio": "1:1",
"deinterlace": "detect",
"video_codec_profile": "main",
"video_codec_level": "3.2",
"video_reference_frames": 4,
"allowed_frame_rates": [
{
"as_float": 23.97,
"as_fraction": "24000/1001"
},
{
"as_float": 24,
"as_fraction": "24/1"
},
{
"as_float": 25,
"as_fraction": "25/1"
},
{
"as_float": 29.97,
"as_fraction": "30000/1001"
},
{
"as_float": 30,
"as_fraction": "30/1"
}
]
},
{
"media_type": "video",
"label": "hls720p",
"video_codec": "h264",
"video_bitrate": 2400,
"decoder_bitrate_cap": 2880,
"decoder_buffer_size": 3600,
"frame_rate": 30,
"keyframe_rate": 0.5,
"width": 1280,
"height": 720,
"video_bframes": 3,
"sample_aspect_ratio": "1:1",
"deinterlace": "detect",
"video_codec_profile": "high",
"video_codec_level": "4",
"video_reference_frames": 4,
"allowed_frame_rates": [
{
"as_float": 23.97,
"as_fraction": "24000/1001"
},
{
"as_float": 24,
"as_fraction": "24/1"
},
{
"as_float": 25,
"as_fraction": "25/1"
},
{
"as_float": 29.97,
"as_fraction": "30000/1001"
},
{
"as_float": 30,
"as_fraction": "30/1"
}
]
},
{
"media_type": "video",
"label": "hls1080p",
"video_codec": "h264",
"video_bitrate": 4500,
"decoder_bitrate_cap": 5400,
"decoder_buffer_size": 6750,
"frame_rate": 30,
"keyframe_rate": 0.5,
"width": 1920,
"height": 1080,
"video_bframes": 3,
"sample_aspect_ratio": "1:1",
"deinterlace": "detect",
"video_codec_profile": "high",
"video_codec_level": "4.2",
"video_reference_frames": 4,
"allowed_frame_rates": [
{
"as_float": 23.97,
"as_fraction": "24000/1001"
},
{
"as_float": 24,
"as_fraction": "24/1"
},
{
"as_float": 25,
"as_fraction": "25/1"
},
{
"as_float": 29.97,
"as_fraction": "30000/1001"
},
{
"as_float": 30,
"as_fraction": "30/1"
}
]
}
],
"packages": [],
"manifest": {
"name": "playlist",
"segment_duration_seconds": 2,
"hls": {}
},
"profile_type": "live"
}
Parameter | Description | Notes |
---|---|---|
model_version |
Profile model version | Use 2 for NextGen Live profiles |
keyframe_rate |
Keyframes per second (fractional value) | 0.5 = 1 keyframe every 2 seconds |
segment_duration_seconds |
Length of each video segment in seconds | 2 for reduced latency, 6 for standard |
profile_type |
Type of profile | Must be "live" for live streaming profiles |
Follow these steps to create a custom ingest profile with reduced latency:
manifest
block with segment_duration_seconds: 2
as shown in the example aboveOnce you've created the custom ingest profile, you can use it when creating live events or channels, similar to how you would use any other ingest profile.
If you want reduced latency, and you use the Live API to create your live jobs, just create the channel as you normally do, and set segment_duration_seconds
inside the manifest block to 2:
{
"manifest": {
"name": "playlist",
"segment_duration_seconds": 2,
"hls": {}
}
}
When using reduced segment duration, your encoder settings become more critical for maintaining stream stability.