Skip to main content

terpsi

Dance corpora from single-dancer videos: body landmarks (no video kept), audio, subtitles, on-screen text, and movement-versus-music analysis. Named for Terpsichore, the muse of dance.

pip install "terpsi[all]"   # mediapipe + opencv, librosa, an OCR backend, yb (yt-dlp); ffmpeg on PATH
terpsi ingest https://youtu.be/q_TUyxUhoEw
terpsi clips

A clip goes in as a URL (YouTube, Wikimedia Commons, anything yt-dlp reads) or a local file, and comes out as a folder under ~/.local/share/terpsi/clips/<clip_id>/ holding what a dance model needs and nothing a video needs: 553 landmarks per frame (33 body + 2×21 hands + 478 face, with metric 3D world coordinates for body and hands, and 52 face blendshapes), the audio stream as the source carried it, the description and metadata, the subtitles, the text that was on screen with its timestamps, a beat grid, and a movement-versus-music report. The video is deleted once extracted.

Python

from terpsi import ingest, Corpus

clip_id = ingest("https://youtu.be/q_TUyxUhoEw")      # download, extract, delete the video
clip = Corpus()[clip_id]
lm = clip.landmarks            # LandmarkSeries: lm.pose (F,33,4), lm.pose_world (F,33,3), lm.hand_left, lm.face, ...
clip.beats["tempo"]            # 129.2
clip.screen_text[:2]           # [{'t_start': 3.0, 't_end': 6.0, 'text': 'Mise en place', ...}, ...]
clip.report["beat_alignment"]  # AIST++ Beat Alignment Score of the body's landings against the music beats

Each stage is a function with one seam, a keyword argument whose default works out of the box:

stage function seam default a replacement that exists
fetch terpsi.acquire.fetch downloader= yb over yt-dlp, with info.json, description, subtitles a local file (passes through)
landmarks terpsi.pose.extract_landmarks extractor= MediaPipe HolisticLandmarker kodokan.pose.estimate_poses (RTMPose, 2D)
on-screen text terpsi.screen_text.read_screen_text ocr= ocracy (ocrmac on macOS, Tesseract elsewhere) any ocracy backend id
beats terpsi.audio.track_beats tracker= librosa's beat tracker + onset envelope a madmom or su tracker with the same signature
storage terpsi.store.Corpus root= ~/.local/share/terpsi/clips any folder, a mounted or synced bucket included (a byte-store backend is the next seam, terpsi#1)

import terpsi needs only numpy, scipy and cw; the heavy dependencies are extras (pose, audio, ocr, acquire) imported on first use.

Choosing clips

terpsi search "house dance tutorial footwork" --n 15          # YouTube, Creative-Commons-filtered by default
terpsi screen https://youtu.be/XXXXXXXXXXX                      # single dancer? whole body? (a pose count on sampled frames)
terpsi ingest-many sources.txt                                  # one URL per line

screen reports the fraction of sampled frames with exactly one body, the fraction where that body is whole (nose and an ankle visible), and the licence yt-dlp found. The licence of record per clip is yt-dlp's license field, stored in the manifest.

The analysis

terpsi.analysis implements the literature's movement-versus-music measures over a LandmarkSeries and a beat grid: motion energy (summed joint speed), kinematic beats (its local minima, AIST++), the Beat Alignment Score in both directions, the phase concentration of the body's landings within the beat cycle (a resultant length), the motion tempo by autocorrelation and its ratio to the music tempo, and the audio-visual lag by onset cross-correlation. terpsi analyze <clip_id> recomputes a clip's report. When YouTube rate-limits the captions endpoint but still serves the video (a 429 on the subtitles alone, common in batches), the clip is ingested without subtitles and its manifest records subtitles_error; terpsi subtitles <clip_id> fetches them into the clip's folder later. The motion-tempo estimate is NaN when the motion has no periodicity (every autocorrelation peak negative).

Data layout

~/.local/share/terpsi/clips/<clip_id>/
  manifest.json       id, title, source, licence, duration, fps, coverage, mirrored hint, files
  info.json           yt-dlp's metadata
  description.txt
  subtitles/*.vtt
  audio.m4a           the source audio stream (no re-encode)
  landmarks.npz/.json the LandmarkSeries (NaN where nothing was seen) and its meta
  screen_text.json    [{t_start, t_end, text, lines}]
  beats.json          tempo, beats, onset envelope
  report.json         the movement-vs-music report

$TERPSI_DATA_DIR moves the root. Models (.task files) are fetched once into <root>/models/.

thoremin (the live instrument whose body nodes and pulse follower this corpus is for), paces (step documents from tutorial video), kodokan (pose analysis of judo video), yb, ocracy. Research notes: docs/research/.

Metadata

Release files for terpsi 0.0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for terpsi 0.0.5
File Size Uploaded Provenance Actions
terpsi-0.0.5.tar.gz 32.9 kB Without provenance Details for terpsi-0.0.5.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for terpsi 0.0.5
File Interpreter ABI Platform Actions
terpsi-0.0.5-py3-none-any.whl Python 3 none any Details for terpsi-0.0.5-py3-none-any.whl

Total release size: 70.5 kB

Release files / terpsi-0.0.5.tar.gz

Download URL terpsi-0.0.5.tar.gz
Size 32.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a82d54efb43cf6b4195a3e8b2c2335e4056a8ff8bf020ced64fc4dcd241cc01e
BLAKE2b-256 checksum
How to use checksums
a40a446679cd0c2b7f93c0bb24580dcc01a332a0702d390ea9eb1640649e325d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / terpsi-0.0.5-py3-none-any.whl

Download URL terpsi-0.0.5-py3-none-any.whl
Size 37.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ed0fd7e3f45ec9228b28c72cff220582961f1a5781380c520bc99da81451d972
BLAKE2b-256 checksum
How to use checksums
7205769fde96bdc7cb63775d90704d9c6eaeee239bc16e72838ac50ea4f25d93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for terpsi 0.0.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page