Skip to content

mbaetgen-wup/gst-projectm

 
 

Repository files navigation

Contributors Forks Stargazers Issues LGPL-2.1


gst-projectm

GStreamer plugin utilizing the projectM library.

Report Bug · Request Feature


Table of Contents
  1. Getting Started
  2. Plugin Properties
  3. Presets and Textures
  4. Release Packages
  5. Usage Examples
  6. Technical Details
  7. Logging and Debugging
  8. Easy Audio to Video Conversion (Docker)
  9. Contributing
  10. Licensing
  11. Support
  12. Contact

Getting Started

gst-projectm is a GStreamer plugin that takes an audio stream as input and produces a video stream of real-time projectM visualizations. It is not a standalone application — it is a plugin element (projectm) that runs inside any GStreamer pipeline, which means it works from the command line with gst-launch-1.0, inside applications that use GStreamer, in Docker containers, or anywhere GStreamer runs.

The plugin renders directly to OpenGL textures via FBO and outputs video/x-raw(memory:GLMemory) buffers that stay in GPU memory. Use glimagesink for zero-copy display, or gldownload when you need to hand off to CPU-side elements like video encoders.

There are several ways to get the plugin, depending on what you need:

Option What it does Best for Guide
Install a package Adds the plugin to your existing GStreamer installation. Use with gst-launch-1.0 or any GStreamer app. Most users Linux · macOS · Windows
Rebuild from source packages Recompile from .dsc or .src.rpm for your exact distro and architecture, without cloning the repo. Distro packagers, non-x86 architectures Linux
Build from source Clone the repo and build. Full control over dependencies and build options. Developers, custom projectM builds Linux · macOS · Windows
Docker container One-command audio-to-video conversion. No setup required. Quick audio-to-video rendering Docker conversion
Flatpak / AppImage Self-contained bundles that ship their own GStreamer and run gst-launch-1.0 directly. No system GStreamer needed. Quick testing without installing anything Linux — Portable Bundles

Packages that install the plugin (DEB, RPM, ZIP, tar.gz) place a single shared library (libgstprojectm.so / .dll) into your GStreamer plugin path. After that, the projectm element is available in every pipeline on the system. The Flatpak and AppImage bundles are different — they are self-contained executables that include their own copy of GStreamer and are intended for quick testing, not as a way to add the plugin to your system.

(back to top)

Plugin Properties

The projectm element accepts these properties, set in a pipeline with property=value syntax:

Property Type Default Description
preset string (none) Path to a directory of MilkDrop preset files (.milk).
texture-dir string (none) Path to a directory of texture images used by presets.
preset-duration double 0 (indefinite) Seconds before auto-switching to the next preset. 0 plays indefinitely.
soft-cut-duration double 3.0 Duration in seconds of smooth crossfade transitions.
hard-cut-duration double 3.0 Minimum seconds between hard (abrupt) cuts.
hard-cut-enabled boolean false Allow hard cuts triggered by beats in the audio.
hard-cut-sensitivity float 1.0 Sensitivity for hard cut triggers (0.0–1.0).
beat-sensitivity float 1.0 How strongly the visualizer responds to beats (0.0–5.0).
mesh-size string 48,32 Visualization mesh resolution as width,height. Higher = smoother but slower.
aspect-correction boolean true Adjust rendering for non-square aspect ratios.
easter-egg float 0.0 Probability of triggering the easter egg (0.0–1.0).
preset-locked boolean false Lock on the current preset, disabling automatic switching.
enable-playlist boolean true Enable playlist-based preset switching.
shuffle-presets boolean true Randomize preset order. Requires enable-playlist=true.
is-live string auto Rendering mode: auto detects live pipelines automatically, true forces real-time rendering (may drop frames), false forces offline rendering (as fast as possible). Auto-detection is not supported on Windows or GStreamer < 1.24; set explicitly in those cases.
min-fps string 1/1 Lower bound for adaptive FPS in live pipelines, as a fraction (e.g. 15/1). When rendering can't keep up with the pipeline framerate, the plugin reduces its target FPS down to this floor. Only applies when is-live=true.

Output video resolution and framerate are set through GStreamer caps, not plugin properties. The plugin outputs video/x-raw(memory:GLMemory) in RGBA format:

... ! projectm ! "video/x-raw(memory:GLMemory),width=1920,height=1080,framerate=60/1" ! ...

Run gst-inspect-1.0 projectm for the full listing from your installed version.

(back to top)

Presets and Textures

The plugin requires MilkDrop-compatible preset files to produce visualizations. Presets may also reference textures. Neither presets nor textures are bundled with any release package — download them separately:

Resource Repository
Presets (curated) projectM-visualizer/presets-cream-of-the-crop
Textures projectM-visualizer/presets-milkdrop-texture-pack
git clone https://github.com/projectM-visualizer/presets-cream-of-the-crop.git ~/projectM-presets
git clone https://github.com/projectM-visualizer/presets-milkdrop-texture-pack.git ~/projectM-textures

Then pass the paths to the plugin:

gst-launch-1.0 audiotestsrc ! queue ! audioconvert \
  ! projectm preset=~/projectM-presets texture-dir=~/projectM-textures preset-duration=10 \
  ! "video/x-raw(memory:GLMemory),width=1920,height=1080,framerate=60/1" \
  ! glimagesink

You can also use any directory of .milk preset files, including your own.

(back to top)

Release Packages

Pre-built packages are available on the GitHub Releases page.

Package Variants

Variant Description
static-gl projectM statically linked with desktop OpenGL. Self-contained — no external projectM needed. Recommended for most desktop systems.
static-gles projectM statically linked with OpenGL ES. For embedded or GLES-only environments.
dynamic projectM not included. Requires projectM (>= 4.2.0) installed separately.

Only one variant can be installed at a time — they conflict with each other.

Platform Packages

Format Platform Guide
DEB Ubuntu, Debian Linux
RPM Fedora, RHEL Linux
DEB Source / SRPM Any DEB/RPM-based distro Linux
ZIP Windows (x64) Windows
tar.gz macOS (arm64) macOS
Flatpak / AppImage Linux (x86_64) Linux — Portable Bundles

(back to top)

Usage Examples

These examples assume the plugin is installed and presets/textures have been downloaded (see above).

Live Audio Visualization

# Visualize a test tone (zero-copy GL display)
gst-launch-1.0 audiotestsrc ! queue ! audioconvert \
  ! projectm preset=~/projectM-presets texture-dir=~/projectM-textures preset-duration=5 \
  ! "video/x-raw(memory:GLMemory),width=1920,height=1080,framerate=60/1" \
  ! glimagesink

# Visualize PipeWire/PulseAudio system audio
gst-launch-1.0 pipewiresrc ! queue ! audioconvert \
  ! projectm preset=~/projectM-presets preset-duration=5 \
  ! "video/x-raw(memory:GLMemory),width=2048,height=1440,framerate=60/1" \
  ! glimagesink

Audio to Video Conversion

For offline (faster-than-real-time) conversion, use gldownload to transfer frames from GPU to CPU memory before encoding:

gst-launch-1.0 -e \
  filesrc location=input.mp3 ! decodebin ! tee name=t \
    t. ! queue ! audioconvert ! audioresample \
      ! "audio/x-raw,format=F32LE,channels=2,rate=44100" \
      ! avenc_aac bitrate=320000 ! queue ! mux. \
    t. ! queue ! audioconvert \
      ! projectm preset=~/projectM-presets texture-dir=~/projectM-textures \
          preset-duration=6 mesh-size=1024,576 is-live=false \
      ! "video/x-raw(memory:GLMemory),framerate=60/1,width=3840,height=2160" \
      ! gldownload ! videoconvert ! videorate \
      ! x264enc bitrate=50000 key-int-max=200 speed-preset=veryslow \
      ! "video/x-h264,stream-format=avc,alignment=au" ! queue ! mux. \
  mp4mux name=mux ! filesink location=output.mp4

Some elements (x264enc, avenc_aac) require additional GStreamer plugin packages on your system (e.g. gstreamer1.0-plugins-ugly, gstreamer1.0-libav).

(back to top)

Internals

OpenGL Rendering and Buffer Handling

projectM output is rendered to OpenGL textures via Frame Buffer Objects (FBO). Textures are pooled and reused across frames. Each rendered texture becomes a GStreamer video buffer pushed downstream — all video buffers stay in GPU memory as video/x-raw(memory:GLMemory). Use glimagesink for zero-copy display, or gldownload to transfer to system memory for CPU-side elements like video encoders.

Timing and Synchronization

The plugin synchronizes rendering to the GStreamer pipeline clock using the audio presentation timestamp (PTS) as the leading reference. Pipeline caps control the desired video framerate. The render loop is push-based to conform with GStreamer's pipeline timing model and to enable faster-than-real-time rendering. A fixed number of audio samples is consumed per video frame — for example, 735 samples per frame at 44.1 kHz yields approximately 60 FPS.

Live pipelines are auto-detected if GStreamer supports it (not supported on Windows or GStreamer < 1.24). For those cases, set is-live=true explicitly. The default mode is offline rendering (is-live=false), which renders as fast as possible. In live mode, frames may be dropped or the rendering FPS may be reduced adaptively if frame rendering cannot keep up with the pipeline framerate.

Video frame PTS offset is derived from the first audio buffer PTS or segment event, plus accumulated samples, to align video timing with the audio stream.

Timing Source Origin Mode Purpose
Audio Timestamps Audio input All Determine video timing and sync
Sample Rate / Pipeline FPS Audio input / Caps All Number of audio samples per frame and target FPS
Segment Info Segment event All Running time and playback position for PTS offsets
QoS Feedback QoS event Live Skip outdated frames to correct sync with downstream
Render Frame Drop Render loop Live Drop frames that cannot be rendered in time
GL Frame Render Duration Render loop Live EMA of frame render duration; adjusts plugin target FPS when rendering consistently exceeds the real-time budget
Latency Event Render loop Live Inform upstream of latency changes from adaptive FPS
Buffer Push Clock Jitter Render loop Live EMA of source pad push jitter from the scheduler; added as a correction to buffer PTS

(back to top)

Logging and Debugging

The plugin uses GStreamer's standard logging system. Set the GST_DEBUG environment variable to control verbosity per category. The general syntax is category:level, where levels range from 1 (errors only) to 7 (full trace). Multiple categories are comma-separated.

Quick Start

# See errors and warnings from the plugin
GST_DEBUG=gstprojectm:3,projectm_base:3 gst-launch-1.0 ...

# Debug frame drops and adaptive FPS in live pipelines
GST_DEBUG=renderbuffer:5,pmaudiovisualizer:5 gst-launch-1.0 ...

# Full trace (very verbose)
GST_DEBUG=gstprojectm:7,projectm_base:7,glbaseaudiovisualizer:7,pmaudiovisualizer:7,renderbuffer:7,pushbuffer:7 gst-launch-1.0 ...

Plugin Log Categories

Category Source What it logs
projectm_base gstprojectmbase.c projectM instance lifecycle, property changes, preset loading, and all log output from the projectM library itself (errors, warnings, info, debug from libprojectM are forwarded through this category)
gstprojectm gstprojectm.c Top-level plugin element: GL start/stop, per-frame render dispatch, audio/video caps
glbaseaudiovisualizer gstglbaseaudiovisualizer.c GL context discovery, FBO setup, render mode detection (live vs offline), caps changes, state transitions
pmaudiovisualizer gstpmaudiovisualizer.c Audio/video timing, QoS frame skipping, segment events, latency negotiation, buffer pool management
renderbuffer renderbuffer.c Render slot scheduling, frame drop events (eviction and timeout), adaptive FPS (EMA adjustments), render duration monitoring
pushbuffer pushbuffer.c Buffer push scheduling, clock wait jitter tracking
buffercleanup bufferdisposal.c GL buffer disposal lifecycle

(back to top)

Easy Audio to Video Conversion

A Docker-based conversion tool is included for one-command audio-to-video rendering with no manual setup.

Prerequisites

Quick Start

git clone https://github.com/projectM-visualizer/gst-projectm.git
cd gst-projectm
./projectm-convert -i your-audio-file.mp3 -o output-video.mp4

The first run builds the container automatically (takes a while). Subsequent runs use the cached image. Conversion time depends on audio length and settings.

Conversion Options

Option Description Default
-d, --duration SEC Seconds between preset transitions 6
--mesh WxH Mesh size for visualization 1024x576
--video-size WxH Output video resolution 1920x1080
-r, --framerate FPS Output frame rate 60
-b, --bitrate KBPS Video bitrate in kbps 8000
--speed PRESET x264 speed preset (ultrafast to veryslow) medium
-p, --preset DIR Path to custom presets directory Default presets
# 4K high quality
./projectm-convert -i song.mp3 -o viz-4k.mp4 --video-size 3840x2160 -b 16000 --speed veryslow

# Quick test
./projectm-convert -i song.mp3 -o viz-test.mp4 --speed ultrafast --video-size 1280x720

(back to top)

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

Licensing

This project distinguishes between the plugin source code and the distribution bundle:

  • The Plugin: The source code for gst-projectm is licensed under the GNU Lesser General Public License (LGPL) v2.1 or later. This allows for broad compatibility with both open-source and proprietary applications. See LICENSE.
  • The AppImage/Flatpak: The binary distribution bundle is licensed under the GNU General Public License (GPL) v2.0 or later.

Note: This "upgrade" to GPL applies only to the bundle itself. It is required because the bundle includes GStreamer's "Ugly" plugin set, which contains GPL-licensed dependencies (such as x264). See BUNDLE-LICENSE.

(back to top)

Support

Discord

(back to top)

Contact

Blaquewithaq (Discord: SoFloppy#1289) - @anomievision - anomievision@gmail.com

Mischa (Discord: mish) - @revmischa

(back to top)

About

This is a plugin for GStreamer that allows you to utilize the ProjectM library to create visualizations from audio.

Resources

License

LGPL-2.1, GPL-2.0 licenses found

Licenses found

LGPL-2.1
LICENSE
GPL-2.0
BUNDLE-LICENSE

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • C 79.3%
  • Shell 9.5%
  • CMake 6.4%
  • PowerShell 3.7%
  • Dockerfile 1.1%