Streamlit FunPlayer

July 19, 2025 ยท View on GitHub

A modern React component for synchronized media and haptic playback with professional-grade performance and VR support.

License: CC BY-NC-SA 4.0 Python 3.9+ Streamlit React

Overview

FunPlayer is a versatile in-browser media player based on Video.js that synchronizes audio/video content with haptic feedback devices through the Buttplug.io ecosystem. Built with modern React architecture and optimized for real-time performance, it supports everything from simple media playback to complex multi-channel haptic orchestration.

Key Differentiators:

  • ๐ŸŽฏ React-first architecture 100% JS/React, this Streamlit component being provided as a convenience wrapper for Python integration
  • โšก 120Hz haptic refresh rate with optimized interpolation caching
  • ๐Ÿฅฝ Native VR support (Quest, Pico) via browser with Intiface sideload
  • ๐Ÿ”ง Modular design - autonomous managers with event-driven communication
  • ๐ŸŽฎ 100+ device compatibility through Buttplug.io and Intiface Central ecosystem
  • ๐ŸŽจ Professional UI with real-time visualization and adaptive theming

Quick Start

Installation

pip install streamlit-funplayer

Basic Usage

import streamlit as st
from streamlit_funplayer import funplayer

# Simple video with haptic synchronization + custom theme
funplayer(
    playlist=[{
        'sources': [{'src': 'video.mp4', 'type': 'video/mp4'}],
        'funscript': {'actions': [{"at": 0, "pos": 0}, {"at": 1000, "pos": 100}, ...]},
        'name': 'Demo Scene'
    }],
    theme={
        'primaryColor': '#FF6B6B',
        'backgroundColor': '#1E1E1E'
    }
)

Features

๐ŸŽฌ Universal Media Support

Formats & Protocols:

  • Video: MP4, WebM, MOV, AVI, MKV, M4V
  • Audio: MP3, WAV, OGG, M4A, AAC, FLAC
  • Streaming: HLS (m3u8), DASH (mpd), direct URLs
  • VR: 360ยฐ/180ยฐ content with WebXR integration
  • Haptic-only: Timeline playback without media

Smart Playlists:

  • Auto-progression with seamless transitions
  • Mixed content types (video + audio + haptic-only)
  • Poster generation and metadata handling

๐ŸŽฎ Advanced Haptic System

Device Integration:

  • Buttplug.io ecosystem - 100+ supported devices
  • Auto-discovery and intelligent capability mapping
  • Multi-actuator support (vibration, linear, rotation, oscillation)
  • Virtual device mode for development without hardware

Real-time Performance:

  • 120Hz update rate with adaptive throttling
  • Interpolation caching for smooth seeking
  • Sub-millisecond timing accuracy for VR applications
  • Memory-optimized processing for long sessions

Professional Controls:

  • Per-channel configuration (scale, offset, range, invert)
  • Global modulation with real-time adjustment
  • Multi-channel funscripts with automatic routing
  • Live visualization with customizable waveforms

๐Ÿฅฝ VR & Cross-Platform

VR Optimization:

  • Meta Quest native (via Intiface Central sideload)
  • Browser-based - zero app store friction
  • 90Hz display + 120Hz haptic synchronized rendering
  • Memory management optimized for sustained VR sessions

Platform Support:

  • Desktop: Windows, macOS, Linux
  • Mobile: iOS, Android browsers
  • VR Headsets: Quest 2/3/Pro, Pico, any WebXR device
  • HTTPS required for device access in production

API Reference

Core Function

funplayer(
    playlist: Optional[List[Dict[str, Any]]] = None,
    theme: Optional[Dict[str, Any]] = None,
    key: Optional[str] = None
) -> Any

Playlist Item Format

The playlist parameter is an optional list of dict items. The playlist item format follows Video.js format with additional haptic integration via the funscript parameter. Multiple sources can be provided for a single item to allow the user or the player to select the quality of the playback (480p, 720p, 1080p, etc.) depending on the bandwith available.

{
    'sources': [                        # Media sources (Video.js format)
        {
            'src': 'video_480p.mp4',    # URL / Local file / BytesIO
            'type': 'video/mp4',        # MIME type (optional, auto-detected)
            'label': '480p'             # Quality label (optional)
        },
        {
            'src': 'video_720p.mp4',    # Alternate quality
            'type': 'video/mp4',       
            'label': '720p'             
        }
    ],
    'funscript': funscript,             # Haptic data / URL / Local file / BytesIO
    'name': str,                        # Display title
    'description': str,                 # Description (optional)
    'poster': str,                      # Poster image URL (optional)
    'duration': float,                  # Duration in seconds (optionnal)
    'textTracks': list                  # Subtitles/captions (optional)
}

Theme Parameters

The theme parameter accepts a dictionary with the following optional keys:

theme = {
    # Colors
    'primaryColor': '#FF4B4B',                      # Primary accent color
    'backgroundColor': '#FFFFFF',                   # Main background
    'secondaryBackgroundColor': '#F0F2F6',          # Secondary background
    'textColor': '#262730',                         # Text color
    'borderColor': '#E6EBF5',                       # Border and divider color
    
    # Typography & Layout
    'fontFamily': '"Source Sans Pro", sans-serif',    # Font family
    'baseRadius': '0.5rem',                           # Border radius
    'spacing': '1rem',                                # Base spacing unit
    
    # Base theme (optional)
    'base': 'dark'                                    # Predefined theme base
}

Architecture

Design Philosophy

FunPlayer uses a modular, event-driven architecture where independent managers handle specific domains without tight coupling. FunPlayerCore serves as the central hub, coordinating between business logic managers and UI components through a unified event bus.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                            UI (React)                           โ”‚
โ”‚                    FunPlayer (Main UI Component)                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  MediaPlayer    โ”‚ โ”‚ HapticSettings  โ”‚ โ”‚ HapticVisualizerโ”‚    โ”‚
โ”‚  โ”‚   (Video.js)    โ”‚ โ”‚   (Controls)    โ”‚ โ”‚    (Canvas)     โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚            โ”‚                   โ”‚                   โ”‚            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
             โ”‚                   โ”‚                   โ”‚
             โ”‚                   โ”‚                   โ”‚         
             โ”‚                   โ”‚                   โ”‚          
             โ–ผ                   โ–ผ                   โ–ผ          
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                          FunPlayerCore                          โ”‚
โ”‚                                                                 โ”‚
โ”‚                 Event Bus + State Coordination                  โ”‚
โ”‚                                                                 โ”‚
โ”‚        โ€ข notify() system        โ€ข Lazy manager getters          โ”‚
โ”‚        โ€ข Event routing          โ€ข Lifecycle management          โ”‚
โ”‚        โ€ข State synchronization  โ€ข Error handling                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
             โ–ฒ                    โ–ฒ                   โ–ฒ         
             โ”‚                    โ”‚                   โ”‚           
             โ”‚                    โ”‚                   โ”‚          
             โ”‚                    โ”‚                   โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚            โ”‚                    โ”‚                   โ”‚           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚ ButtPlugManager โ”‚ โ”‚FunscriptManager โ”‚ โ”‚ PlaylistManager โ”‚    โ”‚
โ”‚  โ”‚                 โ”‚ โ”‚                 โ”‚ โ”‚                 โ”‚    โ”‚
โ”‚  โ”‚ โ€ข Device comms  โ”‚ โ”‚ โ€ข Multi-channel โ”‚ โ”‚ โ€ข Content mgmt  โ”‚    โ”‚
โ”‚  โ”‚ โ€ข Auto-mapping  โ”‚ โ”‚ โ€ข Interpolation โ”‚ โ”‚ โ€ข Format valid  โ”‚    โ”‚
โ”‚  โ”‚ โ€ข Capabilities  โ”‚ โ”‚ โ€ข Channel types โ”‚ โ”‚ โ€ข Navigation    โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                 โ”‚
โ”‚                    Business Logic Managers                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Core Components

FunPlayerCore: Central singleton orchestrating manager communication through event bus

ButtPlugManager: Device communication, capability detection, command optimization

FunscriptManager: Multi-channel parsing, intelligent interpolation, auto-mapping

PlaylistManager: Content validation, format normalization, navigation

MediaPlayer: Video.js integration with playlist extensions and VR support

System Requirements

Software Dependencies

Required:

  • Python 3.9+ with pip
  • Streamlit 1.45+ for component API compatibility
  • Modern browser with WebSocket and WebXR support
  • Intiface Central for device connectivity

Development:

  • Node.js 18+ for frontend development
  • npm or yarn for dependency management

Hardware Compatibility

Haptic Devices:

  • 100+ devices via Buttplug.io ecosystem
  • USB and Bluetooth connectivity
  • Multi-actuator devices supported
  • Virtual device simulation available

VR Headsets:

  • Meta Quest 2/3/Pro (tested, optimized)
  • Pico 4/4E, ByteDance devices
  • Any WebXR-compatible headset
  • Desktop VR via browser

Development

Frontend Development

The React component can be developed independently:

cd streamlit_funplayer/frontend
npm install
npm start  # Development server on localhost:3001

Production Build

cd streamlit_funplayer/frontend
npm run build  # Creates optimized build/

# Switch to production mode
# Edit streamlit_funplayer/__init__.py: _RELEASE = True

Testing

# Component testing
streamlit run funplayer.py

# End-to-end testing
python -m pytest e2e/

Performance Optimizations

  • Interpolation caching with smart invalidation
  • Throttled device commands to prevent flooding
  • Memory management for long VR sessions
  • Bundle optimization via Vite with tree-shaking
  • Adaptive quality based on system capabilities

Use Cases

Entertainment & Content Creation

  • Adult content platforms with synchronized haptic feedback
  • VR experiences with enhanced tactile immersion
  • Music and rhythm games with haptic enhancement
  • Interactive storytelling with physical feedback

Research & Development

  • Haptic perception and HCI research
  • Multi-modal interface prototyping
  • Therapeutic applications with controlled feedback
  • Educational tools with enhanced sensory learning

Accessibility

  • Haptic substitution for audio content (hearing impaired)
  • Customizable intensity for different user needs
  • Multi-modal feedback for enhanced accessibility

Contributing

We welcome contributions from the community! Please follow existing architectural patterns and test thoroughly with both virtual and real devices.

Focus Areas:

  • Device compatibility and testing
  • Performance optimizations for high-frequency updates
  • Additional funscript format support
  • Enhanced visualization and debugging tools

License

Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International

For commercial licensing, contact: bferrand.math@gmail.com

Acknowledgments

Built on the excellent work of:

  • Buttplug.io - Universal haptic device protocol
  • Intiface - Desktop bridge application
  • Video.js - Robust media player framework
  • Streamlit - Python web app framework
  • Funscript community - Haptic scripting standards and content