kinemotion

Kinemotion Library API Examples

This directory contains examples demonstrating how to use kinemotion as a Python library for programmatic video analysis.

Overview

Kinemotion can be used as a library in your Python code, not just as a CLI tool. This is ideal for:

Quick Start

Single Video Processing

from kinemotion import process_dropjump_video

# Process a single video
metrics = process_dropjump_video(
    video_path="athlete_jump.mp4",
    drop_height=0.40,  # 40cm drop box (REQUIRED)
    verbose=True
)

print(f"Jump height: {metrics.jump_height_m:.3f} m")
print(f"Ground contact time: {metrics.ground_contact_time_ms:.1f} ms")
print(f"Flight time: {metrics.flight_time_ms:.1f} ms")

Bulk Video Processing

from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk

# Configure multiple videos
configs = [
    DropJumpVideoConfig("video1.mp4", drop_height=0.40),
    DropJumpVideoConfig("video2.mp4", drop_height=0.30),
    DropJumpVideoConfig("video3.mp4", drop_height=0.50),
]

# Process in parallel with 4 workers
results = process_dropjump_videos_bulk(configs, max_workers=4)

# Check results
for result in results:
    if result.success:
        print(f"{result.video_path}: {result.metrics.jump_height_m:.3f} m")
    else:
        print(f"{result.video_path}: ERROR - {result.error}")

Example Scripts

simple_example.py

Basic examples showing:

Run it:

python examples/simple_example.py

bulk_processing.py

Advanced examples showing:

Run it:

python examples/bulk_processing.py

API Reference

Core Functions

process_video()

Process a single drop jump video.

Parameters:

Returns:

Raises:

process_dropjump_videos_bulk()

Process multiple videos in parallel.

Parameters:

Returns:

Data Classes

VideoConfig

Configuration for a single video.

DropJumpVideoConfig(
    video_path="video.mp4",
    drop_height=0.40,
    quality="balanced",
    output_video=None,
    json_output=None,
    # Expert parameters...
)

VideoResult

Result of processing a single video.

Attributes:

DropJumpMetrics

Analysis results for a drop jump.

Key attributes:

Common Use Cases

1. Batch Process a Directory

from pathlib import Path
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk

# Find all MP4 files
video_dir = Path("athlete_videos")
video_files = list(video_dir.glob("*.mp4"))

# Create configs with consistent settings
configs = [
    DropJumpVideoConfig(
        video_path=str(video_file),
        drop_height=0.40,
        quality="balanced",
        json_output=f"results/{video_file.stem}.json"
    )
    for video_file in video_files
]

# Process with progress tracking
def show_progress(result):
    status = "✓" if result.success else "✗"
    print(f"{status} {result.video_path}")

results = process_dropjump_videos_bulk(
    configs,
    max_workers=4,
    progress_callback=show_progress
)

# Calculate statistics
successful = [r for r in results if r.success]
avg_jump = sum(r.metrics.jump_height_m for r in successful) / len(successful)
print(f"\nAverage jump height: {avg_jump:.3f} m")

2. Export Results to CSV

import csv
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk

# Process videos
configs = [...]  # Your video configs
results = process_dropjump_videos_bulk(configs, max_workers=4)

# Export successful results
with open("results.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow([
        "Video", "GCT (ms)", "Flight Time (ms)",
        "Jump Height (m)", "RSI"
    ])

    for result in results:
        if result.success:
            writer.writerow([
                result.video_path,
                f"{result.metrics.ground_contact_time_ms:.1f}",
                f"{result.metrics.flight_time_ms:.1f}",
                f"{result.metrics.jump_height_m:.3f}",
                f"{result.metrics.reactive_strength_index:.2f}"
                if result.metrics.reactive_strength_index else "N/A"
            ])

3. Different Quality Settings

from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk

configs = [
    # Fast: Quick screening
    DropJumpVideoConfig("video1.mp4", drop_height=0.40, quality="fast"),

    # Balanced: Default, good accuracy/speed
    DropJumpVideoConfig("video2.mp4", drop_height=0.40, quality="balanced"),

    # Accurate: Research-grade, slower
    DropJumpVideoConfig("video3.mp4", drop_height=0.40, quality="accurate"),
]

results = process_dropjump_videos_bulk(configs, max_workers=3)

4. Custom Parameters for Challenging Videos

from kinemotion import process_dropjump_video

# Low quality video - more aggressive smoothing
metrics = process_dropjump_video(
    video_path="low_quality.mp4",
    drop_height=0.40,
    smoothing_window=7,        # More smoothing
    velocity_threshold=0.025,  # Less sensitive
    quality="accurate"
)

# High speed video - let auto-tuning handle FPS
metrics = process_dropjump_video(
    video_path="high_speed_120fps.mp4",
    drop_height=0.40,
    quality="accurate"  # Auto-adjusts for 120fps
)

5. Generate Debug Videos

from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk

# Process and save debug videos for review
configs = [
    DropJumpVideoConfig(
        video_path="athlete1_trial1.mp4",
        drop_height=0.40,
        output_video="debug/athlete1_trial1_debug.mp4",
        json_output="results/athlete1_trial1.json"
    ),
    # ... more videos
]

results = process_dropjump_videos_bulk(configs, max_workers=2)

Performance Tips

1. Choose Appropriate Worker Count

# CPU-bound processing - use 1 worker per CPU core
import multiprocessing
max_workers = multiprocessing.cpu_count()

# Or limit to avoid overloading
max_workers = min(multiprocessing.cpu_count(), 8)

2. Use Quality Presets Wisely

3. Skip Debug Videos for Batch Processing

Debug videos are slow to generate. Skip them for large batches:

# Don't set output_video parameter
DropJumpVideoConfig("video.mp4", drop_height=0.40)  # No debug video

4. Process Videos Sequentially for Single Machine

# Use max_workers=1 if you have limited memory
results = process_dropjump_videos_bulk(configs, max_workers=1)

Error Handling

All errors are isolated per video - one failure doesn’t crash the batch:

results = process_dropjump_videos_bulk(configs, max_workers=4)

for result in results:
    if result.success:
        # Process successful result
        print(f"✓ {result.video_path}: {result.metrics.jump_height_m:.3f} m")
    else:
        # Handle error
        print(f"✗ {result.video_path}: {result.error}")

        # Log error to file
        with open("errors.log", "a") as f:
            f.write(f"{result.video_path}: {result.error}\n")

Integration Examples

With Pandas

import pandas as pd
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk

# Read video list from CSV
df = pd.read_csv("videos.csv")  # Columns: path, drop_height

# Create configs
configs = [
    DropJumpVideoConfig(row.path, row.drop_height)
    for _, row in df.iterrows()
]

# Process
results = process_dropjump_videos_bulk(configs, max_workers=4)

# Create results DataFrame
results_data = []
for result in results:
    if result.success:
        results_data.append({
            "video": result.video_path,
            "gct_ms": result.metrics.ground_contact_time_ms,
            "flight_time_ms": result.metrics.flight_time_ms,
            "jump_height_m": result.metrics.jump_height_m,
            "rsi": result.metrics.reactive_strength_index,
        })

results_df = pd.DataFrame(results_data)
results_df.to_csv("analysis_results.csv", index=False)

With Click for Custom CLI

import click
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk

@click.command()
@click.argument("video_dir", type=click.Path(exists=True))
@click.option("--drop-height", type=float, required=True)
@click.option("--workers", type=int, default=4)
def analyze_directory(video_dir, drop_height, workers):
    """Analyze all videos in a directory."""
    from pathlib import Path

    videos = list(Path(video_dir).glob("*.mp4"))
    configs = [
        DropJumpVideoConfig(str(v), drop_height=drop_height)
        for v in videos
    ]

    click.echo(f"Processing {len(videos)} videos with {workers} workers...")

    results = process_dropjump_videos_bulk(configs, max_workers=workers)

    successful = [r for r in results if r.success]
    click.echo(f"Success: {len(successful)}/{len(results)}")

if __name__ == "__main__":
    analyze_directory()

Troubleshooting

Import Errors

If you see import errors, make sure kinemotion is installed:

# From the repository root
uv sync

Memory Issues with Large Batches

Reduce max_workers or process videos sequentially:

results = process_dropjump_videos_bulk(configs, max_workers=1)

Video Processing Failures

Check the error message in VideoResult.error:

for result in results:
    if not result.success:
        print(f"Failed: {result.video_path}")
        print(f"Reason: {result.error}")

Common issues:

Questions?

For more information, see: