1347 lines
28 KiB
Markdown
1347 lines
28 KiB
Markdown
# 📚 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
|
||
|
||
```bash
|
||
npm install @alper/video-player
|
||
```
|
||
|
||
### Yarn ile Kurulum
|
||
|
||
```bash
|
||
yarn add @alper/video-player
|
||
```
|
||
|
||
### Peer Dependencies
|
||
|
||
Video player, React 18+ gerektirmektedir:
|
||
|
||
```bash
|
||
npm install react react-dom
|
||
```
|
||
|
||
### Opsiyonel Bağımlılıklar
|
||
|
||
HLS streaming desteği için hls.js otomatik olarak yüklenecektir (gerektiğinde):
|
||
|
||
```bash
|
||
npm install hls.js # Opsiyonel
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 Hızlı Başlangıç
|
||
|
||
### Basit Kullanım
|
||
|
||
```tsx
|
||
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:
|
||
|
||
```tsx
|
||
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
|
||
|
||
```typescript
|
||
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
|
||
|
||
```typescript
|
||
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
|
||
|
||
```typescript
|
||
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
|
||
|
||
```typescript
|
||
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:
|
||
|
||
```tsx
|
||
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:
|
||
|
||
```tsx
|
||
<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:
|
||
|
||
```tsx
|
||
<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):
|
||
|
||
```tsx
|
||
<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:
|
||
|
||
```tsx
|
||
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:
|
||
|
||
```tsx
|
||
<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:
|
||
|
||
```tsx
|
||
<VideoPlayer
|
||
src="/videos/content.mp4"
|
||
language="tr"
|
||
/>
|
||
```
|
||
|
||
### 8. Klavye Kısayolları Devre Dışı
|
||
|
||
Bazı durumlarda klavye kısayollarını kapatmak isteyebilirsiniz:
|
||
|
||
```tsx
|
||
<VideoPlayer
|
||
src="/videos/presentation.mp4"
|
||
keyboardShortcuts={false}
|
||
/>
|
||
```
|
||
|
||
### 9. Responsive Layout
|
||
|
||
Farklı ekran boyutlarında:
|
||
|
||
```tsx
|
||
<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:
|
||
|
||
```tsx
|
||
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:
|
||
|
||
```css
|
||
: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
|
||
|
||
```css
|
||
:root {
|
||
--player-primary: #3b82f6;
|
||
--player-primary-hover: #2563eb;
|
||
--player-primary-active: #1d4ed8;
|
||
--player-bg: #0f172a;
|
||
}
|
||
```
|
||
|
||
```tsx
|
||
// veya JavaScript ile
|
||
<VideoPlayer
|
||
src="/videos/demo.mp4"
|
||
theme={{
|
||
primaryColor: '#3b82f6',
|
||
accentColor: '#2563eb',
|
||
backgroundColor: '#0f172a',
|
||
textColor: '#f1f5f9'
|
||
}}
|
||
/>
|
||
```
|
||
|
||
#### Yeşil Tema
|
||
|
||
```css
|
||
:root {
|
||
--player-primary: #10b981;
|
||
--player-primary-hover: #059669;
|
||
--player-primary-active: #047857;
|
||
}
|
||
```
|
||
|
||
#### Mor Tema
|
||
|
||
```css
|
||
: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:
|
||
|
||
```css
|
||
/* 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:
|
||
|
||
```tsx
|
||
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:
|
||
|
||
```tsx
|
||
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:
|
||
|
||
```tsx
|
||
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ü:
|
||
|
||
```tsx
|
||
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ı
|
||
|
||
```tsx
|
||
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
|
||
|
||
```tsx
|
||
// 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:
|
||
|
||
```tsx
|
||
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:
|
||
|
||
```tsx
|
||
<VideoPlayer
|
||
src="https://example.com/stream/playlist.m3u8"
|
||
/>
|
||
```
|
||
|
||
### Manuel HLS Kontrolü
|
||
|
||
```tsx
|
||
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:
|
||
|
||
```tsx
|
||
<VideoPlayer
|
||
src="https://example.com/stream/playlist.m3u8"
|
||
// Kalite menüsü otomatik görünecek
|
||
/>
|
||
```
|
||
|
||
### HLS Hata Yönetimi
|
||
|
||
```tsx
|
||
<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:
|
||
|
||
```tsx
|
||
<div className="mobile-container">
|
||
<VideoPlayer
|
||
src="/videos/mobile.mp4"
|
||
// Mobil cihazlarda touch gesture'lar otomatik aktif
|
||
/>
|
||
</div>
|
||
```
|
||
|
||
```css
|
||
.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ı
|
||
|
||
```tsx
|
||
<div style={{
|
||
width: '100%',
|
||
aspectRatio: '16/9',
|
||
backgroundColor: '#000'
|
||
}}>
|
||
<VideoPlayer
|
||
src="/video.mp4"
|
||
style={{ width: '100%', height: '100%' }}
|
||
/>
|
||
</div>
|
||
```
|
||
|
||
### Grid Layout ile Çoklu Video
|
||
|
||
```css
|
||
.video-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||
gap: 20px;
|
||
padding: 20px;
|
||
}
|
||
```
|
||
|
||
```tsx
|
||
<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:
|
||
|
||
```tsx
|
||
// 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
|
||
|
||
```tsx
|
||
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:**
|
||
```bash
|
||
npm install hls.js
|
||
```
|
||
|
||
### 6. Performance İpuçları
|
||
|
||
```tsx
|
||
// ❌ 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:
|
||
|
||
```typescript
|
||
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
|
||
|
||
```tsx
|
||
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
|
||
|
||
```tsx
|
||
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
|
||
|
||
```tsx
|
||
<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
|
||
|
||
```bash
|
||
# 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ı
|
||
|
||
```html
|
||
<!-- 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
|
||
|
||
```tsx
|
||
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
|
||
|
||
```tsx
|
||
// 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
|
||
|
||
```bash
|
||
# 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:
|
||
```tsx
|
||
<VideoPlayer
|
||
src="/video.mp4"
|
||
poster="/poster.jpg" // İlk frame veya özel tasarım
|
||
/>
|
||
```
|
||
|
||
### 3. Loading State Yönetimi
|
||
|
||
```tsx
|
||
const [videoLoading, setVideoLoading] = useState(true)
|
||
|
||
<VideoPlayer
|
||
src="/video.mp4"
|
||
onLoadedMetadata={() => setVideoLoading(false)}
|
||
/>
|
||
```
|
||
|
||
### 4. Error Boundaries
|
||
|
||
```tsx
|
||
import { ErrorBoundary } from 'react-error-boundary'
|
||
|
||
<ErrorBoundary fallback={<div>Video hatası</div>}>
|
||
<VideoPlayer src="/video.mp4" />
|
||
</ErrorBoundary>
|
||
```
|
||
|
||
### 5. Accessibility
|
||
|
||
```tsx
|
||
<VideoPlayer
|
||
src="/video.mp4"
|
||
subtitles={subtitleTracks} // Altyazı ekle
|
||
// ARIA labels otomatik eklenir
|
||
/>
|
||
```
|
||
|
||
---
|
||
|
||
## 🎓 Örnek Projeler
|
||
|
||
### Next.js ile Kullanım
|
||
|
||
```tsx
|
||
// 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
|
||
|
||
```tsx
|
||
// 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
|
||
|
||
```tsx
|
||
// 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:
|
||
```tsx
|
||
<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. |