Güvenlik

Bilibili İndirici Mimarisine Yakından Bakış: Hız, DASH ve FFmpeg

Şöyle söyleyeyim, Bir videoyu “indir” düğmesine basıp geçmek kolay. Gerisi? İşte orası karışık. Bilibili tarafında tek bir dosya çekmiyorsunuz zaten — çoğu zaman ses ve görüntü ayrı akıyor, üstüne bir de kimlik doğrulama, hız sınırlaması, anti-hotlink kuralları ve CDN kaprisleri bindirilince tablo bayağı farklılaşıyor. Kısacası iş karmaşık… ama bu karmaşıklığın kendine has bir güzelliği de var açıkçası.

Açık konuşayım, Geçen ay Kadıköy’deki çalışma masamda benzer bir medya akışı sorununu debug ederken şunu fark ettim: Kullanıcıya “basit görünen” şeylerin altında çoğu zaman bayağı sert mühendislik kararları yatıyor. Bilibili için geliştirilen indirme motoru da öyle — dışarıdan bakınca sadece video alıyormuş gibi duruyor, içeride ise AV/BV dönüşümü, DASH parça yönetimi. Son birleştirme adımı var. Oyun motoruna bakıp “sadece kare çiziyor” demek gibi bir şey bu, hani.

💡 Bilgi: Bilibili tarzı platformlarda asıl mesele tek bir büyük dosyayı indirmek değil; doğru akışı bulup ses ile görüntüyü düzgün eşleştirmek, sonra da kullanıcıya tek parça gibi sunmak.

AV’den BV’ye Geçiş Neden Önemliydi?

Bilibili’nin eski AV numaraları tahmin edilebilir bir yapıdaydı. Açık kapı. Botlar için davetiye gibiydi yani. BV sistemine geçiş aslında sadece kozmetik bir isim değişikliği değil; erişimi zorlaştıran, en azından rastgele kazıyıcıların işini yavaşlatan somut bir katman oldu. Çok gösterişli görünmüyor, kabul, ama baya işe yarıyor.

Ben 2023’ün sonlarında yerel bir medya arşivleme aracını denerken benzer bir durumla karşılaştım — düz sayı tabanlı ID’ler loglardan bile okunabiliyor olunca veri seti neredeyse davetiyeye dönüyor. BV yaklaşımı bu yüzden önemliydi; kaba kuvvetle tahmin etmeyi çok daha zahmetli hale getiriyor. Tam güvenlik mi? Değil. Ama saldırganın elini kolaylaştırmıyor, o kesin.

Lafı gevelemeden söyleyeyim: Böyle sistemlerde kimlik mantığını çözmek çoğu zaman indirme tarafının ilk eşiği oluyor. Bu eşik geçilmeden geri kalan her şey — kalite seçimi, altyazı yakalama, manifest çözümlemesi — yarım kalıyor zaten.

Base-58 Mantığı Kaba Görünür Ama İş Görür

BV kodunun temelinde salt okunur bir karakter dizisi var gibi dursa da arka tarafta sabit pozisyonlar, çevirim tabloları ve ufak matematik oyunları bulunuyor. Kasada saklanan anahtarın üstüne renkli bant sarmak gibi bir şey bu. Basit. Ama caydırıcı.

Konu Neden önemli? Sahadaki etkisi
ID dönüşümü Tahmini zorlaştırır Kazıyıcı trafiğini yavaşlatır
Cookie kontrolü Kalite erişimini açar 1080P/4K gibi akışlara kapı verir
Referer denetimi Dış istemcileri sınırlar Basit wget isteklerini boşa düşürür

DASH Akışı: Ses Ayrı, Görüntü Ayrı Olunca Ne Oluyor?

İşin en kilit tarafına geldik. DASH yapısında video ile ses genelde farklı URL’lerden geliyor, ayrı parçalar halinde taşınıyor. Kullanıcı açısından görünmez bu — oynat tuşuna basarsınız, görüntü akar gider. Ama indirici yazarken tablo tamamen değişiyor çünkü iki farklı hattı aynı anda takip edip sonra tekrar tek dosyada toplamanız gerekiyor. Kolay değil.

Açık konuşayım: İlk kez bu yapıyla uğraşırken insanın morali hafif bozuluyor. “Tek link ver, geç” beklentisi çöpe gidiyor çünkü. Ben bunu ilk kez İstanbul’da küçük bir demo servisinde test ettiğimde (Mart 2024’tü), video geldiği halde sesin geciktiği birkaç saçma örnek gördüm — meğer bağlantılar arasındaki eşleşme mantığını yanlış kurmuşuz. Küçük hata, ama sonuç rahatsız edici.

Neden İki Parça Yerine Tek Dosya Beklememeliyiz?

Şöyle ki, DASH’in avantajı esneklik. Ağınız zayıflarsa kalite düşüyor ama yayın kopmuyor; ağ iyiyse yüksek bitrate’e çıkabiliyor. Dezavantaj ise downloader cephesinde ortaya çıkıyor: tek URL’nin peşinden koşmuyorsunuz artık, manifest içinden doğru video ve audio segmentlerini seçip bunları uygun sırayla indiriyorsunuz (şaşırtıcı ama gerçek). Bence burada en pratik zihinsel model şu — DASH’i kargo şirketi gibi düşünün. Ürün tek kutuda gelmiyor olabilir; bazen önce koli bandı gelir, sonra kitap, en son fatura… Siz hepsini depoda toparlarsınız.

Durun, bir saniye.

# Mantık olarak kabaca:
# 1) Playurl/manifest çek
# 2) Video + audio stream URL'lerini ayıkla
# 3) Paralel indir
# 4) FFmpeg ile yeniden paketle
ffmpeg -i video.m4s -i audio.m4s -c copy -map 0:v:0 -map 1:a:0 output.mp4

Neden Sadece requests Yetmiyor?

Araya gireyim: Klasik senkron HTTP istemcileri böyle projelerde çabuk tıkanıyor. Aynı anda meta veri çekmek, kapak almak, stream listesi çözmek ve segment indirmek istiyorsanız bekleme süreleri üst üste biniyor… sistem ağırlaşıyor, ağırlaşıyor, ağırlaşıyor. Geçen yıl Ankara’daki bir kurumsal raporlama projesinde benzer yük altında httpx + asyncio kombinasyonunu denemiştim — fark barizdi. Bağlantıları doğru yönettiğinizde CPU’dan çok ağ bekleme süresi belirleyici oluyor (bu beni çok şaşırttı). Yani darboğaz bazen işlemci değil, su borusu daralması gibi bir şey.

Eşzamanlılık Güzel Ama Düzensizse Baş Belasıdır

  • Pozitif taraf: Aynı anda birçok isteği döndürerek toplam süreyi ciddi azaltır.
  • Pozitif taraf: TCP bağlantısını yeniden kullanmak TLS maliyetini düşürür.
  • Eksi taraf: Fazla agresif istek atarsanız rate limit veya blok yersiniz.
  • Eksi taraf: Loglama zayıfsa hata ayıklamak çileye döner.

Neyse uzatmayayım. İyi tasarlanmış async yapı ile kötü tasarlanmış async yapı arasındaki fark gece-gündüz kadar net oluyor. Birincisi uçuyor. İkincisi ise sistemi kendi ayağına dolandırıyor, hem de güzel güzel.

Bunu biraz açayım. Bu konuyla ilgili TikTok’ta Aynı Videoyu Farklı Kılmanın Akıllı Yolları yazımıza da göz atmanızı tavsiye ederim. Daha fazla bilgi için AI Arama Savaşı: Perplexity, SearchGPT ve Claude yazımıza bakabilirsiniz.

Muxing Katmanı: FFmpeg Burada Neyi Çözüyor?

Ne yalan söyleyeyim, Muxing kısmı aslında hikayenin en tatmin edici bölümü olabilir — dağıtılmış parçaları alıp kullanıcıya tek MP4 vermek tam burada tamamlanıyor (ben de ilk duyduğumda şaşırmıştım) (bu konuda ikircikliyim). Üstelik yeniden kodlama yapılmadığı için kalite kaybı yaşamıyorsunuz; elde edilen sonuç ham malzemeye oldukça sadık kalıyor. Güzel.

Bana göre bunun iyi yani şu: CPU’ya gereksiz yük bindirmiyorsunuz (ki bu çoğu kişinin gözünden kaçıyor). Bir startup ortamında bu altın değerinde çünkü her ekstra transcode işi faturaya yazılıyor. Tahmin eder misiniz? Kurumsal tarafta ise mesele biraz daha farklı; ölçek büyüdükçe aynı işlem binlerce kez tekrarlandığında kaynak yönetimi çok daha kritik bir hal alıyor, hani “önemsiz görünen şey” çarpıyla büyüyünce önemsiz kalmıyor.

FFmpeg’in stream copy modu kulağa teknik gelebilir ama özünde yaptığı şey basit: yeniden pişirmeden tabağa koymak.

Kullanıcı Deneyimi Tarafını Hafife Almayın

Kullanıcı “dosyam hazır mı?” diye bakar. Sistem arkada beş ayrı servis dolaştırsa bile onun gözünde olay nettir: ya vardır, ya yoktur. Bu yüzden backend hızlı olsa bile hata mesajlarının anlaşılır olması şart. Bir de şu var: başarısız birleştirme denemelerinde sessiz kalmak çok kötü fikir. Ben bunu küçük bir yan projede bizzat yaşadım — çıktı üretilemediğinde arayüz boş kaldığı için kullanıcılar sanki uygulama çökmüş sandılar. Halbuki sadece referanslardan biri eksikti. Küçük detay, büyük sinir bozucu etki (evet, doğru duydunuz)

Kötü Senaryolar İçin Savunma Stratejisi Nasıl Kurulur?

Böyle araçlarda yalnızca mutlu yolculuğu planlamak yetmiyor. Referer değişir, cookie süresi dolar, CDN cevap vermez, segmentlerden biri bozuk gelir — yani sürpriz bol. Savunmacı programlama şart. İndirme motoru nazik davranmalı: önce retry, sonra alternatif rota, en sonunda kullanıcıya dürüst hata mesajı. AI Ajanlarıyla Yazmak: Değer mi, Hangi Noktada Tıkanıyor? yazımızda bu konuya da değinmiştik.

Ben İzmir’de yaşayan bir arkadaşımın hazırladığı medya servisinde şunu görmüştüm: proxy havuzu vardı. Sağlık kontrolü yoktu. Sonuç? Sistem canlı görünüyordu fakat isteklerin yarısı duvara tosluyordu. Sağlık kontrolü olmadan proxy havuzu araba lastiğine hava basmadan uzun yola çıkmaya benziyor — yürür gibi yapar, ama ilerlemez.

Şimdi gelelim pratik ayrımlara:

  • Küçük bir startup için: düşük maliyet, az bağımlılık, sade queue yapısı daha mantıklı. Fazla karmaşıklık erken aşamada gereksiz yük bindirir.
  • Büyük ölçek / enterprise için: rate limiting, distributed job queue, izleme panelleri ve merkezi log toplama şart. (bu kritik)
  • Saha operasyonunda: başarısız işlerin tekrar denenmesi kadar neden başarısız olduğunu saklamak da önemli. (bence en önemlisi)
  • Kullanıcı bakımından: kaliteli hata mesajları destek talebini ciddi azaltır.

Bence En Zor Kısım Performans Değil… Tutarlılık

Aynen öyle. Herkes hızdan bahsediyor. Tutarlılık ise sessiz kahraman gibi duruyor köşede. Mesela bazı videolarda metadata anlık güncellenirken segment listesi biraz geriden gelebiliyor — siz ise tutarsız bu dünyada doğru çıktıyı garanti etmeye çalışıyorsunuz. Kolay değil, gerçekten.

Bu konuda yüzde yüz emin değilim (buna dikkat edin). Sanırım en büyük fark tam burada ortaya çıkıyor: hızlı çalışan sistemlerle sağlam çalışan sistemler aynı şey değil (şaşırtıcı ama gerçek). Ben geçmişte bunu test ederken özellikle uzun kuyruklarda bitmeyen görevlerin sistemi nasıl kirlettiğini gördüm — hızlıydılar, evet, ama temiz değillerdi. İki farklı şey bunlar.

Bir dakika, şunu da ekleyeyim: böyle projelerde gözden kaçan şey genelde concurrency limit oluyor. Limit olmazsa servis kendini yer; limit fazla sıkarsa kullanıcı bekler (ilk duyduğumda inanamadım). İnce ayar lazım — trafikte orta şerit gibi, tam o his. Hem performans hem güvenilirlik aynı pakette olunca iş güzelleşiyor. Yoksa sadece “çok paralel” olmak hiçbir şeyi kurtarmıyor. Kağıt üstünde süper, pratikte… göreceğiz artık.

Sıkça Sorulan Sorular

Bilibili videolarında neden ses ve görüntü ayrı geliyor?

Bak şimdi, Bilibili çoğunlukla DASH kullanıyor. Bu yapı sesi. Görüntüyü ayrı akışlar halinde gönderiyor ki kalite değişimleri daha rahat yönetilsin. Downloader’ın işi de bu iki parçayı sonradan düzgün biçimde birleştirmek oluyor.

Peki neden?

Muxing sırasında kalite kaybı olur mu?

Eğer yeniden kodlama yapmazsanız genelde kalite kaybı olmaz. FFmpeg’in stream copy modu tam burada işe yarar ; mevcut veriyi olduğu gibi yeni kapsayıcıya taşır.

Neden bazı istekler403 veya412 dönduruyor?

Bunun nedeni çoğu zaman referer kontrolü cookie doğrulaması ya da anti-bot mekanizmalarıdır ។ Bazense aşırı sık istek attığınız için geçici korumaya takılırsınız.

Küçük proje ile kurumsal mimari arasında en büyük fark ne?

Eh, Küçük projede sade çözüm yeterli ; enterprise tarafta ise izleme, retry stratejisi, dağıtık kuyruklar ve sağlık kontrolleri gerekir. Ölçek büyüdükçe basit görünen hatalar pahalı hale gelir.

Kaynaklar ve İleri Okuma

N_m3u8DL-RE GitHub Sayfası

[p]Deploy Sonrası Yavaşlayan Metodu Bulan Küçük Bir Araç[/a]Postgres LISTEN/NOTIFY Debugging’i Nihayet Rahatlatan Yöntem[/a]

Aşkın KILIÇ

20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

AZ-305AZ-104AZ-500AZ-400DP-203AI-102

Bu içerik işinize yaradı mı?

Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

Haftalık Bülten

Her pazar özenle seçilmiş teknoloji yazıları doğrudan e-postanıza gelsin.

← Onceki Yazi
TikTok’ta Aynı Videoyu Farklı Kılmanın Akıllı Yolları
Sonraki Yazi →
Bilibili İndirmenin Perde Arkası: DASH, M4S ve FFmpeg

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Haftalık Bülten

Azure, DevOps ve Yapay Zeka dünyasındaki en güncel içerikleri her hafta doğrudan e-postanıza alın.

Spam yok. İstediğiniz zaman iptal edebilirsiniz.
📱
Uygulamayı Yükle Ana ekrana ekle, çevrimdışı oku
Kategoriler
Ara
Paylaş
İçindekiler
← TikTok’ta Aynı Videoyu Farklı ...
Bilibili İndirmenin Perde Arka... →
📩

Gitmeden önce!

Her pazar özenle seçilmiş teknoloji yazıları ve AI haberleri doğrudan e-postanıza gelsin. Ücretsiz, spam yok.

🔒 Bilgileriniz güvende. İstediğiniz zaman ayrılabilirsiniz.

📬 Haftalık bülten: Teknoloji + AI haberleri