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 nasıl çalışır? Kodlayıcı, Yayın sunucusu, Web sunucusu veya CDN, Oynatıcı

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

text
#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.m3u8

RFC 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)

text
#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
EtiketRFC 8216'daki anlamı
EXT-X-TARGETDURATIONBir segmentin en fazla kaç saniye olabileceği.
EXT-X-MEDIA-SEQUENCEListede görünen ilk segmentin sıra numarası. Canlı yayında eski segmentler düştükçe artar.
EXTINFHemen altındaki segmentin süresi.
EXT-X-PLAYLIST-TYPEEVENT: segmentler yalnızca sona eklenebilir. VOD: liste hiç değişmez.
EXT-X-ENDLISTListeye artık segment eklenmeyeceğini, yayının bittiğini gösterir.

Variant ve ABR: neden birden fazla kalite?

Variant ve ABR: neden birden fazla kalite? 416 x 234, 640 x 360, 768 x 432, 768 x 432

İ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ükBitrate (kbit/s)Kare hızı
416 x 23414530 fps ve altı
640 x 36036530 fps ve altı
768 x 43273030 fps ve altı
768 x 432110030 fps ve altı
960 x 5402000Kaynakla aynı
1280 x 7203000Kaynakla aynı
1280 x 7204500Kaynakla aynı
1920 x 10806000Kaynakla aynı
1920 x 10807800Kaynakla 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-MAP etiketi 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ğiNe 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-INFKısmi segmentlerin hedef süresini (PART-TARGET) bildirir; EXT-X-PART kullanılıyorsa zorunludur.
EXT-X-PRELOAD-HINTOynatıcıya bir sonraki parçanın adresini önceden bildirir; böylece istek erken açılır.
Blocking Playlist ReloadOynatı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-REPORTDiğer kalitelerin en güncel durumunu bildirir, kalite geçişini hızlandırır.
EXT-X-SERVER-CONTROLSunucunun 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.

html
<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 penceresi: canlı yayını geri sarmak: RFC 8216'ya göre sunucu, EXT-X-ENDLIST içermeyen bir listeden, süresi hedef..., Listeden çıkarılan segment de bir süre daha erişilebilir...

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:EVENT kullanı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:

ÖzellikHLSMPEG-DASH
Manifest.m3u8 (metin).mpd (XML)
BelgeRFC 8216 (Informational) ve rfc8216bis taslağıISO/IEC 23009-1
Apple cihazlardaSafari'de yerel oynatmaGenellikle JavaScript oynatıcıyla
Diğer tarayıcılarhls.js gibi kütüphanelerle MSE üzerindendash.js gibi kütüphanelerle MSE üzerinden
SegmentMPEG-TS veya fMP4/CMAFGenellikle 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