Python İle RTSP Akışını Kaydetme ve İzleme | Detaylı RTSP Yapısı

Python ile IP kameranızın verdiği RTSP yayınını hazır kütüphaneler kullanmak yerine gelen akışı analiz ederek kaydedebiliriz. Bu dersimizde RTSP yayınımızdan gelen paketleri yakalayacağız ve içindeki video verisini toplayarak kaydedeceğiz. Öncesinde RTSP protokolü nedir detaylıca inceleyelim.

RTSP (The Real Time Streaming Protocol), eğlence ve iletişim sistemlerinde medya serverlarında ki verilerin akışını kontrol etmek için tasarlanan bir ağ denetim protokolüdür. Bu protokol bitiş noktaları arasındaki medya bağlantılarının kurulması ve kontrol edilmesinde kullanılır.

Veri akışının iletimi RTSP protokolünün görevi değildir. Çoğu RTSP sunucusu medya akışının dağıtımı için RTP (Gerçek Zamanlı Aktarım Protokolü) kullanır. Ancak bazı sunucular özel taşıma protokolü de uygulamaktadır. (Realnetworks’daki RTSP sunucusu RDT kullanmaktadır.)

Özetle bir kameradan akış alabilmek için cihaza RTSP protokolüyle RTSP istek mesajları göndeririz. Fakat video verileri RTP protokolü ile encode edilerek bize iletilir. RTSP protokolü sadece mesajlar aracılığı ile akış üstünde SETUP,PLAY,RECORD gibi işlemler yapabilmemizi mümkün kılar. Bu mesajlar tıpkı HTTP GET,POST,PUT istekleri gibi mesaj başlığında bulunur.

1. RTSP Mesajlaşmaları İle Akışı Başlatmak

Yukarıda özette dediğimiz gibi RTSP protokolü medya akışını iletmek için değil kontrol etmek için kullanılır. Örneğin bağlantıyı kurma, akışı başlatma, durdurma, sonlandırma gibi işlemler RTSP protokolü sayesinde yapılır. Peki nedir bu işlemler hemen bakalım:

  • OPTIONS : OPTIONS isteği sunucunun kabul ettiği istek tiplerini döndürür.
  • DESCRIBE : DESCRIBE isteği RTSP URL (rtsp://…) isteklerini ve yönetilebilir cevap veri türlerini içerir. UDP ve TCP için taşımaları için RTSP protokolü için varsayılan port 554’dür. Bu cevap genellikle Session Description Protocol (SDP) formatında olup sunum açıklamaları içerir. Diğer şeylerin yanı sıra sunum açıklaması toplam URL leleri ile kontrollü medya akışlarını listeler. Tipik bir durum da, her bir ses ve video için bir stream akışı bulunmaktadır.
  • SETUP : SETUP isteği tek bir medya akışının nasıl taşınacağını belirtmektedir. Bu istek PLAY isteği gönderilmeden önce yapılmalıdır. İstek medya akış URL’sini ve taşıma belirteci içerir. Bu belirtec genellikle RTCP verilerisini(ses veya video) almak için yerel bir port içerir. Sunucu cevaplarımız genellikle seçilen parametrelerin onaylanması ve yanlış kısımların duzeltilmesidir. Toplu PLAY isteği gönderilmeden önce her medya akışı SETUP kullanılarak yapılandırılmış olması gerekir.
  • PLAY : PLAY bir veya tüm medya akışlarının çalınması isteğidir. Birçok çalma isteği gönderilerek PLAY isteği yığın haline getirilebilir. URL toplam bütün URL de olabilir(tüm medya akışlarını oynatmak için) veya tek bir medya akışı için gerekli URL de(sadece tek bir akışı oynatmak için) olabilir. Bunla ilgili bir aralıkta belirtilebilir. Hiç aralık belirtilmezse PLAY akışı baştan sona kadar oynatılır veya akış durdurulursa sonra durdurulduğu bu noktan aynen devam eder.
  • PAUSE : PAUSE isteği akışı geçici olarak durdurur veya tüm akış isteğini bir PLAY isteği gelince devam edicek şekilde erteler. İstek toplu veya medya akış URL si içerir. PAUSE zamanı bir dizi parametresi ile belirlenebilir. Dizi parametresi PAUSE yi hızlı bir şekilde değiştirebilir yani PAUSE yi kaldırabilir.
  • RECORD : RECORD isteği depolama yapmak için sunucuya akış isteği göndermede kullanılır.
  • TEARDOWN : TEARDOWN isteği oturumu sonlandırmak için kullanılır. Bütün medya akışlarını durdurur ve sunucudaki bütün oturumla ilgili verileri kurtarır.

Bu komutlar TCP ile mesaj gövdesinde iletilir ve alınır. Wireshark ile örnek bir RTSP haberleşmesini analiz ettiğimizde kamera ve bilgisayar arasındaki mesajlaşmanın resimdeki gibi olduğunu görebilirsiniz.

Bu mesajları Wireshark programında Follow -> TCP menüsü ile tek pencerede görmek istersek aşağıdaki gibi bir çıktı alırız.

Video verisinin akışı yalnızca başarılı bir RTSP mesajlaşmasının ardından PLAY komutu ile mümkün olur. Bizde bu bölümde video akışını başlatabilmek için ilk olarak bu el sıkışmalarını gerçekleştireceğiz. Yapacağımız haberleşmenin özeti aşağıdaki resimde olduğu gibi olacak.

1.1 Socket Oluşturma

İlk olarak komutlarımızı gönderip alacağımız socketi başlatalım. Bu bölüme geçmeden önce Python socket programlama dersimize göz gezdirebilirsiniz.

Haberleşme TCP üzerinden olacağı için SOCK_STREAM kullanacağız. Test kamerası olarakta 203.67.18.25 ip adresli kamerayı kendi örneklerinizde de kullanabilirsiniz. Son olarak RTSP sunucusunun default portu 554 dür.

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.settimeout(5)
s.connect(('203.67.18.25',554))

1.2 OPTIONS Komutu

Yukarıda verdiğim şemada OPTIONS komutunun olmadığını biliyorum. Bunun sebebi OPTIONS komutuyla medya sunucusunun sadece hangi komutları kullanmamıza izin verdiğini göstermesidir. Yani bu işleyişte OPTIONS komutu göndererek ön bilgi alabiliriz ama üstünde herhangi bir işlem yapmayacağız.

mesaj = 'OPTIONS rtsp://203.67.18.25/0 RTSP/1.0\r\n\r\n'

gonder = s.send(mesaj.encode('utf-8'))
cevap = s.recv(bufLen).decode('utf-8')

Socket üzerinden yolladığımız OPTIONS komutuna aldığımız cevap şu şekilde olacaktır.

Bu cevaptan da anlayacağımız üzere RTSP protokolü ile OPTIONSDESCRIBESETUPPLAYTEARDOWN ve SET_PARAMETER komutlarını kullanabiliyormuşuz. Bizde DESCRIBE komutuyla başlayalım.

1.3 DESCRIBE Komutu

Artık akışımızın özelliklerini öğrenmeye geldi. Yayını hangi kanaldan çekeceğimiz, codec ve çözünürlük bilgileri, frekans bilgisi gibi daha birçok meta bilgisini bu komutla öğreniyoruz. Öyleyse hadi hemen komutumuzu gönderelim.

mesaj = 'DESCRIBE rtsp://203.67.18.25/0 RTSP/1.0\r\n\r\n'

gonder = s.send(mesaj.encode('utf-8'))
cevap = s.recv(bufLen).decode('utf-8')

Şimdi gelen mesaja bakalım:

Bu da ne? 401 koduyla işlemi gerçekleştirmek için gerekli olan izinlere sahip olmadığımızı söyledi sunucu. O zaman sunucunun WWW-Authenticate: başlığı altında söylediği Digest doğrulama yöntemini kullanarak gerekli izinleri alalım.

HTTP Authentication Yöntemleri başlıklı derste anlattığım gibi gerekli izin anahtarını oluşturuyoruz. Bu oluşturma detaylarını tekrar burada anlatmayacağım. Bunun yerine yazı sonunda verdiğim kaynak kodu inceleyebilirsiniz.

NOT: Sunucu farklı bir Authentication yöntemi de kullanıyor olabilir. Hatta hiç kullanmıyor da olabilir. Kaynak kodda bu doğrulamayı yaparak gerekli Authorization başlığını oluşturuyoruz.

Şimdi gerekli Authorization başlığı ile tekrar gönderelim mesajı.

mesaj = """
DESCRIBE rtsp://203.67.18.25/0 RTSP/1.0\r\n
CSeq: 1\r\n
Authorization: Digest username="admin", realm="Surveillance Server", algorithm="MD5", nonce="06396879", uri="/0", response="c97c02f235d77c1df9f3789e2f12019c"\r\n
User-Agent: Kerteriz RTSP\r\n
Accept: application/sdp\r\n\r\n
"""

gonder = s.send(mesaj.encode('utf-8'))
cevap = s.recv(bufLen).decode('utf-8')

Buradaki CSeq paket numarasıdır. Her gönderdiğimiz pakette bir artıracağız. User-Agent rastgele bir ziyaretçi ismi, Accept mesaj formatıdır. Şimdi dönen cevaba bakalım.

Dönen mesajdan akışta video ve ses olmak üzere iki kanal olduğu, RTP/AVP profilindeki medyanın 1920x1080 çözünürlüğünde, 10 fps ve 4096 bitrate olduğu, video kanalının trackID=0, ses kanalının trackID=1, payload tipinin yani codecin H264 ve 90000Hz olduğu gibi birçok bilgiyi görebiliyoruz. Tabi en önemlisi ise sprop-parameter-sets ile base64 formatında gelen SPS ve PPS bilgileridir.

NOT: Her H264 streami akış bilgilerini içeren SPS ve PPS verileriyle başlamalıdır. Yani bir akışın bütünü şu şekilde bir formata sahiptir. Ayrıca H264 akışta her frame 0x000001 verisiyle başlamalıdır.

H264: 0x000001[SPS], 0x000001[PPS], 0x000001[VIDEO FRAME], 0x000001[VIDEO FRAME], 0x000001…
MPEG4: 0x000001[Visual Object Sequence Start], 0x000001[VIDEO FRAME]

Bu nedenle bu aşamada SPS ve PPS verilerini base64 ten bytes array formatına çevirerek dosyamızın en başına koyuyoruz. Akış devam ederken de yine aralarda gelen SPS ve PPS paketlerini ileride paketin devamına ekleyeceğiz.

f = open('stream.h264','wb')

startbytes = b"\x00\x00\x00\x01"
sprop = "p2oHgCJ+WbgICAgQA==,aO48gA==" # bu bölümü kaynak kodda nasıl çektiğimizi görebilirsiniz
sprop = sprop.split(',')
sps = base64.decodebytes(sprop[0].encode())
pps = base64.decodebytes(sprop[1].encode())

f.write(startbytes+sps)
f.write(startbytes+pps)

Böylece videomuzun başlangıç bilgileri hazır. Bundan sonra işlemlere gönül rahatlığıyla devam edebiliriz.

1.4 SETUP Komutu

Medya ve akış hakkında bilgileri topladıktan sonra bu akış ile aramızdaki bağlantıyı kurabiliriz. Bunun için aşağıdaki SETUP komutunu gönderiyoruz. Bu komutta bağlantıyı kuracağımız RTSP adresi (rtsp://203.67.18.25/0/trackID=0), DESCRIBE komutu ile elde ettiğimiz video kanalının adresidir.

mesaj = """
SETUP rtsp://203.67.18.25/0/trackID=0 RTSP/1.0\r\n
CSeq: 2\r\n
Authorization: Digest username="admin", realm="Surveillance Server", algorithm="MD5", nonce="85490023", uri="/0", response="960f1e24ab5423d0c0d5e8e856d4a167"\r\n
User-Agent: Kerteriz RTSP\r\n
Blocksize: 65535\r\n
Transport: RTP/AVP;unicast;client_port=60784-60785\r\n\r\n
"""

gonder = s.send(mesaj.encode('utf-8'))
cevap = s.recv(bufLen).decode('utf-8')

Bu komutta en önemli kısım client_port değişkenidir. Bağlantı kurulup akışı başlattığımızda bu port üzerinden akışımızı dinleyeceğiz. Sizde rastgele bir boş port seçebilirsiniz. Şimdi aldığımız cevaba bakalım.

Dönen başarılı cevapta oturumumuzun 68042081 id li Session üzerinden yürütüleceği belirtiliyor. Bizde bu session id yi dinleyeceğiz.

1.5 PLAY Komutu

Oturumu kurup session id yi aldıktan sonra belirttiğimiz portlar üzerinden medya oynatımını başlatabiliriz. Öyleyse hemen PLAY komutunu gönderelim.

mesaj = """
PLAY rtsp://203.67.18.25/0 RTSP/1.0\r\n
CSeq: 4\r\n
Authorization: Digest username="admin", realm="Surveillance Server", algorithm="MD5", nonce="98390526", uri="/0", response="1191a66ef1ef96b28f0a1c25c4c0442b"\r\n
User-Agent: Kerteriz RTSP\r\n
Session: 61503321\r\n
Range: npt=0.000-\r\n
"""

gonder = s.send(mesaj.encode('utf-8'))
cevap = s.recv(bufLen).decode('utf-8')

Cevabımıza bakalım:

Tebrikler! Artık akış başladı. Öyleyse RTSP protokolü kısmını geçelim ve gelen UDP paketlerini dinlemeye başlayalım.

2. Akıştan Gelen UDP Paketlerini Toplamak ve Analiz Etmek

Şu anda medya sunucusu bize UDP paketlerini göndermeye devam ediyor. Öyleyse belirttiğimiz client port üzerinden hemen bu paketleri dinleyelim. Tabi öncesinde yeni bir socket oluşturarak başlayalım.

2.1 Socket Oluşturma

Paketlerimiz UDP üzerinden geleceği için bu sefer SOCK_DGRAM kullanacağız. Medya sunucusu belirtmiş olduğumuz 60784 portu üzerinden bize paketleri gönderecek. Öyleyse bu portu dinleyelim.

s1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s1.settimeout(5)
s1.bind(('203.67.18.25',60784))

Gelen paketlere hızlıca bir göz gezdirelim.

Çok güzel! UDP paketleri portumuz üzerinden geliyor. Artık bu paketleri toplayıp kaydetmeye geldi. Ama önce UDP paket içeriğini görelim.

2.2 UDP Paket Analizi

Ağ üzerindeki veriler bulunduğu ve kullandığı protokole uygun olarak kapsülle işlemine tabi tutulur. Böylece her katman kendi paketini kolayca alır ve okur.

Bu doğrultuda bize gelen bir UDP paketi iki bölümden oluşur. Yani UDP kapsülü iki parçadan oluşur. Bunlar;

UDP Packet = | UDP Header | + | UDP Payload |

UDP Header kısmı uygulama katmanına taşınmaz. Şanslıyız ki biz bu sebeple sadece UDP Payload kısmı yani asıl verimizle ilgileneceğiz. Peki bu verinin içeriği nedir? Hemen bakalım;

UDP Payload = | RTP Header | + | RTP Payload |

RTP Header ve RTP Payload kısımları bizim medyamızın bulunduğu asıl kısımdır. RTP Header kısmında ilk 12 byte uzunluğu sabittir. Bu 12 byte içerisinde ki bazı parametrelere göre header uzunluğu uzayabilir. Tüm UDP Payload bölümünden RTP Header i çıkardığımızda ise geriye RTP Payload bölümü kalır.

Tüm parametrelerin ne olduğuna hızlıca bakalım:

  • version (V): 2 bits => RTP versiyonunu tanımlar. Güncel versiyon (2) dir.
  • padding (P): 1 bit => Eğer (1) ayarlanmışsa payload verisi bittikten sonra ekstra bir veya birden fazla octet var demektir.
  • extension (X): 1 bit => Eğer (1) ayarlanmışsa sabit header ile payload arasında eksta bir header verisi daha var demektir.
  • CSRC count (CC): 4 bits => CSRC sayımı, sabit başlığı takip eden CSRC identifiers sayısını içerir.
  • marker (M): 1 bit => Bir profil tarafından tanımlanır ve uygulama seviyesinde kullanılır. Eğer ayarlanırsa uygulama için o andaki verinin uygulamayla ilgili bazı özel durumlara sahip olduğunu belirtir. Örneğin 1 ayarlıysa video frameninin sonunun geldiğini gösterir.
  • payload type (PT): 7 bits => Payload formatını gösterir. Ve uygulama tarafından onun yorumlanmasına karar verilir. Bir RTP profili tarafından belirtilir. Örneğin minimal kontrol ile ses ve video konferansları.
  • sequence number: 16 bits => Sıra numarası RTP başlığında paket kaybını belirlemeye yarayan ve aynı tarih bilgisi değerine sahip paketlerin sıralanmasını sağlar. Ve başlangıç değeri rastgele olarak belirlenir.
  • timestamp: 32 bits => Başlangıcı rastgele olan ve gecikme ile jitter i hesaplamada kullanılan zaman bilgisi verisi.
  • SSRC: 32 bits => Senkronizasyon kaynak tanımlayıcıları, tek bir şekilde bir streamin kaynağını tanımlar. aynı RTP oturumu içindeki senkronizasyon kaynağı tek ve eşsiz olmalıdır. Bu tanımlayıcı rastgele seçilir.
  • CSRC list: 32 bits => Yardımcı kaynak idleri birçok kaynaktan oluşturulan bir stream için yardımcı kaynakları numaralandırır.

RTP Payload kısmına geldiğimizde ise ilk 1 byte yani 8 bit sabittir. Bu alanda yer alan parametreler ise şu şekildedir;

  • F: 1 bit => forbidden_zero_bit. Aktarım esnasında bir hata olup olmadığını gösterir. (0) değeri normal, (1) değeri syntax ihlali olduğunu gösterir. Yani 0 olmalıdır.
  • NRI: 2 bits => nal_ref_idc. Sonraki 2 bit, bu NAL biriminin bir reference field/frame/picture olup olmadığını gösterir. Yani (0) tahmin paketidir, videoda kullanılmaz. (0) dan büyük bir değerse bu NAL paketi reference field/frame/picture den biridir.
  • Type: 5 bits => nal_unit_type. NAL unitin tipini belli eder. Tablodan bakabilirsiniz.
                Payload Packet    Single NAL    Non-Interleaved    Interleaved
        Type    Type      Unit Mode           Mode             Mode
        -------------------------------------------------------------
        0      reserved      ig               ig               ig
        1-23   NAL unit     yes              yes               no
        24     STAP-A        no              yes               no
        25     STAP-B        no               no              yes
        26     MTAP16        no               no              yes
        27     MTAP24        no               no              yes
        28     FU-A          no              yes              yes
        29     FU-B          no               no              yes
        30-31  reserved      ig               ig               ig

Bu tabloda 0 kullanılamaz ve 30-31 daha sonraki teknolojiler için rezerve edilmiştir. 1-23 ise NAL meta bilgilerini tutar. Örneğin 7 SPS8 PPS paketidir. Özetle Nal unit type değerini 1-23 arasında gördüğünüz paketleri direkt olarak depolayabilirsiniz. Çünkü bu paketler resolution, vb. meta bilgileri sunan NAL unit lerdir.

H264 ve MPEG4 verileri genellikle paketlenir (fragmanted unit – FU – 28 ve 29), çünkü bir uç noktanın MTU adı verilen TCP veya UDP aracılığıyla gönderebileceği belirli bir ağ sınırı vardır. Genellikle 1500 bayt veya daha azdır. Dolayısıyla, video karesi bundan daha büyükse, MTU boyutlu parçalara bölünmesi (paketlenmesi) gerekir. Bu, TCP ve UDP aktarımındaki encoder/streamer ile yapılabilir. Bu sebeple type değeri 28 veya 29 gelen paketler H264 e aittir yani fragmented veridir. Bizde type ı 28 olan paketler üstünde son bir işlem yapıp dosyaya yazacağız. (type 29 için ileride kaynak kodu güncelleyeceğim.)

Öyleyse programımızda type değeri 28 olarak gelen paketlerin bir H264 fragmentinin hangi parçası olduğunu bilmemiz gerekir. Buna göre her fragmenti doğru yerden birleştirmeliyiz. Bunun için bir H264 fragmenti nasıl görünür hemen bakalım.

H264 FRAGMENT
İlk byte: [ 3 NAL UNIT BITS | 5 FRAGMENT TYPE BITS]
İkinci byte: [ START BIT | END BIT | RESERVED BIT | 5 NAL UNIT BITS]
Diğer bytes: [… VIDEO FRAGMENT DATA…]

İlk byte kontrolünü yukarıda yapmıştık (Type 1-28 arası ise geri kalan tüm veriyi aldık). Şimdi Type değeri 27-28 olanların hangi parça olduğunun kontrolünü yapacağız. Bu nedenle ikinci byte değerlerine bakalım. Burada yer alan parametreler ise şu şekildedir;

  • Start Bit: 1 bit => 1 ayarlanmışsa NAL verisinin başlangıcıdır. Startbytes + Nal unit bits + Video Fragment Data depolanır.
  • End Bit: 1 bit => 1 ayarlanmışsa NAL unit verisinin son bölümüdür. Sadece Video Fragment Data depolanır.

Bu şekilde tüm paketler tek tek analiz edilir ve fragmentler birleştirilerek frameler elde edilir, ardından bir dosyada depolanır. Bu kısım biraz karışık gelmiş olabilir ama aslında mantığı gayet basit. Kaynak kodları incelerken daha iyi anlayacaksınızdır.

Not: Üst taraflarda yazmıştım ama tekrar hatırlatayım. Fragmentleri birleştirerek frameleri elde ettikten sonra dosyaya yazarken her video frame verisinin başına 3 byte uzunluğundaki 0x000001 değerini eklemeyi unutmayın. Tabi en başta SPS ve PPS bilgilerinin olacağını da unutmuyoruz. Özetle bir video şu şekilde oluşturulur;

H264: 0x000001[SPS], 0x000001[PPS], 0x000001[VIDEO FRAME], 0x000001…
MPEG4: 0x000001[Visual Object Sequence Start], 0x000001[VIDEO FRAME]

2.2 Kaydedilen H264 Paketinin Oynatılması

Bu kısma başlarken küçük bir özet geçelim;

  1. RTSP protokolü sayesinde medya sunucusu ile gerekli konuşmaları yaptık ve akışı başlattık.
  2. Bu haberleşmeden SPS ve PPS paketlerini alıp dosyanın başına koyduk
  3. Açtığımız port üstünden gelen UDP paketlerini dinledik.
  4. UDP paketlerini analiz ettik ve içindeki video fragment verilerini bir dosyada topladık.

Şimdi ise yapacağımız şey çok çok basit. Tek gereken bir H264 codec destekli video player ile bu dosyamızı açmak. VLC player işimizi profesyonellikle görecektir. Hemen heyecanla dosyamızı VLC playere sürekleyip atalım.

Süper! topladığımız akışı izleyebiliyoruz. Demek ki başarılı bir şekilde depoladık.

3. Son Sözler ve Tavsiyeler

1 haftalık araştırmam ve okuduğum standart dökümanlar (RFC) ile H264 codec ile encode edilmiş bir RTSP yayınını başarıyla kaydedip izleyebildim. Eksikleri var mı derseniz elbette çok var. İyileştirmeleri zamanla yapıp kaynak kodunu güncelleyeceğim ama sizde bu arada RTP Payload Format for H.264 Video
(RFC3984)
 dökümanını okuyarak geliştirme yapabilirsiniz. Hatta farklı codecler bile ekleyebilirsiniz.

Kardeşim bu kadar eziyete ne gerek var, ffmpeg kullansaydın diyenler olabilir. Sonuna kadar da haklılar çünkü FFMpeg, OpenRTSP, VLC gibi projeler zaten çok iyi seviyede çalışıyorlar. Üstelik bizim burada yaptığımız gibi tek bir codeci değil, neredeyse tamamını destekliyorlar. Hata kontrolleri, iyileştirmeler vs. de cabası. Ama bu araştırmayı yapmamda ki amaçta zaten tam olarak buydu. Bu kütüphanelerin nasıl çalıştığı, paketlerin nasıl kapsüllendiği, RTP payload içinde neler olduğu gibi birçok konuyu merak ediyordum ki bu 1 hafta içerisinde aydınlandım diyebilirim. Çok küçük bir parçasından başlamış olsamda en azından artık yolu biliyorum. Gün geçtikçe kodumu iyileştirerek diğer codecleri de yavaş yavaş ekleyebilecek bilgiyle başlamam beni mutlu ediyor. Umarım sizin içinde faydalı olur. Halen ben bununla uğraşamam, FFMpeg yeterli diyenler içinde şu iki komutu vereyim. Bende en azından buraya bu komutları not etmiş olurum 🙂

FFMpeg ile yukarıdaki kodların aynısını yapan komut (RTSP akışını kayıt eden):

ffmpeg -i rtsp://admin:admin@203.67.18.25/0 -an -vcodec copy stream.h264

Burada -an ses kanalını almak istemediğimizi (sessiz olsun video), -vcodec copy orjinal codeci birebir istediğimizi, stream.h264 de dosya adımızı gösteriyor. Siz dosya adını xxx.mp4 yaparsanız direkt oynatabilirsiniz. Aksi halde stream.h264 dosyasını sürükleyip bırakmalısınız.

FFMpeg ile RTSP yayını her x sürede bir yeni dosyada depolayan komut:

ffmpeg -i rtsp://admin:admin@203.67.18.25/0 -an -vcodec copy -f segment -segment_time 30 -segment_atclocktime 1 -reset_timestamps 1 -strftime 1 %H-%M-%S.mp4

Burada ise -segment_time 30 ile her 30 sn de bir yeni dosya olarak kayıt ediyoruz.

4. Kaynak Kodlar

Bu kadar yazıdan sonra artık kaynak kodları sizlerle paylaşabilirim. Sizde hem yukarıda ki örnek kamerada hemde kendi kameranızda (H264 olması şartıyla) test edebilir ve özgürce geliştirebilirsiniz. Önerileriniz ve sorularınız için ise aşağıdaki yorum alanını kullanabilirsiniz.

=> Proje Adı: Python RTSP Recoder
=> Kaynak kodlara erişmek için Tıklayınız.