Skip to main content

High-performance Python wrapper for Spout 2.007 GPU texture sharing

Project description

liru

High-performance Python wrapper for Spout 2 GPU texture sharing

License: BSD-2-Clause Python 3.13+ Platform: Windows

liru provides zero-copy GPU texture sharing between Python applications using the Spout 2 DirectX 11 shared texture mechanism. Designed for real-time video mixing, compositing, and live graphics applications on Windows.

Key Features

  • Zero-Copy GPU Sharing: Direct GPU-to-GPU texture transfer via DirectX 11
  • Real-Time Performance: Minimal latency for 60 FPS+ video pipelines
  • ModernGL Integration: Seamless interoperability with ModernGL contexts
  • Simple API: Pythonic interface wrapping Spout 2.007 SDK
  • Type Hints: Full type annotations for IDE autocomplete and type checking
  • Context Managers: Automatic resource cleanup with with statements

Installation

pip install liru

Requirements:

  • Windows 10/11 (Spout is Windows-only)
  • Python 3.13 or later
  • DirectX 11 compatible GPU
  • Visual C++ Redistributable 2022 (usually already installed)

Quick Start

Sending Textures

import moderngl
import liru

# Create OpenGL context and texture
ctx = moderngl.create_context()
texture = ctx.texture((1920, 1080), 4)  # RGBA

# Send textures via Spout (automatic cleanup with context manager)
with liru.Sender("MyOutput", 1920, 1080) as sender:
    running = True
    while running:
        # Render to texture
        # ... your rendering code ...

        # Send via Spout (GPU-only, zero CPU copy)
        sender.send_texture(texture.glo)

        # Optional: monitor performance
        print(f"FPS: {sender.get_fps():.1f}, Latency: {sender.last_send_time_ms:.3f}ms")

Receiving Textures

import moderngl
import liru

ctx = moderngl.create_context()

# Connect to a Spout sender (automatic cleanup with context manager)
with liru.Receiver("MyOutput") as receiver:
    # Get dimensions immediately (no frame reception required)
    print(f"Sender resolution: {receiver.width}x{receiver.height}")

    # Create texture sized to match sender
    texture = ctx.texture((receiver.width, receiver.height), 4)

    running = True
    while running:
        # Note: is_updated() may return False for first 1-2 frames
        # while the OpenGL connection is being established
        if receiver.is_updated():
            width, height = receiver.receive_texture(texture.glo)
            # Use texture for compositing, preview, etc.
            # ... your processing code ...

Listing Available Senders

import liru

with liru.Receiver() as receiver:
    senders = receiver.get_sender_list()
    for sender_name in senders:
        print(f"Available sender: {sender_name}")

Documentation

Why liru?

You want to use Python and Spout. It seems alternatives were somewhat stale or lacking at the time I needed this.

API Overview

Sender

# Constructor
liru.Sender(name: str, width: int, height: int)

# Methods
send_texture(texture_id: int) -> None
get_fps() -> float
release() -> None

# Properties
name: str                  # Sender name
width: int                 # Texture width
height: int                # Texture height
last_send_time_ms: float   # Last send operation time in milliseconds

Receiver

# Constructor
liru.Receiver(sender_name: str = "")

# Methods
receive_texture(texture_id: int) -> tuple[int, int]  # Returns (width, height)
is_updated() -> bool
select_sender(name: str) -> None
get_sender_list() -> list[str]

# Properties
active_sender: str         # Currently connected sender name
width: int                 # Sender texture width
height: int                # Sender texture height
last_receive_time_ms: float  # Last receive operation time in milliseconds

Development

For contributors and developers who want to build from source, see CONTRIBUTING.md for detailed setup instructions.

Project Structure

liru/
├── liru/                   # Python package
│   ├── __init__.py         # Public API
│   ├── sender.py           # Sender wrapper
│   ├── receiver.py         # Receiver wrapper
│   └── py.typed            # Type checking marker
├── src/                    # C++ sources
│   ├── bindings.cpp        # pybind11 bindings
│   ├── sender_wrapper.cpp  # Sender implementation
│   └── receiver_wrapper.cpp # Receiver implementation
├── tests/                  # Test suite
├── docs/                   # Documentation
├── CMakeLists.txt          # CMake configuration
├── pyproject.toml          # Python packaging (scikit-build-core)
└── README.md               # This file

Contributing

Contributions are welcome! Please read CONTRIBUTING.md for guidelines on:

  • Setting up your development environment
  • Running tests
  • Code style and quality standards
  • Submitting pull requests

License

liru is licensed under the BSD-2-Clause License - see LICENSE for details. Q: Why not MIT? A: Because Spout is BSD-2 too so 1 type is less than 2.

Third-Party Components

liru includes and redistributes the following third-party components:

All third-party licenses are included in the distribution and must be retained when redistributing liru.

Acknowledgments

Support

Project Status

liru is under active development (Alpha). The API is stable but may change before the 1.0 release.


Maintained by: Veitsi Development Team License: BSD-2-Clause

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

liru-0.2.5-cp314-cp314-win_amd64.whl (216.5 kB view details)

Uploaded CPython 3.14Windows x86-64

liru-0.2.5-cp313-cp313-win_amd64.whl (210.2 kB view details)

Uploaded CPython 3.13Windows x86-64

File details

Details for the file liru-0.2.5-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: liru-0.2.5-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 216.5 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for liru-0.2.5-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 c8d6e3bebde6791f75c3585812b6ed4b3716e2db85622084920f96d174861eb3
MD5 32ca5a8d2b9b33b493aa75b9cc05ee02
BLAKE2b-256 f5d12673a92c294169f3ce81f7127d16ef04ca9b69d40f52816c903cfb62f401

See more details on using hashes here.

Provenance

The following attestation bundles were made for liru-0.2.5-cp314-cp314-win_amd64.whl:

Publisher: release.yml on Ranttali/liru

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file liru-0.2.5-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: liru-0.2.5-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 210.2 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for liru-0.2.5-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 60e1052dc7a843e50010a011307170869fcd98f2c570669e4c42826a227e60ef
MD5 b245d4fa9798e300625125556eed2b7a
BLAKE2b-256 3ba7fb8565ea2f129425d158d54ecf5e5c625bc396341afe715e1c90ab376da9

See more details on using hashes here.

Provenance

The following attestation bundles were made for liru-0.2.5-cp313-cp313-win_amd64.whl:

Publisher: release.yml on Ranttali/liru

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page