Here is a screencast of the result. I type some text in the window, close the app and open the mp4 file in Preview:
And here is how to do it:
python3 -m venv env
source env/bin/activate
pip install pyside6
pip install imageio
pip install imageio-ffmpeg
Create main.py and paste this code:
import sys
import imageio
import numpy as np
from PIL import Image
from PySide6.QtWidgets import QApplication
from PySide6.QtWidgets import QMainWindow
from PySide6.QtWidgets import QLabel
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLineEdit
from PySide6.QtCore import Qt
from PySide6.QtGui import QPixmap
from PySide6.QtCore import QSize
from PySide6.QtCore import QTimer
from __feature__ import snake_case, true_property
class VideoWriter(QTimer):
fps = 24
def __init__(self, widget, filepath):
super().__init__()
self.widget = widget
self.writer = imageio.get_writer(filepath, format="mp4", mode="I", fps=self.fps)
self.timeout.connect(self.append_frame)
def render_pixmap(self):
size = QSize(self.widget.size.width() * 2, self.widget.size.height() * 2)
pixmap = QPixmap(size)
pixmap.set_device_pixel_ratio(2)
self.widget.render(pixmap)
return pixmap
def start_recording(self):
self.start(1000 / self.fps)
def append_frame(self):
pixmap = self.render_pixmap()
bytes = pixmap.to_image().bits().tobytes()
size = pixmap.size()
w = size.width()
h = size.height()
array = np.frombuffer(bytes, dtype=np.uint8).reshape(h, w, 4)
self.writer.append_data(np.asarray(np.roll(array, 1)))
def dispose(self):
self.stop()
self.writer.close()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.window_title = "INPUT"
self.size = QSize(200, 152)
self.lineedit = QLineEdit()
self.lineedit.set_parent(self)
self.lineedit.set_focus()
self.set_central_widget(self.lineedit)
self.style_sheet = "border-style: none; padding: 8px; color:#fff; background-color: #f00"
app = QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()
video_writer = VideoWriter(mainwindow, "screencast.mp4")
video_writer.start_recording()
app.exec_()
video_writer.dispose()