Recording the screen of a QEMU/KVM virtual machine (VM) directly—without capturing the host's Virtual Machine Manager window or the guest OS screen—can be achieved by leveraging QEMU's built-in capabilities. Here’s how you can do it:
ffmpegThis method involves redirecting the VM's display to a VNC server and then recording the VNC output using ffmpeg.
Start the VM with VNC Display
When starting your VM, use the -vnc option to expose the display over VNC. For example:
bashqemu-system-x86_64 -vnc :1 -display none ...
:1 means the VNC server will listen on port 5901 (default VNC port is 5900 + display number).-display none disables the default graphical window.Connect to the VNC Server
Use a VNC client (like vinagre, tigervnc-viewer, or RealVNC) to connect to localhost:5901 and verify the display is working.
Record the VNC Display with ffmpeg
Use ffmpeg to capture the VNC display:
bashffmpeg -f vnc -i localhost:5901 -r 30 -c:v libx264 -preset ultrafast -crf 0 output.mp4
-r 30: Sets the frame rate to 30 FPS.-c:v libx264: Uses the H.264 codec for recording.-preset ultrafast: Optimizes for speed (lower quality, but faster encoding).-crf 0: Lossless recording (adjust for quality vs. file size).output.mp4: Output file name.Stop Recording
Press q in the ffmpeg terminal to stop recording.
spice-vdagentIf your VM uses SPICE for display, you can record the SPICE stream.
Start the VM with SPICE
Use the -spice option to enable SPICE:
bashqemu-system-x86_64 -spice port=5900,disable-ticketing -vga qxl -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent ...
Connect to SPICE
Use a SPICE client (like virt-viewer or Remote Viewer) to connect to localhost:5900.
Record SPICE with ffmpeg
Use ffmpeg to capture the SPICE display:
bashffmpeg -f spice -i localhost:5900 -r 30 -c:v libx264 -preset ultrafast -crf 0 output.mp4
-display sdl and ffmpegIf you want to avoid VNC/SPICE, you can use SDL (Simple DirectMedia Layer) for display and pipe it to ffmpeg.
Start the VM with SDL Display
bashqemu-system-x86_64 -display sdl ...
Record SDL Window with ffmpeg
Use ffmpeg to capture the SDL window by its title:
bashffmpeg -f x11grab -i :0.0+100,200 -r 30 -c:v libx264 -preset ultrafast -crf 0 output.mp4
:0.0+100,200: X11 display and offset (adjust 100,200 to match the SDL window position).-display none and FramebufferIf you want to record the raw framebuffer, you can dump it to a file and encode it.
Start the VM with Framebuffer Dump
bashqemu-system-x86_64 -display none -serial stdio -device virtio-gpu-pci,xres=1920,yres=1080 -vga none ...
Use ffmpeg to Record Framebuffer
This method is complex and requires custom scripting to dump the framebuffer to a file and encode it.
Use Method 1 (VNC + ffmpeg) for simplicity and reliability. It works well for headless recording and avoids capturing the host window.
ffmpeg is installed (sudo apt install ffmpeg on Debian/Ubuntu).-r, -crf, and -preset in ffmpeg for performance/quality trade-offs.-preset superfast or -preset veryfast instead of ultrafast.Vibe can make mistakes. Check answers. Learn more