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.4.tar.gz (95.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.4-py3-none-any.whl (32.7 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for gradio_labanmovementanalysis-0.0.4.tar.gz
Algorithm Hash digest
SHA256 34e823a1c71d75d96e2107518fc4e0d7d7d493af2b949b99acc40d967b610639
MD5 5741c36179700854dca80531afa7aab0
BLAKE2b-256 08b8d086701fa1db906c59d5646fe376ecedb23c80041ecbb6fb7e64d0d9f82c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gradio_labanmovementanalysis-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 4c7f56c762736755d47dbf3fd6a22dfde50e3c3645e5feb0f50af03bf1a9afc8
MD5 54540dd416d32d67d8c93d5dc291584d
BLAKE2b-256 ba04e841ea6897a4a93cf99458d3dfa18799d1284d111f7f5114750e75ba1b72

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