Cumartesi, Temmuz 11, 2009

red5, rtmp ve flash ile ilgili öğrendiklerim

uzun zamandır bloğumu ihmal ettiğimi farkettim, ve işin ilginci son 5-6 aydır red5 ile yatıp red5 ile kalkan bir insan olarak nedense hiç red5 ile ilgili bir girdi yapmamışım. öğrendiklerimi tek bir girdide toplayıp acısını çıkarayım dedim.

öncelikle rtmp açık bir protokol değil, dolayısıyla red5 bir tersine mühendislik ürünü, facebook'un bile red5 tercih ettiğini düşünecek olursak oldukça da başarılı bir ürün. bu arada adobe 2009 yılının ortasında rtmp belirtimlerini açacağını duyurmuş olmasına rağmen henüz açmadı.

rtmp bağlantıları tcp soketleri üzerinden kuruluyor, neden udp değil anlamış değilim, tcp'nin kayıpsızlığı canlı video aktarımlarında biraz sıkıntı yaratıyor. yetersiz bağlantılarda gecikmeler kaçınılmaz hale geliyor. gelen yayına (stream) müdahale edemiyorsunuz, sadece izleyenlere giden yayında paket düşürebiliyorsunuz ki elinizi koda bulaştırmadan bu paket düşürme işlerini yapamıyorsunuz.

elinizi koda sokma sıkıntısı ölçeklendirme ve red5'den red5'e yayın aktarma konusunda da var. ölçeklendirme için terracotta kullanıyor insanlar[1], sunucudan sunucuya yayın aktarma işi için de örnek kod bulmak mümkün değil, teoride nasıl yapılabileceğini e-posta listesinde bulmak mümkün[2], yani kolları biraz sıvamak şart bu işlere girmeniz gerekirse.

red5 ön tanımlı olarak, 5080'den http, 1935'den rtmp, 8443'den rtmps ve 8088'den rtmpt sunuyor. bu durumda şirketlerin güvenlik duvarlarına takılıyorsunuz doğal olarak. çoğu yerde sadece 80 portuna izin veriliyor. biz vidi için red5 üzerinden axis ile hem bir webservisi sunuyoruz hem de rtmp hizmeti sunuyoruz. yani en az 2 port açmamız gerekiyordu aynı sunucu üzerinde. bu engeli de vidi uygulamasının web.xml'inde bazı servlet ayarları yaparak aştık[3].

rtmpt aslında http'den başka bir şey değil. yayın verileri peşpeşe http paketleri olarak aktarılıyor. dolayısıyla aynı port üzerinden hem webservisini hem rtmpt sunmak için şu servlet ayarlarını eklemeniz yeterli:


<servlet>
<servlet-name>rtmpt</servlet>
<servlet-class>org.red5.server.net.rtmpt.RTMPTServlet</servlet>
<load-on-startup>1</load>
</servlet>

<servlet-mapping>
<servlet-name>rtmpt</servlet>
<url-pattern>/fcs/*</url>
</servlet-mapping>

<servlet-mapping>
<servlet-name>rtmpt</servlet>
<url-pattern>/open/*</url>
</servlet-mapping>

<servlet-mapping>
<servlet-name>rtmpt</servlet>
<url-pattern>/close/*</url>
</servlet-mapping>

<servlet-mapping>
<servlet-name>rtmpt</servlet>
<url-pattern>/send/*</url>
</servlet-mapping>

<servlet-mapping>
<servlet-name>rtmpt</servlet>
<url-pattern>/idle/*</url>
</servlet-mapping>


iletişimi ssl ile şifrelemek için yaptığımız çalışmalarda da anladık ki aslında rtmps diye bir şey yok, rtmps=rtmpts=https demek mümkün. ssl işinde baya zorlandık, 0.7.4'de çalışmayınca 0.8 sürümlerine geçtik, orada da çalışmadı, bir düzine deneme sonrası sadece 0.8-RC2 versiyonunda çalıştırmayı başarabildik. bu versiyonun üstünde de altında da problemler yaşadık.

flash player tarafında ise, uygulama tasarımına girişmeden flash kısıtlarını araştırmak da fayda var. örneğin flash'ın izin kutucuklarının boyutu sabit, bu boyutun altında bir flash yaratırsanız kullanıcı kamerayı kullanma iznini veremiyor, ve eğer kullanıcı hatırla kutucuğunu işaretlememişse her flash için bu izni ayrı ayrı vermesi gerekiyor. eğer ekranda flashın tamamı gözükmüyorsa flash üzerindeki herhangi bir düğmeye tıklayamıyorsunuz. tam ekran yapma gibi işlevleri kullanıcı bir yere tıklamadıkça yapamıyorsunuz. bir de flash'i içine entegre ettiğiniz siteden başka bir alan adından sunacaksanız atmanız gereken epey bir takla var, flash'ın güvenlik politikası ile ilgili belgeleri bir okuyun derim ben. böyle ufak detaylar uygulama tasarımını tamamen değiştirebiliyor.

sunucuyla flash istemciler arasındaki komut iletişimi için shared object yerine uzak fonksiyon çağrılarını kullanmakta fayda var, red5'in shared object gerçeklemesinde sıkıntılar var.

bunun dışında geliştirme ortamı olarak linux üzerinde çalışan insanlar olarak actionscript yazmak da çok zorlanmadık, flex3sdk ve derlemeler için ant kullanımı yeterli oldu. ama ince çizimler yapacağım, tasarımla uğraşacağım diyorsanız linux çok doğru bir tercih değil.

red5'i kapalı devre sistemler için kullanıp kullanamacağımızı görmek için kalite konusunda sınırıları zorlama durumunda da kaldık, gördük ki flash player ile dvd kalitesine (480 satır) kadar çıkmak mümkün. dvd normalde 7-8 mbit/s'lik bir bant genişliği gerektiriyor, red5'de ise bant genişliği kontrollerini aktif hale getirmeden 1mbit/s'lik upload hızını aşamıyorsunuz, bant genişliği kontrollerini aktif hale getirebilmek için de biraz kod yazmanız gerekiyor.

yalnız 480 satırdan sonra flash oynatıcı çatlamaya başlıyordu. bir de flash oynatıcı ile görüntüyü sadece h.263 veya vp6 kodlayabiliyorsunuz. flash oynatıcı h.264 kodlayamıyor ama oynatırken h.264'u çözebiliyor. veri miktarını azaltmak için h.264 kullanmak elzem. bu arada xuggler[4] ile gelen yayını dağıtmadan kodlamasını değiştirmek mümkün. ama biz gönderirken h.264 gönderelim dedik flash oynatıcı dışında neyle yayın gönderebiliriz diye araştırdık. rtmp'nin belirtimlerinin kapalı olmasından olsa gerek pek bir alternatif yoktu. yaptığımız araştırmalarda rtsp'nin çok yaygın kullanıldığını gördük. eğer rtmp yayınını rtsp'ye dönüştüren bir ara uygulama olsa baya artacak alternatif sayısı aslında.

vlc 0.9 sonrasında rtmp izleme desteği geliyordu, ama sunucuya görüntü gönderilemiyordu. bu arada vlc'nin red5 ile çalışması için vlc kodunda bazı kontrolleri kaldırıp yeniden derlememiz gerekti. vlc ile flash oynatıcıdan çok daha başarılı bir görüntü akışı elde ettik, ama çok daha fazla gecikme gibi bir bedeli vardı. gecikmenin tam nedenini anlayacak kadar bakamadık henüz. görüntü aktarımı için java'yla yazılmış bir kod bulduk, ama yeterince olgun olmadığını düşündüğümüz için tercih etmedik. sonunda adobe flash media encoder kullanmak durumunda kaldık, bu da windows bağımlılığı anlamına geldiğinden hiç istemediğimiz bir durumdu. bu arada adobe flash media encoder ile red5'e rtmpt üzerinden yayın aktarmak için red5'te "content type" ile ilgili bir kontrolü kaldırıp yeniden derlememiz gerekti.

kalite denilince kodlamadan ziyade görüntüyü taşıdığınız arabirimler önem kazanıyor. red5'e görüntü aktarmak için bilgisayarınızın görüntü kaynağını webcam olarak algılaması gerekiyor. eğer bir yakalayıcı (capture) kart kullanırsanız televizyona verebildiğiniz herhangi bir görüntüyü (bir televizyon kanalını, bilgisayar ekranı görüntüsünü, veya composite çıkışı olan herhangi bir kamerayı, dvr kameraları) kullanabilirsiniz. burada veriyi sayısal olarak taşımak önemli (hdmi, dvi). anolog olarak ise sadece component arabirimi hd kalitesine (1080 satıra) izin veriyor. yalnız yakalayıcı kartlarda yüksek çözünürlük, sayısal arabirim dediğinizde fiyatlar biraz uçuyor.

şimdilik aklıma gelenler bu kadar, sonradan birşeyler hatırladıkça bu girdiye eklemeyi düşünüyorum. bir de yukarıda üstün körü geçtiğim yerlerden açılmasını istediğiniz varsa yorum bırakırsanız gerekli ekleri yapabilirim.

[1] http://www.terracotta.org/confluence/display/wiki/Red5+and+Terracotta+POC
[2] http://osflash.org/pipermail/red5_osflash.org/2007-December/017650.html
[3] http://gregoire.org/2009/01/28/rtmpt-and-red5/
[4] http://www.xuggle.com/xuggler/