Abdulaziz Akyol

HTML5 video ve audio: formatlar, altyazı ve autoplay rehberi

HTML5 · Yazılım geliştirme
29 Eylül 2018 · 7 dk okuma · Abdulaziz Akyol

HTML5’in <video> ve <audio> öğeleri, ses ve görüntüyü herhangi bir eklenti olmadan doğrudan tarayıcıda oynatır. Oynatma denetimleri, altyazı, format seçimi ve JavaScript ile kontrol standart olarak gelir; aynı kod masaüstünde ve mobilde çalışır.

2018’de yazdığım notta “HTML5 henüz Flash’ın kullanılabilirliğine ve kabiliyetine ulaşmış değildir” diyordum. Bu cümle bugün tamamen geçersiz: Adobe, Flash Player desteğini 31 Aralık 2020’de sonlandırdı ve 12 Ocak 2021’den itibaren Flash içeriğinin çalışmasını engelledi. Eski nottaki <embed src="helloworld.swf"> örneği artık hiçbir tarayıcıda çalışmaz. Bu rehberde konuyu 2026’daki duruma göre baştan anlatıyorum; serinin genel çerçevesi için HTML5 nedir? yazısına bakabilirsiniz.

video ve audio öğeleri nasıl kullanılır?

Önerdiğim video iskeleti şöyle:

<video controls width="1280" height="720" preload="metadata"
       poster="/video/tanitim-poster.jpg">
  <source src="/video/tanitim.webm" type='video/webm; codecs="av01.0.08M.08, opus"'>
  <source src="/video/tanitim.mp4" type="video/mp4">
  <track kind="captions" src="/video/tanitim.tr.vtt" srclang="tr" label="Türkçe" default>
  <track kind="subtitles" src="/video/tanitim.en.vtt" srclang="en" label="English">
  <p>Tarayıcınız bu videoyu oynatamıyor. <a href="/video/tanitim.mp4">Videoyu indirin</a>.</p>
</video>

Ses için yapı aynıdır. Eski notumda ses örneği yanlışlıkla <video> etiketiyle verilmişti; doğrusu:

<audio controls preload="none">
  <source src="/ses/podcast-12.m4a" type="audio/mp4">
  <source src="/ses/podcast-12.mp3" type="audio/mpeg">
  <a href="/ses/podcast-12.mp3">Bölümü indirin (MP3)</a>
</audio>

Sık kullanılan öznitelikler:

Öznitelik Ne yapar
controls Tarayıcının oynat, ses, tam ekran denetimlerini gösterir. Klavye ve ekran okuyucu desteği hazır gelir.
autoplay Mümkünse kendiliğinden oynatır; sesli medyada tarayıcılar çoğunlukla engeller.
muted Sesi kapalı başlatır; otomatik oynatmanın ön koşulu.
loop Bitince baştan oynatır.
playsinline iOS’ta videonun tam ekrana geçmeden sayfa içinde oynamasını sağlar.
preload none, metadata ya da auto; ne kadar veri önceden indirileceğine dair ipucu.
poster Video oynatılana kadar gösterilecek görsel.
width, height En-boy oranını belirler, sayfa yüklenirken kaymayı önler.
crossorigin Başka alan adındaki medya ve altyazılar için CORS modu.

<source> listesinde tarayıcı yukarıdan aşağı ilerler ve oynatabildiği ilk kaynağı seçer. Bu yüzden daha verimli format önce, en uyumlu format sonra yazılır. type özniteliğine kodek bilgisi eklemek, tarayıcının dosyayı indirmeden desteklenip desteklenmediğine karar vermesini sağlar.

Hangi format ve kodek seçilmeli?

Konteyner (MP4, WebM) dosyanın kabı, kodek (H.264, AV1, Opus) ise içindeki görüntü ve sesin sıkıştırma yöntemidir. MDN’in codec rehberindeki güncel tabloya göre özet şöyle:

Konteyner Video kodeği Ses kodeği Tarayıcı desteği Rolü
MP4 H.264 (AVC) AAC Tüm büyük tarayıcılar Her zaman yedek
WebM VP9 Opus Güncel büyük tarayıcılar Açık ve telifsiz ara seçenek
WebM ya da MP4 AV1 Opus Chrome, Edge, Firefox; Safari’de yalnızca donanım AV1 çözücüsü olan cihazlar Aynı kalitede en küçük dosya
MP3 ya da M4A — MP3 ya da AAC Tüm büyük tarayıcılar Yalnızca ses

Safari tarafındaki koşul önemli: MDN’e göre AV1 yalnızca M3 ve sonrası Mac’lerde, iPhone 15 Pro’da ve iPhone 16 ve sonrasında çalışıyor. Bu yüzden AV1 kaynağının altında mutlaka H.264’lü bir MP4 bulunmalı. Ses için MDN’in önerisi, tek format seçilecekse AAC’dir; Opus kaliteli ve verimlidir ama Safari’deki desteği konteynere göre sınırlı kalır.

Kodlama için ffmpeg ile başlangıç komutları:

# H.264 + AAC, MP4 (en geniş uyumluluk). faststart: oynatma indirme bitmeden başlasın
ffmpeg -i kaynak.mov -c:v libx264 -preset slow -crf 23 -pix_fmt yuv420p \
  -c:a aac -b:a 128k -movflags +faststart tanitim.mp4

# AV1 + Opus, WebM (daha küçük dosya)
ffmpeg -i kaynak.mov -c:v libsvtav1 -preset 6 -crf 35 -pix_fmt yuv420p \
  -c:a libopus -b:a 96k tanitim.webm

# Poster için 3. saniyeden tek kare
ffmpeg -ss 3 -i kaynak.mov -frames:v 1 -q:v 2 tanitim-poster.jpg

-movflags +faststart sık atlanır ama önemlidir: MP4’ün dizin bilgisini (moov) dosyanın başına taşır, böylece tarayıcı dosyanın tamamını indirmeden oynatmaya başlar.

Görüntü işleme projelerinden bir not: IP kameraların çoğu H.265 (HEVC) üretir ve RTSP ile yayın yapar. RTSP’yi hiçbir tarayıcı doğrudan oynatmaz, HEVC desteği de platforma ve donanıma bağlıdır. Kamera görüntüsünü web’e taşımak için akışı sunucuda HLS, DASH ya da WebRTC’ye dönüştürmek gerekir; zincirin kamera tarafını mevcut kameralarla görüntü analitiği yazısında anlattım. Uzun ve canlı videolarda da tek MP4 yerine uyarlanabilir akış (HLS, DASH) kullanılır; Safari HLS’yi yerel olarak oynatır, tüm tarayıcılarda çalışan yaygın çözüm ise Media Source Extensions tabanlı oynatıcılardır.

Altyazı nasıl eklenir? track ve WebVTT

Altyazılar W3C’nin WebVTT biçiminde, düz metin bir .vtt dosyası olarak hazırlanır:

WEBVTT

NOTE Bu blok ekranda gösterilmez; çevirmen notları için kullanılabilir.

00:00:00.000 --> 00:00:03.500
Bu videoda kurulumun ilk adımını gösteriyoruz.

00:00:03.500 --> 00:00:07.000
[Arka planda makine sesi]
Önce kameranın açısını kontrol ediyoruz.

00:00:07.000 --> 00:00:10.000 line:0
Bu altyazı ekranın üstünde gösterilir.

Dosya WEBVTT satırıyla başlar, her ipucu (cue) boş satırla ayrılır ve başlangıç --> bitiş zamanıyla açılır. line:0 gibi ayarlar, altyazının görüntüdeki önemli bir bölgeyi kapatmaması için konumunu değiştirir.

<track> öğesinin kind değerleri:

  • captions: Diyalogla birlikte ses efektlerini ve konuşmacı bilgisini de içerir; işitme engelli kullanıcılar içindir.
  • subtitles: Diyalogun çevirisidir; sesi duyan ama dili bilmeyen kullanıcı içindir. srclang zorunludur.
  • descriptions: Görsel içeriğin metin açıklaması.
  • chapters: Bölüm başlıkları; oynatıcıda gezinme için.
  • metadata: Kullanıcıya gösterilmeyen, betiklerin okuyacağı veri.

İki pratik tuzak var. Sunucu .vtt dosyasını text/vtt türüyle sunmalıdır. Altyazı başka bir alan adındaysa <video> öğesine crossorigin ekleyin ve o sunucunun CORS başlığı döndürdüğünden emin olun; aksi hâlde track sessizce yüklenmez. Altyazı görünümü ::cue sözde öğesiyle CSS’ten biçimlendirilir.

Autoplay kuralları: video neden kendiliğinden oynamıyor?

MDN’in autoplay rehberine göre tarayıcılar otomatik oynatmaya şu koşullardan biri sağlanırsa izin verir: medya sessizdir (muted ya da ses seviyesi 0), kullanıcı sayfayla etkileşime girmiştir (tıklama, dokunma, tuş), site tarayıcının izin listesindedir ya da bir <iframe>’e Permissions Policy ile autoplay izni verilmiştir. Kısacası, kullanıcı etkileşimi olmadan sesli oynatma genellikle engellenir.

iOS Safari’de ayrıca playsinline gerekir; bu öznitelik olmadan video tam ekrana geçmeye çalışır. Arka plan videosu için doğru desen şöyle:

<video id="arka-video" muted loop playsinline preload="metadata"
       poster="/video/arka-plan.jpg" width="1920" height="1080">
  <source src="/video/arka-plan.webm" type="video/webm">
  <source src="/video/arka-plan.mp4" type="video/mp4">
</video>
<button type="button" id="video-dugme">Arka plan videosunu oynat</button>
const video = document.getElementById("arka-video");
const dugme = document.getElementById("video-dugme");
const hareketAzalt = window.matchMedia("(prefers-reduced-motion: reduce)");

async function oynat() {
  try {
    await video.play();
    dugme.textContent = "Arka plan videosunu durdur";
  } catch (hata) {
    // NotAllowedError: tarayıcı oynatmayı engelledi; poster görünür kalır
    console.warn("Oynatma başlatılamadı:", hata.name);
    dugme.textContent = "Arka plan videosunu oynat";
  }
}

function durdur() {
  video.pause();
  dugme.textContent = "Arka plan videosunu oynat";
}

dugme.addEventListener("click", () => (video.paused ? oynat() : durdur()));

// Hareket azaltma tercihi açıksa kendiliğinden başlatma
if (!hareketAzalt.matches) {
  oynat();
}

Burada autoplay özniteliği yerine play() çağrısı kullandım; böylece hareket azaltma tercihine uyulabiliyor. play() bir Promise döndürür; reddedildiğinde hata adı NotAllowedError ise oynatma izin nedeniyle engellenmiştir ve kullanıcıya bir oynat düğmesi göstermek gerekir. autoplay kullanırsanız preload değerinin yok sayıldığını, videonun hemen indirildiğini de unutmayın.

preload, poster ve performans

Video, bir sayfadaki en ağır kaynaktır. Hızı belirleyen ayarlar:

  • preload: Varsayılan değer tarayıcıya göre değişir; standart metadata değerini öneriyor. Sayfada birden fazla video varsa ya da video ekranın altındaysa none verin. Süreyi göstermek istiyorsanız metadata yeterlidir.
  • poster: İlk izlenimi belirler ve sayfanın en büyük içerik öğesi (LCP) olarak ölçülebilir. AVIF, WebP ya da iyi sıkıştırılmış JPEG kullanın.
  • width ve height: CSS’te width: 100%; height: auto; ile birlikte en-boy oranını korur, düzen kaymasını (CLS) önler.
  • GIF yerine video: Kısa, sessiz, döngülü animasyonlar için muted loop playsinline bir video, aynı içeriğin GIF’inden çok daha küçük olur.

Tembel yükleme: loading="lazy" özniteliği <video> ve <audio> için de HTML standardına eklendi. caniuse verisine göre Eylül 2026 itibarıyla Chrome ve Edge 148 sürümünden beri destekliyor, Firefox ve Safari henüz desteklemiyor. Desteklemeyen tarayıcı özniteliği yok saydığı için preload="none" ile birlikte kullanmak güvenlidir. Görünür olunca oynayan, ekrandan çıkınca duran sessiz klipler için IntersectionObserver her tarayıcıda çalışır:

const gozlemci = new IntersectionObserver((girdiler) => {
  for (const { target: video, isIntersecting } of girdiler) {
    if (isIntersecting) {
      video.play().catch(() => {}); // engellenirse poster kalır
    } else {
      video.pause();
    }
  }
}, { threshold: 0.5 });

document.querySelectorAll("video[data-gorununce-oynat]").forEach((v) => gozlemci.observe(v));

Üçüncü taraf oynatıcılar ve cephe (facade) deseni: YouTube gibi gömülü oynatıcılar, kullanıcı hiç tıklamasa bile yüzlerce kilobaytlık betik yükler. En basit önlem <iframe loading="lazy">’dir. Daha etkilisi, önce yalnızca bir önizleme görseli ve oynat düğmesi gösterip iframe’i tıklamayla yüklemektir:

<button type="button" class="yt-cephe" data-video-id="VIDEO_KIMLIGI"
        data-baslik="Kurulum adımları">
  <img src="https://i.ytimg.com/vi/VIDEO_KIMLIGI/hqdefault.jpg" alt=""
       width="480" height="360" loading="lazy">
  <span>Videoyu oynat: Kurulum adımları</span>
</button>

<script>
  document.querySelectorAll(".yt-cephe").forEach((dugme) => {
    dugme.addEventListener("click", () => {
      const iframe = document.createElement("iframe");
      iframe.src = `https://www.youtube-nocookie.com/embed/${dugme.dataset.videoId}?autoplay=1`;
      iframe.title = dugme.dataset.baslik;
      iframe.width = "560";
      iframe.height = "315";
      iframe.allow = "autoplay; encrypted-media; picture-in-picture";
      iframe.allowFullscreen = true;
      dugme.replaceWith(iframe);
    });
  });
</script>

Medya erişilebilirliği için ne gerekir?

WCAG 2.2, medya için açık ölçütler koyar:

  • Altyazı (1.2.2, A düzeyi): Önceden kaydedilmiş sesli videolarda captions zorunludur.
  • Sesli betimleme (1.2.5, AA düzeyi): Yalnızca görüntüyle aktarılan önemli bilgi seslendirmeyle ya da betimleme parçasıyla anlatılmalıdır.
  • Yalnızca ses ya da yalnızca görüntü (1.2.1, A düzeyi): Podcast gibi içerikler için metin dökümü (transcript) sunulmalıdır.
  • Ses denetimi (1.4.2, A düzeyi): Kendiliğinden başlayan ve 3 saniyeden uzun süren ses durdurulabilmelidir.
  • Durdur, gizle (2.2.2, A düzeyi): Kendiliğinden başlayan ve 5 saniyeden uzun süren hareketli içerik durdurulabilmelidir; yukarıdaki arka plan videosu düğmesi bu yüzden var.

Tarayıcının yerel controls denetimleri klavye ve ekran okuyucu desteğiyle gelir. Özel oynatıcı yazıyorsanız her denetim gerçek bir <button> olmalı ve erişilebilir bir adı bulunmalı; ses seviyesi için etiketli bir type="range" alanı kullanın (HTML5 formlar rehberi). Videoyu açıklamalı bir blok olarak sunmak için <figure> ve <figcaption> kullanımını HTML5 anlamsal etiketler rehberinde anlattım. Video karelerini işlemek ya da üzerlerine çizim yapmak isterseniz drawImage ile karelerin canvas’a nasıl aktarıldığını Canvas rehberinde bulabilirsiniz.

embed ve object ne oldu?

<embed> ve <object> standartta duruyor, ama eklenti dönemi bittiği için pratik kullanımları çok daralmıştır; tipik örnek PDF göstermektir. Video için <video>, ses için <audio>, başka bir sayfayı ya da oynatıcıyı gömmek için <iframe> kullanın.

Kontrol listesi

  • Video önce WebM (AV1 ya da VP9 + Opus), sonra MP4 (H.264 + AAC) kaynağıyla veriliyor; MP4’ler faststart ile kodlandı.
  • width, height ve sıkıştırılmış bir poster var; ekran dışı videolarda preload="none".
  • Otomatik oynayan videolar muted ve playsinline; play() hatası yakalanıyor, durdurma düğmesi var, prefers-reduced-motion dikkate alınıyor.
  • Sesli her videonun kind="captions" WebVTT altyazısı, her ses içeriğinin metin dökümü var.
  • YouTube gibi üçüncü taraf oynatıcılar tıklayınca yükleniyor ya da en azından loading="lazy".

Sık sorulan sorular

Web sitesi için en uygun video formatı hangisi?

Tek dosya yükleyecekseniz MP4 içinde H.264 video ve AAC ses tüm büyük tarayıcılarda çalışır. İki dosya hazırlayabiliyorsanız önce WebM içinde AV1 ya da VP9 ve Opus ses, ardından yedek olarak MP4 verin; tarayıcı listeden oynatabildiği ilk kaynağı seçer.

Video neden otomatik oynamıyor?

Tarayıcılar, kullanıcı sayfayla etkileşime girmeden sesli medyanın oynamasını engeller. Videoya muted özniteliği ekleyin, iOS için playsinline da ekleyin ve play() çağrısının döndürdüğü Promise'i yakalayarak engellendiğinde oynat düğmesi gösterin.

Videoya altyazı nasıl eklenir?

Altyazıyı WebVTT biçiminde bir .vtt dosyası olarak hazırlayın ve video öğesinin içine kind, srclang ve label öznitelikleri olan bir track öğesiyle ekleyin. Dosya başka bir alan adındaysa video öğesine crossorigin ekleyin ve sunucunun CORS başlığı döndürdüğünden emin olun.

HTML5 video Flash'ın yerini tamamen aldı mı?

Evet. Adobe, Flash Player desteğini 31 Aralık 2020'de bitirdi ve 12 Ocak 2021'den itibaren Flash içeriğinin çalışmasını engelledi. Bugün video ve ses için video ve audio öğeleri, uyarlanabilir akış için bunların üzerine kurulan Media Source Extensions kullanılır.

Kaynaklar

  1. WHATWG HTML Standard — Media elements html.spec.whatwg.org
  2. MDN — The video element developer.mozilla.org
  3. MDN — Web video codec guide developer.mozilla.org
  4. MDN — Autoplay guide for media and Web Audio APIs developer.mozilla.org
  5. W3C — WebVTT: The Web Video Text Tracks Format w3.org
  6. Adobe — Flash Player End of Life adobe.com

HTML5videoaudioWebVTTAV1AutoplayErişilebilirlikMarkdown sürümü

İletişim

Konuşalım.