Files
player/DOCUMENTATION.md
T
hibna c643b030d7 .
2025-10-29 13:41:08 +03:00

28 KiB
Raw Blame History

📚 Video Player - Kapsamlı Dokümantasyon

Modern, hafif ve özellik açısından zengin bir React video player kütüphanesi. Bu dokümantasyon, kütüphaneyi projelerinizde kullanmak için ihtiyacınız olan her şeyi içerir.

📦 Kurulum

NPM ile Kurulum

npm install @alper/video-player

Yarn ile Kurulum

yarn add @alper/video-player

Peer Dependencies

Video player, React 18+ gerektirmektedir:

npm install react react-dom

Opsiyonel Bağımlılıklar

HLS streaming desteği için hls.js otomatik olarak yüklenecektir (gerektiğinde):

npm install hls.js  # Opsiyonel

🚀 Hızlı Başlangıç

Basit Kullanım

import { VideoPlayer } from '@alper/video-player'
import '@alper/video-player/styles.css'

function App() {
  return (
    <VideoPlayer
      src="https://example.com/video.mp4"
      poster="https://example.com/poster.jpg"
    />
  )
}

TypeScript Desteği

Kütüphane tam TypeScript desteğine sahiptir ve tip tanımları otomatik olarak gelir:

import { VideoPlayer, VideoPlayerProps } from '@alper/video-player'
import '@alper/video-player/styles.css'

const MyPlayer: React.FC = () => {
  const props: VideoPlayerProps = {
    src: "video.mp4",
    autoplay: false,
    loop: true,
  }

  return <VideoPlayer {...props} />
}

🎬 Özellikler

Temel Özellikler

  • ▶️ Oynatma Kontrolleri: Play, pause, seek
  • 🔊 Ses Kontrolü: Volume slider ve mute
  • Hız Kontrolü: 0.25x - 2x oynatma hızı
  • 🔄 Loop Desteği: Sürekli tekrar
  • 🖼️ Poster Resmi: Video başlamadan önce görünen thumbnail
  • ⌨️ Klavye Kısayolları: 15+ klavye kısayolu
  • 📱 Touch Gesture'lar: Mobil cihazlar için özel kontroller

🎨 Gelişmiş Özellikler

  • 📺 HLS Streaming: .m3u8 dosyaları için otomatik HLS desteği
  • 📝 Altyazı Desteği: WebVTT ve SRT formatları
  • 🎵 Çoklu Ses Kanalı: Farklı dil seçenekleri
  • 🎯 Kalite Seçimi: HLS stream'lerinde otomatik kalite geçişi
  • 🖥️ Fullscreen: Native fullscreen API desteği
  • 📺 Picture-in-Picture: PIP mode desteği
  • 🌍 i18n Desteği: İngilizce ve Türkçe dil desteği
  • 🎨 Tema Özelleştirme: CSS değişkenleri ile kolay özelleştirme

Performans

  • 📦 Küçük Boyut: Sadece ~15KB (gzipped)
  • 🚀 Sıfır Runtime Bağımlılık: React dışında bağımlılık yok
  • 🔄 Lazy Loading: HLS.js sadece gerektiğinde yüklenir
  • 🎯 Optimize Edilmiş: Tree-shakeable exports

📖 API Referansı

VideoPlayer Props

Prop Tip Varsayılan Açıklama
src string zorunlu Video kaynağı URL (MP4, WebM, HLS)
poster string - Poster/thumbnail resmi URL'si
autoplay boolean false Otomatik oynatma
loop boolean false Video tekrarı
muted boolean false Sessiz başlat
controls boolean true Kontrolleri göster
subtitles SubtitleTrack[] [] Altyazı track'leri
theme PlayerTheme - Özel tema renkleri
language string 'tr' Arayüz dili ('tr' veya 'en')
keyboardShortcuts boolean true Klavye kısayollarını etkinleştir
pictureInPicture boolean true PIP butonunu göster
className string - Özel CSS class'ı
style CSSProperties - Inline style'lar
onPlay () => void - Oynatma başladığında
onPause () => void - Oynatma durduğunda
onEnded () => void - Video bittiğinde
onTimeUpdate (time: number) => void - Zaman güncellendiğinde
onVolumeChange (volume: number) => void - Ses seviyesi değiştiğinde
onError (error: Error) => void - Hata oluştuğunda
onLoadedMetadata () => void - Metadata yüklendiğinde
onSeeking () => void - Seek başladığında
onSeeked () => void - Seek bittiğinde

SubtitleTrack

interface SubtitleTrack {
  src: string       // Altyazı dosyası URL'si (.vtt veya .srt)
  lang: string      // Dil kodu (örn: 'en', 'tr')
  label: string     // Görüntülenecek etiket
  default?: boolean // Varsayılan altyazı olarak ayarla
}

AudioTrack

interface AudioTrack {
  name: string      // Ses track'inin adı
  language: string  // Dil kodu
  url: string       // Ses dosyası URL'si
  groupId: string   // Grup ID'si
  default?: boolean // Varsayılan olarak seç
}

VideoQuality

interface VideoQuality {
  height?: number   // Video yüksekliği (px)
  label: string     // Görüntülenecek etiket (örn: "1080p")
  width?: number    // Video genişliği (px)
  bitrate?: number  // Bitrate (bps)
  levelIndex?: number // HLS level index
}

PlayerTheme

interface PlayerTheme {
  primaryColor?: string      // Ana renk (varsayılan: #ef4444)
  accentColor?: string       // Vurgu rengi (varsayılan: #dc2626)
  backgroundColor?: string   // Arkaplan rengi (varsayılan: #000000)
  textColor?: string         // Yazı rengi (varsayılan: #ffffff)
}

💡 Kullanım Örnekleri

1. Basit Video Oynatma

En temel kullanım:

import { VideoPlayer } from '@alper/video-player'
import '@alper/video-player/styles.css'

function SimplePlayer() {
  return (
    <VideoPlayer
      src="/videos/sample.mp4"
      poster="/images/thumbnail.jpg"
    />
  )
}

2. Otomatik Oynatma ve Loop

Video otomatik başlasın ve sürekli tekrarlansın:

<VideoPlayer
  src="/videos/intro.mp4"
  autoplay
  loop
  muted // Not: Otomatik oynatma için genelde muted gereklidir
/>

3. Altyazılı Video

Çoklu altyazı desteği ile:

<VideoPlayer
  src="/videos/movie.mp4"
  subtitles={[
    {
      src: '/subtitles/english.vtt',
      lang: 'en',
      label: 'English',
      default: true
    },
    {
      src: '/subtitles/turkish.srt',
      lang: 'tr',
      label: 'Türkçe'
    },
    {
      src: '/subtitles/spanish.vtt',
      lang: 'es',
      label: 'Español'
    }
  ]}
/>

4. HLS Streaming

HLS video için (hls.js otomatik yüklenir):

<VideoPlayer
  src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
  autoplay={false}
  poster="/images/stream-poster.jpg"
/>

HLS streaming ile kalite seçimi otomatik olarak aktif olur.

5. Event Handler'lar ile İleri Seviye Kullanım

Video olaylarını dinleme:

import { useState } from 'react'
import { VideoPlayer } from '@alper/video-player'

function AdvancedPlayer() {
  const [currentTime, setCurrentTime] = useState(0)
  const [isPlaying, setIsPlaying] = useState(false)

  return (
    <div>
      <VideoPlayer
        src="/videos/tutorial.mp4"
        onPlay={() => {
          console.log('Video başladı!')
          setIsPlaying(true)
        }}
        onPause={() => {
          console.log('Video durdu!')
          setIsPlaying(false)
        }}
        onTimeUpdate={(time) => {
          setCurrentTime(time)
        }}
        onEnded={() => {
          console.log('Video bitti!')
          // Örnek: Sonraki videoya geç
        }}
        onError={(error) => {
          console.error('Video hatası:', error)
          // Hata gösterimi veya fallback
        }}
      />

      <div>
        <p>Durum: {isPlaying ? 'Oynatılıyor' : 'Durdu'}</p>
        <p>Zaman: {Math.floor(currentTime)}s</p>
      </div>
    </div>
  )
}

6. Özel Tema

Kendi renk şemanızla özelleştirme:

<VideoPlayer
  src="/videos/branded.mp4"
  theme={{
    primaryColor: '#3b82f6',      // Mavi
    accentColor: '#2563eb',       // Koyu mavi
    backgroundColor: '#1e293b',   // Koyu gri
    textColor: '#f1f5f9'          // Açık gri
  }}
/>

7. Türkçe Arayüz

Türkçe dil desteği:

<VideoPlayer
  src="/videos/content.mp4"
  language="tr"
/>

8. Klavye Kısayolları Devre Dışı

Bazı durumlarda klavye kısayollarını kapatmak isteyebilirsiniz:

<VideoPlayer
  src="/videos/presentation.mp4"
  keyboardShortcuts={false}
/>

9. Responsive Layout

Farklı ekran boyutlarında:

<div style={{
  width: '100%',
  maxWidth: '1200px',
  margin: '0 auto'
}}>
  <VideoPlayer
    src="/videos/responsive.mp4"
    style={{
      width: '100%',
      aspectRatio: '16/9'
    }}
  />
</div>

10. Video Playlist

Sıralı video oynatma:

import { useState } from 'react'
import { VideoPlayer } from '@alper/video-player'

const videos = [
  { id: 1, src: '/videos/episode1.mp4', title: 'Bölüm 1' },
  { id: 2, src: '/videos/episode2.mp4', title: 'Bölüm 2' },
  { id: 3, src: '/videos/episode3.mp4', title: 'Bölüm 3' },
]

function Playlist() {
  const [currentIndex, setCurrentIndex] = useState(0)

  const handleEnded = () => {
    // Sonraki videoya geç
    if (currentIndex < videos.length - 1) {
      setCurrentIndex(currentIndex + 1)
    }
  }

  return (
    <div>
      <h2>{videos[currentIndex].title}</h2>
      <VideoPlayer
        key={videos[currentIndex].id}
        src={videos[currentIndex].src}
        onEnded={handleEnded}
      />

      <div style={{ marginTop: '20px' }}>
        {videos.map((video, index) => (
          <button
            key={video.id}
            onClick={() => setCurrentIndex(index)}
            style={{
              fontWeight: index === currentIndex ? 'bold' : 'normal'
            }}
          >
            {video.title}
          </button>
        ))}
      </div>
    </div>
  )
}

⌨️ Klavye Kısayolları

Video player, kullanıcı deneyimini geliştirmek için kapsamlı klavye desteği sunar:

Tuş Aksiyon
Space veya K Oynat/Duraklat
(Sol Ok) 5 saniye geri sar
(Sağ Ok) 5 saniye ileri sar
J 10 saniye geri sar
L 10 saniye ileri sar
(Yukarı Ok) Ses seviyesini artır (%5)
(Aşağı Ok) Ses seviyesini azalt (%5)
M Sessiz/Sesli
F Tam ekran aç/kapat
P Picture-in-Picture
0 Başa dön (%0)
1-9 İlgili yüzdeye atla (%10-%90)
Home Başa dön
End Sona git
< Oynatma hızını azalt (0.25x)
> Oynatma hızını artır (0.25x)

Not: Klavye kısayolları sadece video player'a focus edildiğinde çalışır.


📱 Touch Gesture'lar

Mobil cihazlarda kullanıcı deneyimini geliştiren touch gesture'lar:

Temel Gesture'lar

  • Tek Dokunuş: Oynat/Duraklat
  • Çift Dokunuş (Sol): 10 saniye geri sar
  • Çift Dokunuş (Sağ): 10 saniye ileri sar

Swipe Gesture'ları

  • Sağa Kaydır: İleri sar (kaydırma mesafesine göre)
  • Sola Kaydır: Geri sar (kaydırma mesafesine göre)
  • Yukarı Kaydır: Ses seviyesini artır
  • Aşağı Kaydır: Ses seviyesini azalt

Pinch & Zoom

  • Pinch: Video zoom (bazı tarayıcılarda)

🎨 Stil ve Özelleştirme

CSS Değişkenleri

Video player, CSS değişkenleri kullanarak kolayca özelleştirilebilir. İşte tüm değişkenler:

:root {
  /* Ana Renkler */
  --player-primary: #ef4444;              /* Ana renk */
  --player-primary-hover: #dc2626;        /* Hover rengi */
  --player-primary-active: #b91c1c;       /* Active rengi */
  --player-primary-light: rgba(239, 68, 68, 0.2); /* Açık renk */

  /* Arkaplan Renkleri */
  --player-bg: #000000;                   /* Ana arkaplan */
  --player-bg-controls: rgba(0, 0, 0, 0.85); /* Kontrol paneli */
  --player-bg-overlay: rgba(0, 0, 0, 0.6);   /* Overlay */
  --player-bg-menu: rgba(20, 20, 20, 0.95);  /* Menu arkaplan */

  /* Yazı Renkleri */
  --player-text: #ffffff;                 /* Ana yazı */
  --player-text-secondary: #d1d5db;       /* İkincil yazı */
  --player-text-muted: #9ca3af;           /* Soluk yazı */

  /* Kenarlık & Ayırıcı */
  --player-border: #374151;
  --player-divider: rgba(255, 255, 255, 0.1);

  /* Progress & Buffered */
  --player-buffered: rgba(239, 68, 68, 0.3);
  --player-progress-bg: rgba(255, 255, 255, 0.3);

  /* Gölgeler */
  --player-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --player-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  --player-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);

  /* Geçişler */
  --player-transition-fast: 150ms;
  --player-transition-normal: 250ms;
  --player-transition-slow: 400ms;

  /* Z-index */
  --player-z-video: 1;
  --player-z-subtitle: 10;
  --player-z-controls: 20;
  --player-z-menu: 30;
  --player-z-loading: 40;

  /* Boşluklar */
  --player-spacing-xs: 6px;
  --player-spacing-sm: 10px;
  --player-spacing-md: 14px;
  --player-spacing-lg: 20px;
  --player-spacing-xl: 28px;

  /* Border Radius */
  --player-radius-sm: 4px;
  --player-radius-md: 6px;
  --player-radius-lg: 8px;
  --player-radius-full: 9999px;

  /* İkon Boyutları */
  --player-icon-sm: 20px;
  --player-icon-md: 28px;
  --player-icon-lg: 36px;
  --player-icon-xl: 56px;
}

Tema Özelleştirme Örnekleri

Koyu Mavi Tema

:root {
  --player-primary: #3b82f6;
  --player-primary-hover: #2563eb;
  --player-primary-active: #1d4ed8;
  --player-bg: #0f172a;
}
// veya JavaScript ile
<VideoPlayer
  src="/videos/demo.mp4"
  theme={{
    primaryColor: '#3b82f6',
    accentColor: '#2563eb',
    backgroundColor: '#0f172a',
    textColor: '#f1f5f9'
  }}
/>

Yeşil Tema

:root {
  --player-primary: #10b981;
  --player-primary-hover: #059669;
  --player-primary-active: #047857;
}

Mor Tema

:root {
  --player-primary: #8b5cf6;
  --player-primary-hover: #7c3aed;
  --player-primary-active: #6d28d9;
}

Özel CSS ile Özelleştirme

Daha fazla kontrol için özel CSS yazabilirsiniz:

/* Video player container boyutu */
.video-player {
  max-width: 1200px;
  margin: 0 auto;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
}

/* Kontrol paneli opacity */
.video-controls {
  background: rgba(0, 0, 0, 0.95) !important;
}

/* Progress bar yüksekliği */
.progress-bar {
  height: 6px !important;
}

/* Button boyutları */
.control-button {
  width: 48px !important;
  height: 48px !important;
}

🔧 Gelişmiş Kullanım

Context API ile Video Kontrolü

Video player'ın context'ini kullanarak programatik kontrol:

import { VideoPlayer, usePlayerContext, PlayerProvider } from '@alper/video-player'

function VideoControls() {
  const {
    play,
    pause,
    seek,
    setVolume,
    toggleFullscreen,
    videoState
  } = usePlayerContext()

  return (
    <div>
      <button onClick={play}>Oynat</button>
      <button onClick={pause}>Duraklat</button>
      <button onClick={() => seek(30)}>30. saniyeye git</button>
      <button onClick={() => setVolume(0.5)}>%50 ses</button>
      <button onClick={toggleFullscreen}>Tam Ekran</button>

      <p>Oynatılıyor: {videoState.playing ? 'Evet' : 'Hayır'}</p>
      <p>Süre: {videoState.duration}s</p>
      <p>Mevcut: {videoState.currentTime}s</p>
    </div>
  )
}

function App() {
  return (
    <PlayerProvider>
      <VideoPlayer src="/video.mp4" />
      <VideoControls />
    </PlayerProvider>
  )
}

Custom Hook'lar Kullanımı

Kendi player'ınızı oluşturmak için hook'ları kullanabilirsiniz:

import { useKeyboardShortcuts, useTouchGestures } from '@alper/video-player'

function CustomPlayer() {
  const videoRef = useRef<HTMLVideoElement>(null)

  // Klavye kısayollarını ekle
  useKeyboardShortcuts(videoRef, {
    onPlayPause: () => {
      if (videoRef.current?.paused) {
        videoRef.current?.play()
      } else {
        videoRef.current?.pause()
      }
    },
    onSeek: (seconds) => {
      if (videoRef.current) {
        videoRef.current.currentTime += seconds
      }
    }
  })

  // Touch gesture'ları ekle
  useTouchGestures(videoRef, {
    onDoubleTapLeft: () => console.log('Geri sar'),
    onDoubleTapRight: () => console.log('İleri sar'),
  })

  return <video ref={videoRef} src="/video.mp4" />
}

Altyazı İşlemleri

Altyazıları programatik olarak işleme:

import { parseSRT, createSubtitleBlobURL, fetchSubtitle } from '@alper/video-player'

// SRT dosyasını VTT'ye dönüştür
async function convertSRTtoVTT(srtUrl: string) {
  const srtContent = await fetch(srtUrl).then(r => r.text())
  const vttContent = parseSRT(srtContent)
  const blobUrl = createSubtitleBlobURL(vttContent)
  return blobUrl
}

// Altyazıyı fetch et ve kullan
async function loadSubtitle(url: string) {
  const subtitle = await fetchSubtitle(url)
  console.log(subtitle)
}

CORS Kontrolü

Video URL'lerini yüklemeden önce CORS kontrolü:

import { validateVideoURL, checkVideoCORS } from '@alper/video-player'

async function loadVideo(url: string) {
  // URL validasyonu
  const validation = validateVideoURL(url)
  if (!validation.valid) {
    alert(`Geçersiz URL: ${validation.error}`)
    return
  }

  // CORS kontrolü
  const corsCheck = await checkVideoCORS(url)
  if (!corsCheck.supported) {
    console.error('CORS hatası:', corsCheck.error)

    if (corsCheck.needsProxy) {
      console.log('Proxy gerekiyor')
      // Proxy kullanarak yükle
    }
    return
  }

  // Güvenli şekilde yükle
  return <VideoPlayer src={url} />
}

Zaman Formatı Yardımcıları

import { formatTime, parseTime } from '@alper/video-player'

// Saniyeyi formatla
formatTime(125)      // "02:05"
formatTime(3661)     // "01:01:01"

// Formatlanmış zamanı saniyeye çevir
parseTime("02:05")   // 125
parseTime("01:01:01") // 3661

🌍 Çoklu Dil Desteği (i18n)

Video player İngilizce ve Türkçe dil desteği ile gelir.

Dil Değiştirme

// Türkçe arayüz
<VideoPlayer
  src="/video.mp4"
  language="tr"
/>

// İngilizce arayüz
<VideoPlayer
  src="/video.mp4"
  language="en"
/>

Özel Çeviriler

Kendi çevirilerinizi eklemek için:

import { translations, getTranslations } from '@alper/video-player'

// Mevcut çevirileri genişlet
translations.tr.customKey = 'Özel metin'
translations.en.customKey = 'Custom text'

// Çevirileri kullan
const t = getTranslations('tr')
console.log(t.play)  // "Oynat"
console.log(t.pause) // "Duraklat"

Desteklenen Diller

Dil Kod Durum
Türkçe tr Tam destek
İngilizce en Tam destek

🎯 HLS Streaming Detayları

Otomatik HLS Algılama

Video player, .m3u8 uzantılı dosyaları otomatik algılar ve hls.js'i yükler:

<VideoPlayer
  src="https://example.com/stream/playlist.m3u8"
/>

Manuel HLS Kontrolü

import Hls from 'hls.js'

// HLS desteğini kontrol et
if (Hls.isSupported()) {
  console.log('HLS destekleniyor (hls.js ile)')
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
  console.log('Native HLS destekleniyor (Safari)')
}

HLS Kalite Seçimi

HLS stream'inde kalite seçimi otomatik olarak aktif olur:

<VideoPlayer
  src="https://example.com/stream/playlist.m3u8"
  // Kalite menüsü otomatik görünecek
/>

HLS Hata Yönetimi

<VideoPlayer
  src="https://example.com/stream/playlist.m3u8"
  onError={(error) => {
    console.error('HLS hatası:', error)
    // Fallback video göster
  }}
/>

📱 Responsive Tasarım

Mobil Uyumluluk

Video player mobil cihazlarda mükemmel çalışır:

<div className="mobile-container">
  <VideoPlayer
    src="/videos/mobile.mp4"
    // Mobil cihazlarda touch gesture'lar otomatik aktif
  />
</div>
.mobile-container {
  width: 100%;
  padding: 0;
}

/* Mobil için özel ayarlar */
@media (max-width: 768px) {
  .video-player {
    border-radius: 0;
  }

  .video-controls {
    padding: 8px !important;
  }
}

Aspect Ratio Koruması

<div style={{
  width: '100%',
  aspectRatio: '16/9',
  backgroundColor: '#000'
}}>
  <VideoPlayer
    src="/video.mp4"
    style={{ width: '100%', height: '100%' }}
  />
</div>

Grid Layout ile Çoklu Video

.video-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  padding: 20px;
}
<div className="video-grid">
  <VideoPlayer src="/video1.mp4" />
  <VideoPlayer src="/video2.mp4" />
  <VideoPlayer src="/video3.mp4" />
  <VideoPlayer src="/video4.mp4" />
</div>

⚠️ Dikkat Edilmesi Gerekenler

1. CORS (Cross-Origin Resource Sharing)

Video dosyaları farklı bir domain'de ise CORS header'ları gereklidir:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, OPTIONS
Access-Control-Allow-Headers: Range

Çözüm:

  • Sunucunuzda CORS'u etkinleştirin
  • CDN kullanıyorsanız CORS ayarlarını yapın
  • Veya proxy sunucu kullanın

2. Otomatik Oynatma Kısıtlamaları

Modern tarayıcılar, kullanıcı etkileşimi olmadan otomatik oynatmayı engelleyebilir:

// Otomatik oynatma için sessiz gereklidir
<VideoPlayer
  src="/video.mp4"
  autoplay
  muted  // Önemli!
/>

3. iOS Safari Davranışları

iOS Safari'de bazı özel durumlar vardır:

  • Fullscreen native player'ı açar
  • Volume kontrolü çalışmaz (sistem ses seviyesi kullanılır)
  • Otomatik oynatma kısıtlamaları daha katıdır
import { features } from '@alper/video-player'

if (features.isIOSSafari()) {
  console.log('iOS Safari tespit edildi')
  // iOS spesifik ayarlamalar
}

if (!features.hasVolumeControl()) {
  // Volume kontrolünü gizle
}

4. Büyük Video Dosyaları

Büyük video dosyaları için HTTP Range Request desteği önemlidir:

Accept-Ranges: bytes
Content-Range: bytes 0-1024/5242880

5. HLS.js Yükleme

HLS.js optional dependency olarak eklenmiştir. NPM'den yüklenemezse CDN'den otomatik yüklenir.

Manuel kurulum:

npm install hls.js

6. Performance İpuçları

// ❌ Kötü: Her render'da yeni object
<VideoPlayer theme={{ primaryColor: '#ff0000' }} />

// ✅ İyi: Dışarıda tanımla
const theme = { primaryColor: '#ff0000' }
<VideoPlayer theme={theme} />

// ✅ Daha iyi: useMemo kullan
const theme = useMemo(() => ({
  primaryColor: '#ff0000'
}), [])
<VideoPlayer theme={theme} />

7. Memory Leak Önleme

Component unmount olduğunda player otomatik temizlenir. Manuel cleanup gerekmez.

8. TypeScript Strict Mode

TypeScript strict mode ile tam uyumludur:

import type { VideoPlayerProps } from '@alper/video-player'

const props: VideoPlayerProps = {
  src: 'video.mp4',
  // TypeScript tüm prop'ları kontrol eder
}

🧪 Test ve Hata Ayıklama

Hata Yakalama

function SafePlayer() {
  const [error, setError] = useState<Error | null>(null)

  if (error) {
    return (
      <div className="error-message">
        <h3>Video yüklenemedi</h3>
        <p>{error.message}</p>
        <button onClick={() => setError(null)}>Tekrar Dene</button>
      </div>
    )
  }

  return (
    <VideoPlayer
      src="/video.mp4"
      onError={(err) => {
        console.error('Video hatası:', err)
        setError(err)
      }}
    />
  )
}

Loading State

function PlayerWithLoading() {
  const [loading, setLoading] = useState(true)

  return (
    <div style={{ position: 'relative' }}>
      {loading && (
        <div className="loading-overlay">
          Yükleniyor...
        </div>
      )}
      <VideoPlayer
        src="/video.mp4"
        onLoadedMetadata={() => setLoading(false)}
      />
    </div>
  )
}

Console Debug

<VideoPlayer
  src="/video.mp4"
  onPlay={() => console.log('[DEBUG] Play')}
  onPause={() => console.log('[DEBUG] Pause')}
  onTimeUpdate={(t) => console.log('[DEBUG] Time:', t)}
  onError={(e) => console.error('[DEBUG] Error:', e)}
  onLoadedMetadata={() => console.log('[DEBUG] Metadata loaded')}
/>

📊 Browser Desteği

Browser Versiyon Destek
Chrome 90+ Tam
Firefox 88+ Tam
Safari 14+ Tam
Edge 90+ Tam
Opera 76+ Tam
iOS Safari 14+ Tam
Chrome Mobile 90+ Tam
Samsung Internet 15+ Tam

Feature Desteği

Özellik Chrome Firefox Safari Edge
HLS * * *
PIP
Fullscreen
Subtitles
Touch

*hls.js ile desteklenir (Safari'de native)


🚀 Production Deployment

Build Optimizasyonu

# Production build
npm run build:lib

# Bundle boyutunu kontrol et
npm run build:lib -- --mode production

# Gzip sıkıştırma ile
gzip -k dist/video-player.js

CDN Kullanımı

<!-- UMD build -->
<script src="https://unpkg.com/@alper/video-player@latest/dist/video-player.umd.cjs"></script>
<link rel="stylesheet" href="https://unpkg.com/@alper/video-player@latest/dist/video-player.css">

<script>
  const { VideoPlayer } = window.VideoPlayer
  // Kullan
</script>

Lazy Loading

import { lazy, Suspense } from 'react'

const VideoPlayer = lazy(() =>
  import('@alper/video-player').then(m => ({ default: m.VideoPlayer }))
)

function App() {
  return (
    <Suspense fallback={<div>Video player yükleniyor...</div>}>
      <VideoPlayer src="/video.mp4" />
    </Suspense>
  )
}

Code Splitting

// Route-based splitting
import { lazy } from 'react'

const VideoPage = lazy(() => import('./pages/VideoPage'))

// Router
<Route path="/video" element={<VideoPage />} />

💡 En İyi Pratikler

1. Video Dosyası Optimizasyonu

# FFmpeg ile video optimizasyonu
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium \
  -c:a aac -b:a 128k -movflags +faststart output.mp4

2. Poster Resmi Kullanımı

Her zaman poster resmi ekleyin:

<VideoPlayer
  src="/video.mp4"
  poster="/poster.jpg"  // İlk frame veya özel tasarım
/>

3. Loading State Yönetimi

const [videoLoading, setVideoLoading] = useState(true)

<VideoPlayer
  src="/video.mp4"
  onLoadedMetadata={() => setVideoLoading(false)}
/>

4. Error Boundaries

import { ErrorBoundary } from 'react-error-boundary'

<ErrorBoundary fallback={<div>Video hatası</div>}>
  <VideoPlayer src="/video.mp4" />
</ErrorBoundary>

5. Accessibility

<VideoPlayer
  src="/video.mp4"
  subtitles={subtitleTracks}  // Altyazı ekle
  // ARIA labels otomatik eklenir
/>

🎓 Örnek Projeler

Next.js ile Kullanım

// pages/video.tsx
import dynamic from 'next/dynamic'
import '@alper/video-player/styles.css'

const VideoPlayer = dynamic(
  () => import('@alper/video-player').then(m => m.VideoPlayer),
  { ssr: false }
)

export default function VideoPage() {
  return (
    <div>
      <h1>Video Sayfası</h1>
      <VideoPlayer src="/videos/demo.mp4" />
    </div>
  )
}

Gatsby ile Kullanım

// src/pages/video.tsx
import React from 'react'
import { VideoPlayer } from '@alper/video-player'
import '@alper/video-player/styles.css'

const VideoPage = () => {
  return (
    <div>
      <h1>Video Sayfası</h1>
      <VideoPlayer src="/videos/demo.mp4" />
    </div>
  )
}

export default VideoPage

Vite ile Kullanım

// src/App.tsx
import { VideoPlayer } from '@alper/video-player'
import '@alper/video-player/styles.css'

function App() {
  return (
    <VideoPlayer src="/video.mp4" />
  )
}

export default App

📝 SSS (Sıkça Sorulan Sorular)

Video oynatılmıyor, ne yapmalıyım?

  1. Console'da hata kontrolü yapın
  2. CORS ayarlarını kontrol edin
  3. Video dosya formatını kontrol edin (MP4, WebM desteklenir)
  4. URL'in doğru olduğundan emin olun

HLS streaming çalışmıyor?

  • hls.js'in yüklendiğinden emin olun: npm install hls.js
  • URL'in .m3u8 uzantılı olduğunu kontrol edin
  • Tarayıcı console'unda hata kontrolü yapın

Otomatik oynatma çalışmıyor?

Modern tarayıcılar, muted olmadan otomatik oynatmaya izin vermez:

<VideoPlayer src="video.mp4" autoplay muted />

iOS'ta tam ekran native player açılıyor?

Bu iOS Safari'nin varsayılan davranışıdır ve değiştirilemez. İOS native player'ı kullanır.

Altyazılar görünmüyor?

  • Altyazı dosyasının CORS header'larına sahip olduğundan emin olun
  • Format kontrolü yapın (VTT veya SRT)
  • URL'in doğru olduğunu kontrol edin

Bundle boyutunu nasıl azaltırım?

  • hls.js'i optional olarak bırakın (sadece HLS kullanıyorsanız)
  • Tree-shaking için ES Module import kullanın
  • Lazy loading kullanın

Kendi ikonlarımı kullanabilir miyim?

Evet, CSS ile override edebilirsiniz veya kütüphaneyi fork edip özelleştirebilirsiniz.