Sunucu Maliyetlerini Azaltmanın Yenilikçi Yaklaşımı
Modern web uygulamalarında video içeriği paylaşımı giderek artarken, sunucu tarafında video işleme maliyetleri de exponansiyel olarak yükseliyor. Geleneksel yaklaşımda, kullanıcılar büyük video dosyalarını sunucuya yükler ve tüm sıkıştırma işlemleri sunucu kaynaklarını tüketir.
Giriş ve Problem Tanımı
Günümüzün Video İşleme Sorunu
Video paylaşım platformları ve web uygulamaları, kullanıcıların yüklediği ham video dosyalarını işlemek için önemli miktarda sunucu kaynağı ayırmak zorunda kalıyor.
Video Sıkıştırma İçin CPU Hesaplama Maliyetleri
Video kodlama işlemlerinin yüksek işlem karmaşıklığı nedeniyle enerji talebi önemli ölçüde artmaktadır ve bu durum kodlama sürecinin yüksek enerji talebine yol açmaktadır. Çevrimiçi video içeriği küresel CO₂ emisyonlarının %1'ine katkıda bulunmakta ve video-on-demand hizmetleri kodlama için veri merkezlerinde büyük sunucu çiftlikleri kullanmaktadır.
Ağırlıklı olarak CPU kodlaması yapan bu veri merkezleri şu anda küresel güç tüketiminin yaklaşık %3'ünü tüketmekte olup, 2025 yılına kadar 1.000 TW'ı aşması ve 1 trilyon ton kömüre eşdeğer olması beklenmektedir.
Startup'lar İçin Kritik Maliyet Sorunu
Özellikle yeni kurulan şirketler için
Client-Side İşleme Çözümü
Client-Side İşleme Nasıl Çalışır?
Geliştirmiş olduğum bu hibrit sistem, kullanıcının tarayıcısında çalışan gelişmiş web teknolojileri kullanılarak gerçekleştirilir.
Bu süreç üç ana bileşen üzerinde çalışır:
MediaRecorder API
Tarayıcının doğal codec'lerini kullanarak ilk sıkıştırma işlemini yaparWebAssembly (WASM)
FFmpeg kütüphanesini tarayıcıda çalıştırarak native performans sağlarHLS Segmentasyon
Videoyu küçük parçalara bölerek adaptif streaming ve hızlı yükleme sağlarHibrit Sıkıştırma Yaklaşımı
Doğrudan FFmpeg.wasm kullanımı yüksek işlemci gücü gerektirdiğinden çoğu kişisel cihaz için uygun değildir. MediaRecorder API ile gerçekleştirilen ilk sıkıştırma işlemi düşük kaynak tüketimi sağlar ancak çıktı dosyası sunucu yüklemesi için optimize edilmemiştir.
MediaRecorder API'nin ürettiği MP4 dosyalarında MOOV atomu dosya sonunda yer alır, bu durum akış (streaming) için uygun olmayan bir yapı oluşturur. Bu sorunu çözmek için ikinci bir işleme aşaması gereklidir.
İlk aşamada boyutu küçültülmüş dosya artık FFmpeg.wasm ile işlenebilir duruma gelir. Bu aşamada isteğe bağlı olarak ek sıkıştırma uygulanabilir ve dosya HLS formatına dönüştürülerek akış için optimize edilebilir.
Segment Tabanlı Yükleme: Sıkıştırma işlemi tamamlandıktan sonra, video dosyası HLS formatında küçük segment dosyalarına (.ts uzantılı) bölünür ve bu segmentler sunucuya parça parça yüklenir. Bu yaklaşım bant genişliği kullanımını önemli ölçüde azaltır, çünkü ham video dosyası yerine optimize edilmiş segmentler aktarılır.
Sunucu Yükü Azalması
Bant Genişliği Tasarrufu
Maliyet Optimizasyonu
Sunucu kaynaklarının daha verimli kullanılması ve bant genişliği tasarrufu, toplam işletme maliyetlerini %75'e kadar düşürebilir.
Maliyet Analizi
| Maliyet Kalemi | Geleneksel Yaklaşım | Client-Side Optimizasyon | Tasarruf |
|---|---|---|---|
| Sunucu CPU (aylık) | $500 | $0 | $500 (%100) |
| Bant Genişliği (aylık) | $300 | $60 | $240 (%80) |
| Depolama (aylık) | $200 | $200 | $0 (%0) |
| Toplam Aylık Maliyet | $1,000 | $260 | $740 (%74) |
Teknolojik Altyapı
WebAssembly (WASM)
// FFmpeg.wasm başlatma
const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({
log: true,
progress: ({ ratio }) => {
console.log(`İlerleme: ${Math.round(ratio * 100)}%`);
}
});
await ffmpeg.load();
MediaRecorder API
// MediaRecorder ile sıkıştırma
const options = {
mimeType: 'video/webm;codecs=h264',
videoBitsPerSecond: 1000000 // 1 Mbps
};
const mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.start();
HLS (HTTP Live Streaming) Formatı
HLS formatı, videoları küçük segmentlere bölerek adaptif streaming sağlar. Bu yaklaşım hem bant genişliği kullanımını optimize eder hem de kullanıcı deneyimini iyileştirir.
// HLS formatına dönüştürme
await ffmpeg.run(
'-i', 'input.mp4',
'-c:v', 'libx264',
'-preset', 'superfast',
'-crf', '30',
'-f', 'hls',
'-hls_time', '4',
'-hls_list_size', '0',
'-hls_segment_filename', 'segment%03d.ts',
'playlist.m3u8'
);
İş Akışı
Dosya Analizi
Video dosyasının boyutu, formatı ve cihaz türü analiz edilerek en uygun işleme stratejisi belirlenir.
- Dosya boyutu kontrolü
- Format uyumluluğu
- Cihaz optimizasyonu
MediaRecorder ile Sıkıştırma
Tarayıcının yerleşik MediaRecorder API'si kullanılarak ilk sıkıştırma işlemi gerçekleştirilir.
- Gerçek zamanlı sıkıştırma
- Kalite optimizasyonu
- Hızlı işleme
FFmpeg.wasm ile Dönüştürme
FFmpeg.wasm kullanılarak video HLS formatına dönüştürülür ve segmentlere ayrılır.
- HLS segmentasyonu
- Adaptif streaming
- Çoklu kalite seçenekleri
Sıralı Yükleme
İşlenmiş video segmentleri sıralı olarak sunucuya yüklenir ve streaming için hazırlanır.
- Parçalı yükleme
- Hata toleransı
- İlerleme takibi
Teknik Uygulama Detayları
1. Video Yükleme ve Analiz
Kullanıcı tarafından seçilen video dosyası önce analiz edilir. Dosya boyutu, format ve cihaz türüne göre işleme stratejisi belirlenir.
// Video analizi ve strateji belirleme
const analyzeVideo = (videoFile) => {
const fileSizeMB = videoFile.size / (1024 * 1024);
const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
const isMP4 = videoFile.type === 'video/mp4';
if (isMP4 && fileSizeMB < 6) {
return 'DIRECT_UPLOAD'; // Doğrudan yükle
} else if (!isMobile && fileSizeMB < 200) {
return 'FFMPEG_ONLY'; // Sadece FFmpeg
} else {
return 'DUAL_COMPRESSION'; // MediaRecorder + FFmpeg
}
};
2. MediaRecorder ile İlk Sıkıştırma
Büyük dosyalar için önce MediaRecorder API kullanılarak ilk sıkıştırma yapılır. Bu adım özellikle mobil cihazlarda kritiktir.
// MediaRecorder ile sıkıştırma
const compressWithMediaRecorder = async (videoFile) => {
const video = document.createElement('video');
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Hedef çözünürlük belirleme
const targetWidth = 1280;
const targetHeight = 720;
const targetBitrate = 1000000; // 1 Mbps
canvas.width = targetWidth;
canvas.height = targetHeight;
const stream = canvas.captureStream();
const recorder = new MediaRecorder(stream, {
mimeType: 'video/webm;codecs=h264',
videoBitsPerSecond: targetBitrate
});
return new Promise((resolve) => {
const chunks = [];
recorder.ondataavailable = (e) => chunks.push(e.data);
recorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
resolve(blob);
};
recorder.start();
// Video işleme mantığı...
});
};
3. FFmpeg.wasm ile HLS Dönüşümü
İkinci aşamada FFmpeg.wasm kullanılarak video HLS formatına dönüştürülür ve ek sıkıştırma uygulanır.
// FFmpeg.wasm ile HLS dönüşümü
const convertToHLS = async (videoFile) => {
// FFmpeg yükleme
const ffmpeg = createFFmpeg({ log: true });
await ffmpeg.load();
const inputName = 'input.webm';
const compressedName = 'compressed.mp4';
const playlistName = 'playlist.m3u8';
// Dosyayı FFmpeg'e yükle
ffmpeg.FS('writeFile', inputName, await fetchFile(videoFile));
// H264 ile sıkıştırma
await ffmpeg.run(
'-i', inputName,
'-c:v', 'libx264',
'-preset', 'superfast',
'-crf', '30',
'-c:a', 'aac',
'-b:a', '128k',
compressedName
);
// HLS formatına dönüştürme
await ffmpeg.run(
'-i', compressedName,
'-c:v', 'copy',
'-c:a', 'copy',
'-f', 'hls',
'-hls_time', '4',
'-hls_list_size', '0',
'-hls_segment_filename', 'segment%03d.ts',
playlistName
);
// Segmentleri topla
const segments = [];
const m3u8Content = ffmpeg.FS('readFile', playlistName);
segments.push(new File([m3u8Content], playlistName));
let segmentIndex = 0;
while (true) {
try {
const segmentName = `segment${String(segmentIndex).padStart(3, '0')}.ts`;
const segmentData = ffmpeg.FS('readFile', segmentName);
segments.push(new File([segmentData], segmentName));
segmentIndex++;
} catch {
break;
}
}
return segments;
};
4. Segmentli Yükleme
HLS segmentleri sunucuya parça parça yüklenir. Bu yaklaşım hem güvenilirlik hem de performans açısından avantaj sağlar.
// Segmentli yükleme
const uploadHLSSegments = async (segments) => {
// HLS dizini oluştur
const sessionData = await fetch('upload-media.php', {
method: 'POST',
body: new FormData().append('action', 'create_hls_dir')
}).then(r => r.json());
const hlsDir = sessionData.hls_dir;
// Her segmenti yükle
for (let i = 0; i < segments.length; i++) {
const formData = new FormData();
formData.append('action', 'upload_hls_file');
formData.append('hls_dir', hlsDir);
formData.append('file_index', i);
formData.append('hls_file', segments[i]);
await fetch('upload-media.php', {
method: 'POST',
body: formData
});
// İlerleme güncelleme
const progress = ((i + 1) / segments.length) * 100;
updateProgress(progress);
}
return sessionData.hls_url;
};
Sonuç ve Öneriler
Temel Çıkarımlar
Başlıca Faydalar:
- Maliyet Optimizasyonu: %77.5'e varan toplam maliyet azalması
- Ölçeklenebilirlik: Sunucu kaynaklarından bağımsız büyüme
- Çevresel Etki: Daha az enerji tüketimi
- Startup: Büyük sunucu yatırımları olmadan video streaming altyapısı kurabilme
Uygulama Önerileri:
- Aşamalı Geçiş: Mevcut sistemlere entegrasyon için hibrit yaklaşım
- Cihaz Optimizasyonu: Mobil ve masaüstü için farklı stratejiler
- Fallback Mekanizması: Eski tarayıcılar için sunucu tarafı yedekleme
- Performans İzleme: Sürekli optimizasyon için metrik takibi
Gelecek Perspektifi
WebAssembly teknolojisinin gelişimi ve tarayıcı desteğinin artmasıyla, client-side video işleme daha da güçlü hale gelecektir. AV1 codec desteği ve GPU hızlandırması gibi yenilikler, bu alandaki potansiyeli daha da artıracaktır.