How HLS & Transcoding Enable Seamless Video Streaming

HLS transcoding turns one source video into several renditions at different resolutions and bitrates, cuts each one into short segments and lists them in M3U8 playlists. The player then picks the rendition that fits your connection for every segment, so the video keeps playing when bandwidth changes.
Updated Nov 5, 2026: rewrote the guide around a real FFmpeg run, current Apple guidance and the HLS spec, transcoding vs transmuxing, MPEG-TS vs fMP4, and the HLS options and prices in the AIOZ Stream docs.
What is HLS transcoding?
HLS (HTTP Live Streaming) is the streaming protocol Apple created and later published as RFC 8216, an informational RFC from August 2017. It delivers video as many small files over ordinary HTTP, so any web server or CDN can carry it. A player downloads a playlist, then fetches the segments it lists, one after another.
Transcoding means decoding a video and encoding it again with different settings. In an HLS workflow the word usually covers three jobs that run back to back:
- Encode a bitrate ladder: several versions of the same video, called renditions, each with its own resolution and bitrate.
- Cut every rendition into segments a few seconds long.
- Write one M3U8 playlist per rendition, plus a top-level playlist that lists all of them.
The last two steps are often called packaging. If you want to see where HLS sits next to DASH, WebRTC, RTMP and SRT, our guide to video streaming protocols compares them side by side.
We ran the whole process on a 30-second 1080p clip with FFmpeg 7.0.2 on Nov 5, 2026. This is the exact command we used, and the playlists further down are its unedited output:
ffmpeg -i clip.mp4 \
-filter_complex "[0:v]split=3[v1][v2][v3];[v1]scale=-2:360[o1];[v2]scale=-2:720[o2];[v3]scale=-2:1080[o3]" \
-map "[o1]" -map 0:a -map "[o2]" -map 0:a -map "[o3]" -map 0:a \
-c:v libx264 -preset veryfast -profile:v high -g 60 -keyint_min 60 -sc_threshold 0 \
-b:v:0 800k -maxrate:v:0 856k -bufsize:v:0 1200k \
-b:v:1 2500k -maxrate:v:1 2675k -bufsize:v:1 3750k \
-b:v:2 5000k -maxrate:v:2 5350k -bufsize:v:2 7500k \
-c:a aac -b:a 128k -ac 2 \
-f hls -hls_time 6 -hls_playlist_type vod -hls_segment_type mpegts \
-hls_segment_filename "ts/%v/seg_%03d.ts" -master_pl_name master.m3u8 \
-var_stream_map "v:0,a:0,name:360p v:1,a:1,name:720p v:2,a:2,name:1080p" \
"ts/%v/index.m3u8"The bitrate ladder: one rendition for each kind of connection
A bitrate ladder is the list of renditions you produce, and each rung trades picture size against the bandwidth it needs. Our test ladder had three rungs: 640x360 at 800 kbps, 1280x720 at 2.5 Mbps and 1920x1080 at 5 Mbps, all H.264 video with 128 kbps AAC audio.
Two details matter more than the exact numbers. First, every rendition needs keyframes at the same moments, because a player can only switch where the next segment starts with a full picture. Apple's HLS authoring specification asks for a keyframe every two seconds and says video segments must start with one. We forced that with a fixed 60-frame keyframe interval at 30 fps.
Second, the bitrates are only targets, so a simple clip can come in well under them. Ours is mostly flat motion graphics, and its segment files averaged about 390 kbps, 890 kbps and 1.37 Mbps, transport stream overhead included. Busier footage, such as sports, needs much more of each budget. Our guide on how to build a video bitrate ladder covers picking the rungs for your own content.
How do segments and M3U8 playlists work?
Segment length is a trade-off, because short segments let a player start sooner and react faster, while long segments mean fewer files and fewer HTTP requests. Apple's current spec says target durations should be 6 seconds, and that is what we used.
The run produced five 6-second segments per rendition and two kinds of playlist. The top-level file used to be called the master playlist, and the draft second edition of the HLS spec renames it the multivariant playlist. Here is the one FFmpeg wrote:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=1020800,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2"
360p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2890800,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
720p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5640800,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
1080p/index.m3u8Each EXT-X-STREAM-INF line describes one rendition, where BANDWIDTH is the peak bitrate in bits per second, RESOLUTION is the frame size and CODECS names the codecs. For example, avc1.64001f is H.264 High profile at level 3.1, and mp4a.40.2 is AAC-LC audio. The player reads these values before it downloads any video.
Each rendition then has its own media playlist, and this is the 720p one:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:6.000000,
seg_000.ts
#EXTINF:6.000000,
seg_001.ts
#EXTINF:6.000000,
seg_002.ts
#EXTINF:6.000000,
seg_003.ts
#EXTINF:6.000000,
seg_004.ts
#EXT-X-ENDLISTEXT-X-TARGETDURATION is the longest segment length rounded to a whole second, and EXTINF gives each segment's exact duration. EXT-X-ENDLIST tells the player that no more segments will come, which marks a finished video rather than a live stream. For a closer look at every tag, see our explainer on how M3U8 files and HLS video segmentation work.
MPEG-TS or fMP4 segments?
HLS segments come in two containers, and MPEG transport stream (.ts) is the original one that works wherever HLS does. Fragmented MP4 (fMP4) is newer and adds a small initialization segment, which the playlist points to with EXT-X-MAP. When we reran the 720p rendition as fMP4, FFmpeg wrote an init.mp4 file, five .m4s segments and a playlist with EXT-X-VERSION:7.
The codec often decides for you, since Apple's spec allows H.264 in either container but requires fMP4 for HEVC (H.265) and AV1. MPEG-DASH uses fMP4 segments too, so one set of files can serve both protocols. Our guide to video encoding explains how codecs and containers fit together.
Adaptive bitrate switching: how the player uses the ladder
Adaptive bitrate (ABR) streaming is the reason you transcode into a ladder at all. The player loads the multivariant playlist, chooses a starting rendition, and then keeps measuring download speed and how much video sits in its buffer. Before each new segment, it can stay on its rung or move up or down.
RFC 8216 leaves the switching algorithm to each player, but it sets rules for the server. Every rendition must show the same content with matching timestamps and the same target duration. That alignment lets a player swap a 720p segment for a 360p one without a visible jump. The AIOZ Stream adaptive streaming docs give a typical case: a viewer at 720p drops to 480p when bandwidth falls near 1.2 Mbps, then climbs back as the buffer recovers.

Our guide to adaptive bitrate streaming covers the algorithms players use to make that choice, from throughput-based to buffer-based.
Transcoding vs transmuxing: what is the difference?
Transmuxing, short for transmultiplexing, repackages video into a new container without touching the encoded frames, while transcoding decodes the frames and encodes them again. The first is close to a file copy and the second is real computation, as our test showed:
- Transcoding the 30-second clip into three renditions took 5.7 seconds on our 16-core test machine.
- Transmuxing the same clip into HLS with FFmpeg's copy mode (
-c copy) took 0.03 seconds.
The playlist showed the trade-off, because transmuxing cannot add keyframes and FFmpeg could only cut where the source already had them. Our source had one keyframe every 8.3 seconds, so the segments came out at 8.3 seconds instead of 6, with a target duration of 8. It also produced a single rendition, because there is no ladder without re-encoding.
So transmux when your source already uses a codec players support, has regular keyframes and comes as a ladder you are happy with. Transcode when you need new renditions, a different codec or aligned keyframes. AIOZ Stream covers the first case with HLS import, and our guide to importing an M3U8 video without re-encoding walks through it.
Costs and latency of HLS transcoding
Transcoding cost grows with three things: minutes of video, the number of renditions and their resolution. A 4K frame has 36 times the pixels of a 360p frame, so a 4K rung needs far more compute. More renditions also mean more files to store, and every segment a viewer downloads counts toward delivery. AIOZ Stream, for example, bills transcoding by the minute and delivery by the gigabyte.
For video on demand, transcoding happens once after upload, so the only delay is the wait before the video is ready to play. For live video, the encoder must keep up in real time for every rung, or the stream falls behind.
Segment length also sets a floor on live delay. RFC 8216 says a player should not start a live stream at a segment that begins less than three target durations from the end of the playlist. With 6-second segments, that start point sits at least 18 seconds behind the end of the playlist. Shorter segments, or Low-Latency HLS with its partial segments, bring that down.
How AIOZ Stream handles HLS transcoding
On AIOZ Stream you upload a source file and the service transcodes it for you. With the Video API, you create a video object (the request must include "type": "video"), upload the file, and can pass a qualities array that defines each rendition. If you leave out the encoding settings, the server applies its defaults, and each quality object has these documented fields:
resolution: 240p, 360p, 480p, 720p, 1080p, 1440p, 2160p or 4320p. A rung above the source resolution is ignored.type:hlsordash.container_type:mpegtsormp4for HLS, andfmp4for DASH.video_config: codech264(up to 4K) orh265(up to 8K), plus a target bitrate. Each resolution has a documented maximum, for example 4 Mbps at 720p and 6 Mbps at 1080p.audio_config: AAC only, with bitrate, channels, sample rate and language.
The docs repeat Apple's rule that HEVC in HLS plays on Apple devices only in fMP4 segments. So if you choose h265 for HLS, pick the mp4 container rather than mpegts. When the video status moves from transcoding to done, the response lists an hls_url such as https://api.aiozstream.network/api/media/{id}/m3u8, plus a DASH manifest URL and player embed links.
For live streams, you pass a similar qualities array when you create a session through the live streaming API, and the session returns an hls_url for playback. If your videos already exist as HLS, the M3U8 import copies a finished master playlist and its segments as they are, without re-encoding.
What HLS transcoding costs on AIOZ Stream
As of November 2026, the AIOZ Stream payment docs price video transcoding per minute of video transcoded:
- Up to HD: $0.01 per minute.
- 2K: $0.02 per minute.
- 4K: $0.05 per minute.
Storage costs $0.02 per GB per month and delivery costs $0.02 per GB. You pay from a wallet funded with AIOZ tokens, credited at the AIOZ/USDT rate at the time of deposit, and usage is billed hourly. To price a ladder before you upload, the API's cost endpoint takes the video's duration and its list of qualities and returns an estimate in USD.
Frequently asked questions
What is HLS transcoding?
It is the process of re-encoding one source video into several renditions, cutting them into segments and writing M3U8 playlists. An HLS player can then switch quality as your bandwidth changes.
What segment length should I use for HLS?
Apple's authoring spec says target durations should be 6 seconds, with a keyframe every 2 seconds. Go shorter only if you need lower live latency and can handle more HTTP requests.
Is HLS a codec?
No, HLS is a delivery protocol. The video inside the segments uses a codec such as H.264, HEVC or AV1, and the audio uses a codec such as AAC.
What is the difference between transcoding and transmuxing?
Transcoding re-encodes the frames and can change resolution, bitrate or codec. Transmuxing only moves the same frames into a new container. It is much faster, but it keeps the source's keyframes and quality.
Should I use MPEG-TS or fMP4 segments?
MPEG-TS gives the widest support for H.264. Use fMP4 for HEVC or AV1, which Apple requires, or when you want the same files to serve both HLS and DASH.
How much does HLS transcoding cost on AIOZ Stream?
As of November 2026, the docs list $0.01 per minute up to HD, $0.02 per minute for 2K and $0.05 per minute for 4K. Storage and delivery are billed separately at $0.02 per GB.
Can AIOZ Stream import a video that is already in HLS?
Yes. Send the URL of a finished, unencrypted HLS master playlist, and AIOZ Stream copies its renditions and segments without re-encoding them.
Related Reading
- AIOZ DePIN 4.0: Transcoding for Video on Demand and Streaming
- Essential Components of VOD Streaming Infrastructure
- Exploring the VOD Streaming Models
- The Rise of Web3 Video Streaming
- The Key Elements of Web3 Streaming Technology
- AIOZ Stream Launch: Peer-to-Peer Live & On-Demand Streaming, Empowered by AIOZ DePIN
- Video streaming glossary: codecs, protocols and delivery terms
- What Low-Latency HLS (LL-HLS) is and when to use it
About the AIOZ Network
AIOZ Network is a DePIN for AIOZ AI, AIOZ Storage, and AIOZ Stream.
AIOZ empowers a fast, secure, and decentralized future.
Powered by a global community of AIOZ DePIN, AIOZ rewards you for sharing your computational resources for storing, transcoding, and streaming digital media content and powering decentralized AI computation.
Find Us
AIOZ All Links | Website | Twitter | Telegram