Skip to main content

A Gradio 5 component for video movement analysis using Laban Movement Analysis (LMA) with MCP support for AI agents

Project description


title: Laban Movement Analysis emoji: ๐Ÿƒ colorFrom: purple colorTo: green app_file: app.py sdk: gradio sdk_version: 5.33.0 pinned: false tags:

  • laban-movement-analysis
  • pose-estimation
  • movement-analysis
  • video-analysis
  • youtube
  • vimeo
  • mcp
  • agent-ready
  • computer-vision
  • mediapipe
  • yolo
  • gradio short_description: Professional movement analysis with pose estimation and AI license: apache-2.0

gradio_labanmovementanalysis

PyPI - Version

A Gradio 5 component for video movement analysis using Laban Movement Analysis (LMA) with MCP support for AI agents

Installation

pip install gradio_labanmovementanalysis

Usage

# app.py  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
"""
Laban Movement Analysis โ€“ modernised Gradio Space
Author: Csaba (BladeSzaSza)
"""

import gradio as gr
import os
from backend.gradio_labanmovementanalysis import LabanMovementAnalysis
# from gradio_labanmovementanalysis import LabanMovementAnalysis

# Import agent API if available
# Initialize agent API if available
agent_api = None
try:
    from gradio_labanmovementanalysis.agent_api import (
        LabanAgentAPI,
        PoseModel,
        MovementDirection,
        MovementIntensity
    )
    HAS_AGENT_API = True
    
    try:
        agent_api = LabanAgentAPI()
    except Exception as e:
        print(f"Warning: Agent API not available: {e}")
        agent_api = None
except ImportError:
    HAS_AGENT_API = False
# Initialize components
try:
    analyzer = LabanMovementAnalysis(
        enable_visualization=True
    )
    print("โœ… Core features initialized successfully")
except Exception as e:
    print(f"Warning: Some features may not be available: {e}")
    analyzer = LabanMovementAnalysis()


def process_video_enhanced(video_input, model, enable_viz, include_keypoints):
    """Enhanced video processing with all new features."""
    if not video_input:
        return {"error": "No video provided"}, None
    
    try:
        # Handle both file upload and URL input
        video_path = video_input.name if hasattr(video_input, 'name') else video_input
        
        json_result, viz_result = analyzer.process_video(
            video_path,
            model=model,
            enable_visualization=enable_viz,
            include_keypoints=include_keypoints
        )
        return json_result, viz_result
    except Exception as e:
        error_result = {"error": str(e)}
        return error_result, None

def process_video_standard(video, model, enable_viz, include_keypoints):
    """Standard video processing function."""
    if video is None:
        return None, None
    
    try:
        json_output, video_output = analyzer.process_video(
            video,
            model=model,
            enable_visualization=enable_viz,
            include_keypoints=include_keypoints
        )
        return json_output, video_output
    except Exception as e:
        return {"error": str(e)}, None

# โ”€โ”€ 4.  Build UI โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
def create_demo() -> gr.Blocks:
    with gr.Blocks(
        title="Laban Movement Analysis",
        theme='gstaff/sketch',
        fill_width=True,
    ) as demo:

        # โ”€โ”€ Hero banner โ”€โ”€
        gr.Markdown(
            """
            # ๐ŸŽญ Laban Movement Analysis 
            
            Pose estimation โ€ข AI action recognition โ€ข Movement Analysis 
            """
        )
        with gr.Tabs():
            # Tab 1: Standard Analysis
            with gr.Tab("๐ŸŽฌ Standard Analysis"):
                gr.Markdown("""
                ### Upload a video file to analyze movement using traditional LMA metrics with pose estimation.
                """)
                # โ”€โ”€ Workspace โ”€โ”€
                with gr.Row(equal_height=True):
                    # Input column
                    with gr.Column(scale=1, min_width=260):
                        
                        analyze_btn_enh = gr.Button("๐Ÿš€ Analyze Movement", variant="primary", size="lg")
                        video_in = gr.Video(label="Upload Video", sources=["upload"], format="mp4")
                        # URL input option
                        url_input_enh = gr.Textbox(
                            label="Or Enter Video URL",
                            placeholder="YouTube URL, Vimeo URL, or direct video URL",
                            info="Leave file upload empty to use URL"
                        )
                       
                        gr.Markdown("**Model Selection**")
                        
                        model_sel = gr.Dropdown(
                            choices=[
                                # MediaPipe variants
                                "mediapipe-lite", "mediapipe-full", "mediapipe-heavy",
                                # MoveNet variants
                                "movenet-lightning", "movenet-thunder",
                                # YOLO v8 variants
                                "yolo-v8-n", "yolo-v8-s", "yolo-v8-m", "yolo-v8-l", "yolo-v8-x",
                                # YOLO v11 variants
                                "yolo-v11-n", "yolo-v11-s", "yolo-v11-m", "yolo-v11-l", "yolo-v11-x"
                            ],
                            value="mediapipe-full",
                            label="Advanced Pose Models",
                            info="15 model variants available"
                        )
                        
                        with gr.Accordion("Analysis Options", open=False):
                            enable_viz = gr.Radio([("Yes", 1), ("No", 0)], value=1, label="Visualization")
                            include_kp = gr.Radio([("Yes", 1), ("No", 0)], value=0, label="Raw Keypoints")

                        gr.Examples(
                            examples=[
                                ["examples/balette.mp4"],
                                ["https://www.youtube.com/shorts/RX9kH2l3L8U"],
                                ["https://vimeo.com/815392738"],
                                ["https://vimeo.com/548964931"],
                                ["https://videos.pexels.com/video-files/5319339/5319339-uhd_1440_2560_25fps.mp4"],
                            ],
                            inputs=url_input_enh,
                            label="Examples"
                        )


                    # Output column
                    with gr.Column(scale=2, min_width=320):
                        viz_out = gr.Video(label="Annotated Video", scale=1, height=400)
                        with gr.Accordion("Raw JSON", open=True):
                            json_out = gr.JSON(label="Movement Analysis", elem_classes=["json-output"])

                # Wiring
                def process_enhanced_input(file_input, url_input, model, enable_viz, include_keypoints):
                    """Process either file upload or URL input."""
                    video_source = file_input if file_input else url_input
                    return process_video_enhanced(video_source, model, enable_viz, include_keypoints)
                
                analyze_btn_enh.click(
                    fn=process_enhanced_input,
                    inputs=[video_in, url_input_enh, model_sel, enable_viz, include_kp],
                    outputs=[json_out, viz_out],
                    api_name="analyze_enhanced"
                )

        # Footer
        with gr.Row():
            gr.Markdown(
                """
                **Built by Csaba Bolyรณs**  
                [GitHub](https://github.com/bladeszasza) โ€ข [HF](https://huggingface.co/BladeSzaSza)
                """
            )
    return demo
  
if __name__ == "__main__":
    demo = create_demo()
    demo.launch(server_name="0.0.0.0",
                server_port=int(os.getenv("PORT", 7860)),
                mcp_server=True) 

LabanMovementAnalysis

Initialization

name type default description
default_model
str
"mediapipe" Default pose estimation model ("mediapipe", "movenet", "yolo")
enable_visualization
bool
True Whether to generate visualization video by default
include_keypoints
bool
False Whether to include raw keypoints in JSON output
enable_webrtc
bool
False Whether to enable WebRTC real-time analysis
label
typing.Optional[str][str, None]
None Component label
every
typing.Optional[float][float, None]
None None
show_label
typing.Optional[bool][bool, None]
None None
container
bool
True None
scale
typing.Optional[int][int, None]
None None
min_width
int
160 None
interactive
typing.Optional[bool][bool, None]
None None
visible
bool
True None
elem_id
typing.Optional[str][str, None]
None None
elem_classes
typing.Optional[typing.List[str]][
    typing.List[str][str], None
]
None None
render
bool
True None

User function

The impact on the users predict function varies depending on whether the component is used as an input or output for an event (or both).

  • When used as an Input, the component only impacts the input signature of the user function.
  • When used as an output, the component only impacts the return signature of the user function.

The code snippet below is accurate in cases where the component is used as both an input and an output.

  • As output: Is passed, processed data for analysis.
  • As input: Should return, analysis results.
def predict(
    value: typing.Dict[str, typing.Any][str, typing.Any]
) -> typing.Any:
    return value

Project details


Download files

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

Source Distribution

gradio_labanmovementanalysis-0.0.5.tar.gz (197.1 kB view details)

Uploaded Source

Built Distribution

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

gradio_labanmovementanalysis-0.0.5-py3-none-any.whl (34.8 kB view details)

Uploaded Python 3

File details

Details for the file gradio_labanmovementanalysis-0.0.5.tar.gz.

File metadata

File hashes

Hashes for gradio_labanmovementanalysis-0.0.5.tar.gz
Algorithm Hash digest
SHA256 e81b49050a10af3ab4ab87fd34d7054e1ed1a1b82bffdbd7a6b1931b9de4e793
MD5 f97474ee44b6cae4fbc9989a5f51d448
BLAKE2b-256 a191cdc9ad617f2796d6c9d5c9a43c2c61718ea36be3c250394d80ed7ed3523b

See more details on using hashes here.

File details

Details for the file gradio_labanmovementanalysis-0.0.5-py3-none-any.whl.

File metadata

File hashes

Hashes for gradio_labanmovementanalysis-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 a01581c5338c266d8c1e1a51968d285a46d7913367a98975458fe4d91c21d740
MD5 f1d75ebf86a1d4409b27aa9eecec99b4
BLAKE2b-256 8a39dac81ec9209f46ce7737bfc3ec37f7e734cca87ee1de33a8edffbf212460

See more details on using hashes here.

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