loopsmith
Find the longest seamlessly-loopable segment in a video.
Given a clip, loopsmith figures out the longest stretch you can pull out and
play on repeat without a visible jump — the point where some later frame looks
almost exactly like an earlier one, so playback can snap back to the start with
no seam. Handy for turning B-roll, animations, or background footage into clean
loops (looping wallpapers, GIFs, video backdrops, and so on).
How it works
The core of it is a single matrix multiply.
- Sample every Nth frame, shrink each to a 160px thumbnail, convert to grayscale, and z-score normalize it (subtract the mean, divide by the standard deviation).
- Stack the normalized frames into a matrix and multiply it by its own
transpose. For z-scored vectors, each dot product (divided by the pixel
count) is the normalized cross-correlation between two frames — a
similarity score from -1 to 1 where 1 means "visually identical." So one
mat @ mat.Tproduces the score for every pair of frames at once. - For each pair of frames, the gap between them is a candidate loop length. Among all pairs whose similarity clears a threshold, the one with the largest gap wins: those two near-identical frames are the in- and out-points of the longest seam-free loop.
Because the expensive step is one BLAS matmul, it stays quick even though it's effectively comparing every frame against every other frame.
Install
pip install loopsmith
From source, for development (includes the test deps):
pip install -e ".[dev]"
Needs Python 3.9+, OpenCV, and NumPy — the last two are pulled in automatically.
Usage (CLI)
# Analyze a single video
loopsmith clip.mp4
# Batch every .mp4/.mov in a directory
loopsmith ./footage/
# Loosen or tighten the similarity threshold (default 0.85)
loopsmith clip.mp4 --threshold 0.80
# Sample every 5th frame instead of every 3rd (faster, coarser)
loopsmith clip.mp4 --downsample 5
# Detailed report: top 10 loops by similarity and by length
loopsmith clip.mp4 --detail
# Find the best loop closest to a target length, in seconds
loopsmith clip.mp4 --detail --target-length 6
Batch mode prints the best loop per file as a table; --detail (single file)
prints the top candidates plus a yes/no "is this clip loopable" verdict.
Usage (library)
from loopsmith import extract_frames, find_best_loop
rows, frame_indices, fps, total = extract_frames("clip.mp4", downsample=3)
loop = find_best_loop(rows, frame_indices, threshold=0.85)
if loop:
start_frame, end_frame, ncc = loop
seconds = (end_frame - start_frame) / fps
print(f"Loop {start_frame}->{end_frame} ({seconds:.1f}s) at {ncc:.1%} similarity")
Other helpers: find_best_for_target() (the loop closest to a target
duration), find_top_loops() (ranked candidates), and analyze_video() (a
one-call summary dict).
Notes & limitations
- Visual only. It compares frames, not audio. A visually seamless loop can still have an audible seam — check the sound separately if that matters.
- Cut resolution. In/out points are accurate to within
--downsampleframes, since that's the sampling step. Lower it for tighter cuts at the cost of speed. - Scales as O(N²) in sampled frames. It builds an N×N similarity matrix, so
for long videos raise
--downsampleto keep time and memory in check. - It reports, it doesn't cut. Output is frame indices / timestamps and similarity scores; trimming the actual clip (e.g. with ffmpeg) is up to you.
License
MIT — see LICENSE.
Metadata
Release files for loopsmith 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| loopsmith-0.1.0.tar.gz | 8.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| loopsmith-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.3 kB
Release files / loopsmith-0.1.0.tar.gz
| Download URL | loopsmith-0.1.0.tar.gz |
|---|---|
| Size | 8.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
045ac2f6d6d8b2fd6b39fc1de07ec6d67a0131a75bb8d2395b9c83ad08831b61
|
|
BLAKE2b-256 checksum How to use checksums |
e12bc09b4e9150b3e3a72c44747546ee374d73e6a526d29c2da61c77a6628ef8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 23, 2026.
Transparency logRelease files / loopsmith-0.1.0-py3-none-any.whl
| Download URL | loopsmith-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
87c906aec9f72b5bcb3c7f3a0996e6e3a87943931f46fb35a27e066a7809ae54
|
|
BLAKE2b-256 checksum How to use checksums |
9cd1736d3751f1b49ecc0e6fe7c9acbab187b000ca447680e552de7dc4f92c7d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 23, 2026.
Transparency log