Bu konu üzerinde bir geliştirici olarak uzun zamandır çalışıyorum. Yayın yapmak, ya da video, ses gibi medya kullanımını internet servisleri üzerinden sunmak için yazılımlar geliştirmek, içerik sıkıştırma algoritmalarını ve bu tür medyalar için geliştirilmiş veri transfer protokollerini iyi bilmeyi gerektiriyor. Bu yazıda, ffmpeg kullanarak yayın yapmanın biraz teknik taraflarını ele alamayı düşünüyorum.
Öncelikle “FFMPEG nedir” sorusu ile başlayalım. Ffmpeg, içerisinde tüm medya sıkıştırma algoritmalarını ve yayın için gerekli veri transfer protokollerini barındıran, açık kaynak kodlu bir projedir. Açık kaynak kodlu olmasından mütevellit, ffmpeg projesine ait “github repository” üzerinden kaynak kodları çekip kendi projenize dahil etmek oldukça kullanışlı ve kolay bir seçenek. C bilmiyorsanız, ve programcı değilseniz de ffmpeg projesini derleyerek bir araç olarak kullanabiliyorsunuz.https://github.com/FFmpeg/FFmpeg
Medya Transfor Protokolleri
İnternet üzerinden medya yayını nasıl yapılır aşamasına geldiğimizde öncelikle, internet üzerinden yayın yaparken, medya verisi için geliştirilmiş özel veri transfer protokollerini konuşmamız gerekiyor. Bir medya yayınını, HTTP ve ya UDP-TCP gibi protokoller üzerinden gerçekleştirebiliriz. UDP-TCP üzerinden yapılan yayınlarda kullanılan video transfer protokollerinin başında RTP, RTCP, RTSP, RTMP gibi protokoller geliyor. HTTP üzerinden yayın yapmak için ise HLS, HDS, MPEG-DASH gibi video transfer protokolleri kullanılıyor. Neden bu protokollere ihtiyaç duyulmuş diye sorarsanız; bu protokoller medya yayını yaparken dikkat edilmesi gereken bazı püf noktalara göre dizayn edilmişlerdir. Çünkü medya verileri oldukça büyük ve her paketi birbiriyle çok ilişkili verilerdir. Bir canlı yayın yapmak için internet altyapınızın iyi olması gerekiyor. İnternet üzerindeki trafikten kaynaklı olarak, yayın sırasında bir çok veri kaybı ve ya paket düşmesi gibi problemler olabiliyor. Bu yüzden bu verileri taşımak için bu gibi problemler karşısında çözümler sunabilen yeni protokollere ihtiyaç duyulmuştur.
Yaptığınız yayını bir web sayfası üzerinde görüntülemek ya da dağıtmak için tabi ki HTTP tabanlı protokolleri kullanıyoruz. Örneğin oyuncalrın oldukça fazla kullandıkları “Twitch” web sayfasını duymuşsunuzdur. “Twitch” yayınları HTTP üzerinden HLS, HDS gibi protokolleri kullanıyor. Fakat sadece uygulamalar üzerinden yayının dağıtılması için UDP ve ya TCP tabanlı protokoller kullanılıyor. Örneğin Skype uygulaması yayınlarını UDP-TCP üzerinden RTP protokolünü kullanıyor.
HTTP ve ya UDP-TCP olmasının bazı avantajları ve dezavantajları var. HTTP kullanırsanız, yayınızı her türlü web sayfasında görüntüleyebilir, internetteki her türlü güvenlik duvarlarını aşabilir ve bulut sistemlere entegrasyonu daha kolay sağlayabilirsiniz. Bunun yanında, HTTP, uygulama katmanında yani en üst katmanda yer aldığından yavaş bir seçenektir. HTTP yayınındaki gecikmeler oldukça fazla olacaktır. Fakat UDP-TCP üzerinde bir protokol kullanırsanız, hız ve gecikme anlamında daha esnek çözümlere sahip olabilirsiniz. Ama bu sefer de web servislerine yayın yapmazsınız ve HTTP nin avantajlarından faydalanamıyorsunuz.
Medya Sıkıştırma Algoritmaları ve Konteynerler
Veri transfer protokolleri üzerinde konuştuktan sonra, artık medya konteyner ve sıkıştırma algoritmalarından bahsedebiliriz. Bir resim ve video verisi çok çok hatta çok büyüktür. Eğer bu veriyi sıkıştırmazsanız, bir videoyu depolamak ve bir yerden bir yere transfer etmek oldukça zordur. Bu yüzden internet üzerinden yapılan yayınların hepsinde, medya önce sıkıştırılır daha sonra transfer edilir, daha sonra hedef makinede tekrar açılarak görüntülenir.
Burada ayırt edilmesi gereken detay, konteyner ve sıkıştırma algoritmalarını birbirinden ayırmaktır. Genellikle bunlar birbirine karıştırılır. Örneğin MP4 bir sıkıştırma algoritması değil, medya konteyneridir. H264 sıkıştırma algoritması ile sıkıştırılan video ya da medya bilindik tabiri ile h264 ile kodeklenen video MP4 konteynerine konulur.
En bilindik sıkıştırma algoritmaları yani kodekler, h264, h265, VP9, AV1 dur. Buna kıyasla bu sıkıştırma algoritmalarına göre en bilindik konteynerlar ise MP4, WEBM ve IVF dir. . .
Bu şekilde açıklama yaptıktan sonra, artık FFMPEG ile basit bir uygulama yapabiliriz. ffmpeg kaynak kodlarını indirip gerekli sıkıştırma algoritmaları ile derlemek gerekiyor. Tabi biz bu proje de VP9 kodeğini kullandığımız için. Bilgisayarınıza bu kodek için gerekli libvpx kütüphanesini indirmeniz gerekiyor. Aynı zamanda bilgisayarınızda kamera sürücüsünü kontrol etmek ve kameradan frame çekmek gibi işlemler için V4L2-utils’i kurmanız gerek. Daha sonra http üzerinden bilgisayara bağlı bir yayın yapmak için şu komutu kullanabilirsiniz;
ffmpeg -f v4l2 -i /dev/video0 http://127.0.0.1:8080/feed.webm
bu komutla yerel makine IP adresimize VP9 kodeğini ve webm konteynerini kullanan bir HTTP yayını başlatmış olduk. Bu yayın http üzerinden olduğundan HLS protokolünü kullanıyor olacak. Fakat yayın sadece belirli “127.0.0.1” IP adresine yapılıyor. Oysa, yerel ağımda bulunan diğer bilgisayarların da web sayfasına girdiklerinde yaynımı görüntüleyebilmesini istiyorum. Bu yüzden ffserver’a ihtiyaç olacak. ffserver arka planda çalışarak, “127.0.0.1” ip adresine yaptığım yayını, diğer bilgisayarlardan da talep olduğu taktirde onlara da gönderecek. ffserver, ffmpeg projesinin son güncellemelerinde kaldırılmış durumda. Bu yüzden ffserver için önceki versiyonlarını indirmeniz gerekiyor. Örneğin ben 3.14 versiyonunu kullanıyorum. Ffserver’ı şu komutla çalıştırabiliriz;
ffserver -f /etc/ffserver.conf
Tabi bunun için ffserver config dosyasına ihtiyacınız olacak. Bu dosya ise şu şekilde olmalı;
HTTPPort 8080 # Port to bind the server to HTTPBindAddress 0.0.0.0 MaxHTTPConnections 2000 MaxClients 1000 MaxBandwidth 10000 # Maximum bandwidth per client # set this high enough to exceed stream bitrate CustomLog - <Feed feed.ffm> File ./feed.ffm FileMaxSize 1g ACL allow 127.0.0.1 </Feed> <Stream feed.webm> Format webm Feed feed.ffm VideoCodec libvpx VideoSize 320x240 VideoFrameRate 15 VideoBitRate 512 VideoBufferSize 512 NoAudio AVOptionVideo flags +global_header StartSendOnKey </Stream> <Stream status.html> # Server status URL Format status # Only allow local people to get the status ACL allow 192.168.1.0 192.168.1.255 </Stream> #<Redirect index.html> # Just an URL redirect for index # # Redirect index.html to the appropriate site # URL / #</Redirect>
Artık yapılan yayını bir basit HTTP sayfası yaparak yayınlayabiliriz. O basit HTTP sayfası ise şu şekilde olabilir;
<!doctype html> <html> <head> <meta charset="UTF-8"> <link rel="shortcut icon" href="./.favicon.ico"> <title>Example</title> <link rel="stylesheet" href="./.style.css"> <script src="./.sorttable.js"></script> </head> <style> video { width: 640px; height: 360px; } </style> <script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script> <body onload="setupVideo()"> <p><h1>Live Video Streaming over http</h1></p> <video width="320" height="240" controls> <source src="https://127.0.0.1:8080/feed.webm" type="video/webm"> Your browser does not support the video tag. </video> </body> </html> </body> </html>
Merhaba hocam. Bir sitem var ve kiralık sunucu üzerinden yayın yapıyorum. Görüntü hoşuma gitmiyor. Bunu direk kendi sitem üzerinden yapabilir miyim? tugaykuzu.com bakabilirsiniz…
Merhaba, eğer hostinginizi kiraladığınız sunucuya taşırsanız daha kaliteli yayın yapma şansınız olabilir.
Hocam server bağlantısında sorun olduğu anda client da duruyor. Bunun bir çözümü var mı?
Config dosyasındaki VideoBufferSize değişkenini arttırıp deneyebilirsiniz.
Hocam merhabalar windows server üzerinde kurulu web sitemizde bu yayını yayınlayabilir miyiz? 40 tane kamera var standart bir vds’de çalışır mı?
Merhaba, Windows’da hiç denemedim. Fakat çalışmaması için hiç bir neden yok. FFMPEG Server kurduktan sonra çalışması lazım diye düşünüyorum.