Python İle Ekran Kaydedici Yapımı



Şu an için Türkçe kaynak bulamayacağınız bir konu hakkında yazı yazıyorum. Umarım faydalı olur. Programın mantığı basit. Biraz python bilgisi ile geliştirilebilir(ki kendim geliştiriyorum.).

Her zaman ki gibi tüm kodları veriyorum:



import numpy as np
import cv2
#import pyscreenshot as ImageGrab
from PIL import ImageGrab

fourcc = cv2.VideoWriter_fourcc(*"mjpg")
vid = cv2.VideoWriter("kayit.avi", fourcc, 8, (1440, 900), True)
while True:
    img = ImageGrab.grab()
    img_np = np.array(img)
    RGB_img = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)

    vid.write(RGB_img)
    cv2.imshow("Sahne", RGB_img)
    key = cv2.waitKey(1)
    if key == 27:
        break

vid.release()
cv2.destroyAllWindows()

Kullandığımız birkaç modül var ilk önce bunları kurmanız daha iyi olacaktır. Modül kurulumlarından bahsetmeyeceğim zaten hepsini pip ile kolayca kurabilirsiniz.

Eğer PIL modülü linux işletim sistemlerinde çalışmazsa 3. satırda ki gibi pyscreenshot modülünü ImageGrab olarak içeri aktarabilirsiniz.

kodları açıklamaya gelebiliriz nihayetinde.



fourcc = cv2.VideoWriter_fourcc(*"mjpg")
bu satırda videoyu yazdıracağımız codec türünü seçiyoruz. Benim gördüğüm en kaliteli yazma biçimi MJPG. Fakat ihtiyacınıza göre farklı codec türleri seçebilirsiniz. Seçtiğiniz codec'e göre video boyutu küçülür veya büyür. Codec türlerine buradan ulaşabilirsiniz. Fakat ortalama bir video için XVID en uygunu olabilir.
vid = cv2.VideoWriter("kayit.avi", fourcc, 5, (1440, 900), True)
Bu satırda videoyu yazdırmak ile ilgili birkaç ayar veriyoruz.
- "kayit.avi" 
- fourcc 
- 5 
- (1440, 900)
verdiğimiz değerler sırasıyla bunlar.
İlk değerimiz videoyu kaydedeceğimiz ismi belirtir. Yani video çıktısının ismi kayit.avi olacak. İkinci değerimiz biraz önce anlattığım codec türü. Biz bu kodda MJPG kullandık(fakat yinede XVID kullanmanızı öneririm).
Üçüncü değerimiz fps değeri. Burada videoyu 5 fps olarak yazmasını söyledim. Normale göre çok az bir sayı. Fakat Python'un yavaşlığından mı yoksa bilgisayarın yavaşlığından mı anlamadım. Kodun aşağısında ki while döngüsünde saniyede alabildiğim kare sayısı en fazla 7-8. Şu an elimde ki bilgisayar eski olduğu için bilgisayardan da şüpheleniyorum. Düzgün bir bilgisayarda denediğimde hala aynıysa, C veya C++'da bu işlem için bir modül yazıp python'da kullanmam gerekebilir. Bu arada bu değer while döngüsünde alınan saniye başına kare ile aynı sayıda olmazsa videonun hızı değişir. Fazla olursa video hızlı, az olursa video yavaşlar.
Son değerimiz ise çözünürlük. Videoyu hangi çözünürlükte kaydedeceğimizi belirtiyoruz. Ben bende ki monitörün çözünürlüğünü girdim. Fakat her monitöre uygun olması açısından monitör çözünürlüğü otomatik olarak alınıp buraya yerleştirilebilir.
while True:
    img = ImageGrab.grab()
    img_np = np.array(img)
    RGB_img = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)

    vid.write(RGB_img)
    cv2.imshow("Sahne", RGB_img)
    key = cv2.waitKey(1)
    if key == 27:
        break


En önemli kısım burası. Sürekli çalışacak bir döngü oluşturuyoruz. Döngünün içindeki ilk satırda döngü çalıştığı sürece ekran alıntısı alıyoruz. Yukarıda bahsettiğim sorunda burada çıkıyor. Döngü sürekli çalışıyor fakat bilgisayar veya python bu satırı yavaş çalıştırdığı için saniyede alınan kare sayısı düşük oluyor.grab() parantezinin içine bbox(x eksenindeki konum, y eksenindeki konum, genişlik, yükeklik) şeklinde değer vererecek kaydedilecek yerin konumunu ve boyutunu ayarlayabilirsiniz. Değer vermezseniz tam ekran kayıt olur. Fakat burada ekran boyutunu ayarlarsanız vid değişkeninin içindeki çözünürlük kısmınada aynı çözünürlük değerini vermeyi unutmayın.

İkinci satırda alınan ekran alıntıları kuyruğa ekliyoruz.
Daha sonra RGB_img değişkeni içinde kuyruğa aldığımız resimleri RGB renk modeli ile renklendiriyoruz(ki doğru renkleri göstersin).

Daha sonra vid.write() satırı ile renklendirilmiş kareleri tek tek belirlediğimiz ayarlara göre çıktıya yazdırıyoruz. Daha sonra cv2.imshow() komutu ile alınan ekran alıntılarını yeni bir pencerede gösteriyoruz(bu pencere bana OBS Studioyu hatırlatıyor).

Son olarak kullanıcının Escape tuşuna basıp basmadığını kontrol ediyoruz. Basarsa döngü duracak ve video kaydedilecek. Burada önemli bir şey var Escape tuşuna basmadan programı zorla kapatırsanız video hatalı olup açılmayacaktır.

vid.release()
cv2.destroyAllWindows()

son olarak Escape tuşuna basıldığı takdirde videoyu yazma işlemini bitirip imshow pencerelerini kapatıyoruz.


Bu program ile çektiğim bir video:

Yorumlar

Bu blogdaki popüler yayınlar