如何用Python结合GStreamer录制桌面视频并保存为文件?
Absolutely doable! You’ve already got the core pipeline for capturing the desktop with GStreamer—all you need to do is swap out the ximagesink (which displays the video on screen) with elements that encode and save the stream to a file. Here are two straightforward ways to implement this in Python:
This approach gives you more control over the pipeline (like handling errors, pausing/resuming, or adding audio capture later) instead of just running a shell command.
First, make sure you have the required packages installed:
sudo apt-get install python3-gi python3-gi-cairo gir1.2-gstreamer-1.0
Then here’s a complete Python script that captures your desktop and saves it as an MP4 file:
import gi gi.require_version('Gst', '1.0') from gi.repository import Gst, GLib def main(): # Initialize GStreamer Gst.init(None) # Build the pipeline pipeline = Gst.Pipeline.new("desktop-recorder") # Create elements ximagesrc = Gst.ElementFactory.make("ximagesrc", "desktop-source") caps_filter_raw = Gst.ElementFactory.make("capsfilter", "raw-caps") videoscale = Gst.ElementFactory.make("videoscale", "scaler") caps_filter_scaled = Gst.ElementFactory.make("capsfilter", "scaled-caps") x264enc = Gst.ElementFactory.make("x264enc", "video-encoder") mp4mux = Gst.ElementFactory.make("mp4mux", "muxer") filesink = Gst.ElementFactory.make("filesink", "file-output") # Check if all elements were created successfully if not all([pipeline, ximagesrc, caps_filter_raw, videoscale, caps_filter_scaled, x264enc, mp4mux, filesink]): print("Failed to create one or more GStreamer elements") return # Set element properties ximagesrc.set_property("startx", 0) ximagesrc.set_property("use-damage", 0) caps_filter_raw.set_property("caps", Gst.Caps.from_string("video/x-raw,framerate=30/1")) caps_filter_scaled.set_property("caps", Gst.Caps.from_string("video/x-raw,width=1280,height=1080")) x264enc.set_property("speed-preset", 1) # 1 is fast, adjust for quality/speed tradeoff filesink.set_property("location", "desktop_recording.mp4") # Add elements to pipeline pipeline.add(ximagesrc) pipeline.add(caps_filter_raw) pipeline.add(videoscale) pipeline.add(caps_filter_scaled) pipeline.add(x264enc) pipeline.add(mp4mux) pipeline.add(filesink) # Link elements together if not ximagesrc.link(caps_filter_raw): print("Failed to link ximagesrc to caps_filter_raw") return if not caps_filter_raw.link(videoscale): print("Failed to link caps_filter_raw to videoscale") return if not videoscale.link(caps_filter_scaled): print("Failed to link videoscale to caps_filter_scaled") return if not caps_filter_scaled.link(x264enc): print("Failed to link caps_filter_scaled to x264enc") return if not x264enc.link(mp4mux): print("Failed to link x264enc to mp4mux") return if not mp4mux.link(filesink): print("Failed to link mp4mux to filesink") return # Start the pipeline pipeline.set_state(Gst.State.PLAYING) # Run the GLib main loop to keep the pipeline running loop = GLib.MainLoop() try: loop.run() except KeyboardInterrupt: print("\nStopping recording...") # Stop the pipeline properly to avoid corrupted files pipeline.set_state(Gst.State.NULL) loop.quit() if __name__ == "__main__": main()
To stop the recording, just press Ctrl+C—the script will clean up the pipeline to ensure the MP4 file is properly finalized.
gst-launch Command via subprocess If you prefer a simpler approach without dealing with GStreamer's Python API, you can modify your original gst-launch command to output to a file instead of a window, then run it using Python's subprocess module.
Here’s the modified command and Python code:
import subprocess # Modified GStreamer command (swaps ximagesink for encoding + file output) gst_command = [ "gst-launch-1.0", "ximagesrc", "startx=0", "use-damage=0", "!", "video/x-raw,framerate=30/1", "!", "videoscale", "method=0", "!", "video/x-raw,width=1280,height=1080", "!", "x264enc", "speed-preset=1", "!", "mp4mux", "!", "filesink", "location=desktop_recording.mp4" ] try: print("Starting recording... Press Ctrl+C to stop.") subprocess.run(gst_command, check=True) except KeyboardInterrupt: print("\nRecording stopped.") except subprocess.CalledProcessError as e: print(f"Error running GStreamer command: {e}")
Quick Notes:
- Format Flexibility: If you want a different output format, swap
x264encandmp4mux—for example, usevp8enc+webmmuxfor WebM, oravenc_mpeg4+avimuxfor AVI. - Audio Capture: To include system audio, add an audio pipeline branch (e.g.,
pulsesrc ! audioconvert ! voaacenc ! mp4mux—ensure both video and audio streams link to the muxer). - Quality vs Speed: Adjust the
speed-presetonx264enc(0 = slow/high quality, 5 = fast/lower quality) based on your system's performance.
内容的提问来源于stack exchange,提问作者Isocrates

