Bir web sitesinde, akıllı telefonda veya akıllı TV'de izlediğiniz canlı yayınların çok büyük kısmı arka planda HLS ile taşınır. HLS (HTTP Live Streaming), Apple tarafından geliştirilen ve görüntüyü küçük dosya parçalarına bölerek sıradan bir web sunucusu üzerinden dağıtan bir yayın yöntemidir. Bu yüzden CDN'lerle kolay ölçeklenir, güvenlik duvarlarına takılmaz ve tarayıcıda eklentisiz oynatılabilir.
Bu yazıda HLS'in nasıl çalıştığını, .m3u8 dosyasının içinde ne olduğunu, uyarlanabilir bit hızının (ABR) mantığını, Low-Latency HLS'i, fMP4/CMAF parçalarını, tarayıcı desteğini ve DVR penceresini birincil kaynaklara (RFC 8216, IETF taslağı ve Apple belgeleri) dayanarak anlatıyoruz. Son bölümde HLS'i kısaca MPEG-DASH ile karşılaştırıyoruz.
HLS nasıl çalışır?

HLS'in temel fikri basittir: canlı görüntü birkaç saniyelik parçalara (segment) bölünür, bu parçaların listesi bir metin dosyasında (playlist) tutulur, oynatıcı da bu listeyi düzenli aralıklarla yeniden indirip yeni parçaları sırayla oynatır. Her şey sıradan HTTP istekleriyle yapılır.
- Kodlayıcı (OBS, vMix, donanım encoder) görüntüyü genellikle RTMP veya SRT ile yayın sunucusuna gönderir.
- Yayın sunucusu gelen görüntüyü segmentlere böler, gerekirse farklı kalitelere dönüştürür (transcode) ve playlist dosyalarını günceller.
- Web sunucusu veya CDN .m3u8 ve segment dosyalarını izleyicilere dağıtır.
- Oynatıcı (Safari, hls.js, video.js vb.) playlist'i okuyup segmentleri indirir ve oynatır.
HLS, Ağustos 2017'de RFC 8216 olarak yayımlandı. RFC'nin kendisinde belirtildiği gibi bu belge bir İnternet standardı değil, bilgilendirme amaçlı (Informational) bir belgedir; yazarları R. Pantos (Apple) ve W. May'dir. Güncellenmiş ikinci sürüm ise IETF'te draft-pantos-hls-rfc8216bis adıyla taslak olarak sürdürülüyor; Ekim 2026 itibarıyla en son sürüm -22'dir (1 Mayıs 2026). Low-Latency HLS etiketleri bu taslakta tanımlıdır.
.m3u8 dosyası: master ve media playlist
HLS'te iki tür playlist vardır. Master (multivariant) playlist, aynı yayının farklı kalitelerini (variant) listeler. Media playlist ise tek bir kalitenin segmentlerini sıralar. Oynatıcı önce master playlist'i açar, bağlantı hızına uygun kaliteyi seçer, sonra o kalitenin media playlist'ini izler.
Master playlist örneği
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=3300000,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
720p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=6500000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
1080p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=900000,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2"
360p/index.m3u8RFC 8216'ya göre her EXT-X-STREAM-INF etiketi BANDWIDTH özniteliğini içermek zorundadır; CODECS özniteliğinin bulunması gerekir (SHOULD), RESOLUTION ise isteğe bağlıdır ama video içeren varyantlarda önerilir. Apple'ın HLS Authoring Specification belgesi daha katıdır: Apple cihazları için CODECS özniteliği her zaman verilmelidir (MUST).
Media playlist örneği (canlı yayın)
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:2680
#EXTINF:6.000,
segment2680.ts
#EXTINF:6.000,
segment2681.ts
#EXTINF:6.000,
segment2682.ts| Etiket | RFC 8216'daki anlamı |
|---|---|
EXT-X-TARGETDURATION | Bir segmentin en fazla kaç saniye olabileceği. |
EXT-X-MEDIA-SEQUENCE | Listede görünen ilk segmentin sıra numarası. Canlı yayında eski segmentler düştükçe artar. |
EXTINF | Hemen altındaki segmentin süresi. |
EXT-X-PLAYLIST-TYPE | EVENT: segmentler yalnızca sona eklenebilir. VOD: liste hiç değişmez. |
EXT-X-ENDLIST | Listeye artık segment eklenmeyeceğini, yayının bittiğini gösterir. |
Variant ve ABR: neden birden fazla kalite?

İzleyicilerin bağlantı hızı birbirinden çok farklıdır: fiber bağlantıdaki biri 1080p'yi rahatça izlerken mobil veride olan biri 360p'de bile takılabilir. HLS bu sorunu ABR (Adaptive Bitrate, uyarlanabilir bit hızı) ile çözer: oynatıcı her segmenti indirirken hızı ölçer ve gerekirse bir sonraki segmenti başka bir varyanttan ister. Bunun sorunsuz olması için tüm varyantların segment sınırlarının aynı zamana denk gelmesi gerekir; Apple belgesi her video segmentinin bir IDR (anahtar kare) ile başlaması gerektiğini söyler.
Apple'ın HLS Authoring Specification belgesi H.264 için "olası bir varyant seti" olarak şu 16:9 tabloyu veriyor (kbit/s). Bu bir zorunluluk değil, örnek bir merdivendir (bitrate ladder):
| Çözünürlük | Bitrate (kbit/s) | Kare hızı |
|---|---|---|
| 416 x 234 | 145 | 30 fps ve altı |
| 640 x 360 | 365 | 30 fps ve altı |
| 768 x 432 | 730 | 30 fps ve altı |
| 768 x 432 | 1100 | 30 fps ve altı |
| 960 x 540 | 2000 | Kaynakla aynı |
| 1280 x 720 | 3000 | Kaynakla aynı |
| 1280 x 720 | 4500 | Kaynakla aynı |
| 1920 x 1080 | 6000 | Kaynakla aynı |
| 1920 x 1080 | 7800 | Kaynakla aynı |
Aynı belge Apple cihazları için birden çok bitrate (varyant) sunulmasını zorunlu tutuyor, hedef segment süresinin 6 saniye olmasını ve anahtar karelerin (IDR) iki saniyede bir bulunmasını öneriyor. Kodlayıcı tarafında bu ayarların nasıl yapıldığını bitrate ve çözünürlük ayarları yazımızda anlattık.
Segment formatları: MPEG-TS, fMP4 ve CMAF
RFC 8216 dört segment biçimi tanımlar: MPEG-2 Transport Stream (.ts), Fragmented MPEG-4 (fMP4), Packed Audio ve altyazı için WebVTT. Uzun yıllar .ts parçaları standarttı; bugün fMP4 giderek yaygınlaşıyor.
- Apple belgesine göre H.264 video için kapsayıcı fMP4 veya MPEG-TS olabilir; HEVC ve AV1 video için fMP4 zorunludur.
- fMP4 kullanılıyorsa playlist'te başlatma bölümünü gösteren
EXT-X-MAPetiketi bulunmalıdır. - CMAF (Common Media Application Format), fMP4 tabanlı ortak bir paketleme biçimidir. Aynı fMP4 segmentlerini hem HLS hem DASH ile sunabilmeyi kolaylaştırdığı için tercih edilir. hls.js, CMAF dahil fMP4 segmentlerini yeniden paketlemeden doğrudan tarayıcıya aktarabildiğini belirtiyor.
Low-Latency HLS (LL-HLS)
Klasik HLS'te gecikme, segment süresi ve oynatıcının canlı uçtan geride durması nedeniyle yüksektir: hedef süre 6 saniyeyse ve oynatıcı birkaç segment geride başlıyorsa, izleyici olayı yayından epey sonra görür. Apple bu sorunu çözmek için Low-Latency HLS'i geliştirdi; ilgili etiketler rfc8216bis taslağında tanımlanmıştır.
| LL-HLS özelliği | Ne işe yarar |
|---|---|
EXT-X-PART (Partial Segment) | Segment tamamlanmadan önce onun küçük parçalarının yayınlanmasını sağlar. |
EXT-X-PART-INF | Kısmi segmentlerin hedef süresini (PART-TARGET) bildirir; EXT-X-PART kullanılıyorsa zorunludur. |
EXT-X-PRELOAD-HINT | Oynatıcıya bir sonraki parçanın adresini önceden bildirir; böylece istek erken açılır. |
| Blocking Playlist Reload | Oynatıcı _HLS_msn (ve isteğe bağlı _HLS_part) ile istediği segment hazır olana kadar sunucunun cevabı bekletmesini ister; boşuna tekrar tekrar sorgu yapılmaz. |
| Playlist Delta Updates | _HLS_skip=YES ile eski segmentleri atlayan kısa bir liste istenir (EXT-X-SKIP). |
EXT-X-RENDITION-REPORT | Diğer kalitelerin en güncel durumunu bildirir, kalite geçişini hızlandırır. |
EXT-X-SERVER-CONTROL | Sunucunun desteklediği özellikleri (CAN-BLOCK-RELOAD, CAN-SKIP-UNTIL) ve oynatıcının canlı uçtan ne kadar geride durması gerektiğini (HOLD-BACK, PART-HOLD-BACK) bildirir. |
Taslağa göre HOLD-BACK en az hedef sürenin üç katı olmalı; PART-HOLD-BACK en az kısmi segment hedef süresinin iki katı olmalı, üç katı olması önerilir. Bu kurallar, gecikmenin neden sıfıra inemediğini de açıklar: oynatıcı belirli bir güvenlik payıyla canlı uçtan geride durur. Gecikmeyi düşürmenin pratik yollarını canlı yayın gecikmesi yazımızda ele aldık.
Tarayıcı desteği: Safari yerel, diğerleri hls.js ile
Safari (macOS, iOS, iPadOS) HLS'i yerleşik olarak oynatır; <video> etiketine .m3u8 adresini vermeniz yeterlidir. Chrome, Firefox ve Edge gibi tarayıcılarda ise yaygın yöntem, hls.js gibi bir JavaScript kütüphanesi kullanmaktır. hls.js, HTML5 video ve Media Source Extensions (MSE) üzerine kuruludur; MSE'nin olmadığı iOS 17.1 ve sonrası Safari'de Managed Media Source kullanır.
hls.js belgesi önemli bir uyarı yapıyor: canPlayType('application/vnd.apple.mpegurl') bazı tarayıcılarda boş olmayan bir değer döndürse bile bu, oynatmanın gerçekten çalışacağını garanti etmez. Bu yüzden belge, yerel oynatmaya özel bir ihtiyacınız yoksa önce Hls.isSupported() ile kontrol etmenizi öneriyor. Adım adım kurulum için web sitesine canlı yayın ekleme (hls.js) yazımıza bakın.
<video id="tv" controls playsinline></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<script>
var video = document.getElementById('tv');
var src = 'https://yayin.ornek.com/live/kanal/index.m3u8';
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(src);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = src;
}
</script>DVR penceresi: canlı yayını geri sarmak

DVR, izleyicinin canlı yayında geriye sarabilmesidir. HLS'te bu, media playlist'te ne kadar eski segment tutulduğuyla belirlenir. Sunucu yeni segment ekledikçe eskilerini listeden çıkarır (kayan pencere). Liste ne kadar uzunsa izleyici o kadar geri sarabilir.
- RFC 8216'ya göre sunucu, EXT-X-ENDLIST içermeyen bir listeden, süresi hedef sürenin üç katından kısa bir liste oluşacaksa segment çıkaramaz.
- Listeden çıkarılan segment de bir süre daha erişilebilir kalmalıdır; böylece listeyi biraz önce indirmiş oynatıcılar hata almaz.
- Apple belgesi canlı (linear) bir playlist'te en az altı segment bulunmasını zorunlu tutuyor ve en az 15 dakikalık içerik sunulmasını öneriyor.
- Yayın baştan sona geri sarılabilir olsun istiyorsanız
EXT-X-PLAYLIST-TYPE:EVENTkullanılır; segmentler yalnızca eklenir, silinmez.
hls.js, canlı yayınlarda DVR desteğini özellikleri arasında sayıyor. Uzun DVR penceresi daha fazla depolama ve daha büyük playlist demektir; Apple belgesi iki dakikadan uzun pencerelerde playlist delta güncellemelerinin sunulmasını öneriyor.
HLS ve MPEG-DASH karşılaştırması
MPEG-DASH, HLS'e benzer şekilde HTTP üzerinden segment tabanlı çalışan uluslararası bir standarttır (ISO/IEC 23009-1). Manifest dosyası .m3u8 yerine XML tabanlı .mpd'dir. Kısaca farklar:
| Özellik | HLS | MPEG-DASH |
|---|---|---|
| Manifest | .m3u8 (metin) | .mpd (XML) |
| Belge | RFC 8216 (Informational) ve rfc8216bis taslağı | ISO/IEC 23009-1 |
| Apple cihazlarda | Safari'de yerel oynatma | Genellikle JavaScript oynatıcıyla |
| Diğer tarayıcılar | hls.js gibi kütüphanelerle MSE üzerinden | dash.js gibi kütüphanelerle MSE üzerinden |
| Segment | MPEG-TS veya fMP4/CMAF | Genellikle fMP4/CMAF |
Pratikte web TV yayıncıları için HLS, Apple cihazlarındaki yerel desteği nedeniyle en geniş uyumluluğu sağlayan seçenektir. CMAF ile aynı segmentleri iki formatta sunmak da mümkündür.
Sık Sorulan Sorular
HLS ile RTMP arasındaki fark nedir?
RTMP genellikle kodlayıcıdan sunucuya yayını göndermek (ingest) için, HLS ise sunucudan izleyiciye dağıtmak (delivery) için kullanılır. Tipik bir web TV düzeninde OBS RTMP ile gönderir, sunucu HLS üretir. Ayrıntılar RTMP, SRT ve WebRTC farkı yazımızda.
HLS gecikmesi neden yüksek?
Oynatıcı tamamlanmış segmentleri indirir ve güvenlik payı bırakmak için canlı uçtan birkaç segment geride durur. Segment süresini kısaltmak ve LL-HLS kullanmak gecikmeyi azaltır.
.m3u8 dosyasını VLC ile açabilir miyim?
Evet, VLC gibi masaüstü oynatıcılar .m3u8 adresini ağ akışı olarak açabilir. Bu, yayının sunucuda doğru üretildiğini tarayıcıdan bağımsız test etmek için pratik bir yoldur.
HLS yayınını CDN ile dağıtabilir miyim?
Evet. HLS sıradan HTTP dosyalarından oluştuğu için CDN'lerle uyumludur. Playlist dosyalarının çok kısa, segmentlerin daha uzun önbelleğe alınması gerekir. CDN mantığı için CDN nedir yazımıza bakın.
Yazılım ve platform adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen şirketlerle ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Web sitesine canlı yayın ekleme · Canlı yayın gecikmesi · RTMP, SRT, WebRTC farkı · OBS ile canlı yayın · CDN nedir · Nginx yapılandırma rehberi