Python make screen recoder with audio
from PyQt5 import QtCore, QtGui, QtWidgets # pip install pyqt5
from PyQt5.QtWidgets import QFileDialog
import os
import pyautogui # pip install pyautogui
import cv2
import numpy as np
import pygetwindow as gw
import _thread
import imutils
import time
import signal
from threading import Thread
import shlex
import psutil
import subprocess
from subprocess import Popen
from dateutil.relativedelta import relativedelta # Install it via: pip install python-dateutil
try:
os.remove("output_video.mp4")
except:
pass
drawing = False
global x1, y1, x2,y2,num,h,w,windowRegion
x1,y1,x2,y2,h,w = 0,0,0,0,0,0
windowRegion=0
num = 0
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
self.threadpool = QtCore.QThreadPool()
MainWindow.setObjectName("MainWindow")
sizeObject = QtWidgets.QDesktopWidget().screenGeometry(-1)
H = (sizeObject.height())
W = (sizeObject.width())
self.W = W
self.H = H
MainWindow.resize(W//8, H//10)
MainWindow.setMinimumSize(QtCore.QSize(W//5, H//7))
MainWindow.setAcceptDrops(True)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem('')
self.cmd = ""
""" AUDIO and VIDIO DEVICES """
from PyQt5.QtMultimedia import QAudioDeviceInfo,QAudio,QCameraInfo
# List of Audio Input Devices
input_audio_deviceInfos = QAudioDeviceInfo.availableDevices(QAudio.AudioInput)
for device in input_audio_deviceInfos:
self.comboBox.addItem(device.deviceName())
""" ---------------------- """
self.comboBox.setCurrentIndex(1)
self.Mic = input_audio_deviceInfos[0].deviceName()
self.gridLayout.addWidget(self.comboBox, 1, 0, 1, 1)
self.radioButton = QtWidgets.QRadioButton(self.centralwidget)
self.radioButton.setObjectName("radioButton")
self.gridLayout.addWidget(self.radioButton, 2, 0, 1, 1)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setMinimumSize(QtCore.QSize(0, 23))
self.pushButton.setIconSize(QtCore.QSize(16, 25))
self.pushButton.setObjectName("pushButton")
self.gridLayout.addWidget(self.pushButton, 3, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionNew = QtWidgets.QAction(MainWindow)
self.actionNew.setObjectName("actionNew")
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.clicked = False
self.pushButton.clicked.connect(self.takeSnapNow)
self.radioButton.toggled.connect(self.setStatus)
self.comboBox.currentIndexChanged[str].connect(self.setAudioDevice)
self.th={}
self.cap = ""
self.useCam = False
self.st = 0
self.arguments = ''
self.process = None
def setAudioDevice(self,audioD):
self.Mic = audioD
def setStatus(self):
if self.useCam ==False:
self.useCam = True
else:
self.useCam = False
def draw_rect(self,event, x, y, flags, param):
global x1, y1, drawing, num, img, img2,x2,y2
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
x1, y1 = x, y
elif event == cv2.EVENT_MOUSEMOVE:
if drawing == True:
a, b = x, y
if a != x & b != y:
img = img2.copy()
cv2.rectangle(img, (x1,y1),(x,y), (0, 255, 0), 2)
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
num += 1
font = cv2.FONT_HERSHEY_SIMPLEX
x2 = x
y2= y
def takeSnap(self):
global x1, y1, drawing, num, img, img2,x2,y2,h,w
global windowRegion
if self.useCam==False:
key=ord('a')
im1 = pyautogui.screenshot()
im1.save(r"monitor-1.png")
img= cv2.imread('monitor-1.png') # reading image
try:
os.remove('monitor-1.png')
except:
pass
cv2.putText(img,"Click and select the Region, Press w to confirm selection ",(self.W//8,self.H//2),cv2.FONT_HERSHEY_TRIPLEX, 1.3, (20,255,0), 2, cv2.LINE_AA)
img2=img.copy()
cv2.namedWindow("main", cv2.WINDOW_NORMAL)
cv2.setMouseCallback("main", self.draw_rect)
cv2.setWindowProperty("main", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN);
while key!=ord('w'):
cv2.imshow("main",img)
key = cv2.waitKey(1)&0xFF
(h, w) = ((y2-y1),(x2-x1))
if key==ord('w'):
cv2.destroyAllWindows()
else:
x1,y1,w,h = ( 0, 0, self.W, self.H )
if w%2 ==0:
pass
else:
w=w+1
if h%2 ==0:
pass
else:
h=h+1
windowRegion = ( x1, y1, w, h )
return x1,y1,w,h
def run(self,inp,out):
global windowRegion
self.st = time.time()
cnt = 0
while (True):
if self.useCam ==True:
windowRegion = ( 0, 0, self.W, self.H )
frame = np.array(pyautogui.screenshot(region=windowRegion),dtype="uint8")
frame = imutils.resize(frame, width=480)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cv2.imshow("Preview",frame)
rt = relativedelta(seconds=time.time()-self.st)
st = ('{:02d}:{:02d}:{:02d}'.format(int(rt.hours), int(rt.minutes), int(rt.seconds)))
self.pushButton.setText('Stop Recording: '+st)
if cv2.waitKey(1) == 27:
w = gw.getWindowsWithTitle('Windows PowerShell')[0]
w.close()
cv2.destroyAllWindows()
break
def takeSnapNow(self):
if self.clicked ==False:
filename = QtWidgets.QFileDialog.getSaveFileName( self.centralwidget,"Save video to file", os.sep.join((os.path.expanduser('~'), 'Desktop')), "MP4(*.mp4);;AVI(*.avi);;MKV(*.mkv);;MOV(*.mov)")
while filename[0] == '':
pyautogui.alert(text='Please write a video name', title='File name required', button='OK')
filename = QtWidgets.QFileDialog.getSaveFileName( self.centralwidget,"Save video to file", os.sep.join((os.path.expanduser('~'), 'Desktop')), "MP4(*.mp4);;AVI(*.avi);;MKV(*.mkv);;MOV(*.mov)")
try:
os.remove(filename[0])
except:
pass
x1,y1,w,h = self.takeSnap()
# self.cmd = r'"ffmpeg -rtbufsize 100M -f dshow -i audio="{}" -f -y -rtbufsize 100M -f gdigrab -framerate 30 -offset_x {} -offset_y {} -video_size {}x{} -draw_mouse 1 -i desktop -c:v libx264 -r 30 -preset ultrafast -tune zerolatency -crf 25 -pix_fmt yuv420p "{}"'.format(self.Mic,x1,y1,w,h,filename[0])
self.cmd = """ffmpeg -rtbufsize 1500M -f dshow -i audio="{}" -f -y -rtbufsize 1500M -f gdigrab -framerate ntsc -offset_x {} -offset_y {} -video_size {}x{} -draw_mouse 1 -i desktop -c:v libx264 -r 30 -preset ultrafast -tune zerolatency -crf 1 -pix_fmt yuv420p "{}" """.format(self.Mic,x1,y1,w,h,filename[0])
self.arguments = shlex.split(self.cmd)
self.th[0] = Thread(target = self.run,args = (1,1))
self.th[1] = Thread(target = self.makeVideo,args = (1,))
self.th[0].start()
self.th[1].start()
self.clicked =True
self.pushButton.setShortcut("Ctrl+r")
self.radioButton.setEnabled(False)
else:
self.pushButton.setEnabled(False)
self.pushButton.setText('Finalizing...')
w = gw.getWindowsWithTitle('Windows PowerShell')[0]
w.close()
self.clicked =False
def makeVideo(self,inp):
#self.process = subprocess.Popen(self.arguments, shell=True)
FNULL = open(os.devnull, 'w')
retcode = subprocess.call(self.arguments, stdout=FNULL, stderr=subprocess.STDOUT)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "PyShine Video Recorder"))
self.comboBox.setItemText(0, _translate("MainWindow", "Select Audio Device"))
self.radioButton.setText(_translate("MainWindow", "Full Screen"))
self.pushButton.setText(_translate("MainWindow", "Start Recording"))
self.pushButton.setShortcut(_translate("MainWindow", "Ctrl+r"))
self.actionNew.setText(_translate("MainWindow", "New"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
No comments