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: Ranttali 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.6-cp314-cp314-win_amd64.whl (216.5 kB view details)

Uploaded CPython 3.14Windows x86-64

liru-0.2.6-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.6-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: liru-0.2.6-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.6-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 72220a4a8d1ca463de25932be70a743ff12bc903b0125e6174ba0255a40a882f
MD5 221f73917820734c028efecf9b2279e2
BLAKE2b-256 535690aea0aabd36c1301c4eb93aa26cb0f67c79e9bcb6c34bb19f2875e82cf9

See more details on using hashes here.

Provenance

The following attestation bundles were made for liru-0.2.6-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.6-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: liru-0.2.6-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.6-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 f02fb5a95fcf7da14959df65412a88232e1f932899dd69f3e1dad1500c735fe2
MD5 ecdbea1f103914e929ef44e6e30b4ee4
BLAKE2b-256 e1b3395cd6f354c2f9fa0006e3d42d943a10c5f0bed5dcdc7ca34c15c0b4cc26

See more details on using hashes here.

Provenance

The following attestation bundles were made for liru-0.2.6-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