--- title: NextJump Broadcast emoji: 🏅 colorFrom: blue colorTo: gray sdk: gradio sdk_version: 5.38.2 app_file: app.py pinned: false --- # NextJump Broadcast Upload a jump-rope video and get back a broadcast-ready overlay video, vertical 9:16 or horizontal 16:9: - AI jump count from the NextJump ONNX model (`nextjump_all_128.onnx`, run at 60 fps). - Auto-framing on the jumper using MoveNet keypoints. - Speed gauge, speed trace, splits, rhythm strip and rope-phase ring. - Optional official beep detection. The Space counts only between the start and end beeps and highlights both on the graphics. The rendering is done by `claude_anim_v2.py`. `app.py` is only the Gradio front end. ## Deploying The Space folder has to be self-contained. From the `nextjump-eval` repo, run: ``` python hf_spaces/sync_assets.py ``` This copies `claude_anim_v2.py`, the MoveNet weights and package, `beep.WAV`, the logo and the font into `hf_spaces/`. Then push the folder to the Space. The `.pth` file goes through Git LFS; `huggingface_hub`'s `upload_folder` handles that automatically. ### Private counting model The ONNX checkpoint is **not** part of the Space. `sync_assets.py` never copies it, and `.gitignore` excludes `checkpoint/` and `*.onnx`. Instead, `app.py` downloads it at startup from the private model repo with `hf_hub_download`, the same way `NextJump-Tournament/app.py` does. The download is cached, so restarts are fast. In the Space settings, add a **secret** named `DATASET_SECRET` holding a read token for `lumos-motion/nextjump`. `HF_TOKEN` also works. | Variable | Default | Purpose | |---|---|---| | `NEXTJUMP_MODEL_REPO` | `lumos-motion/nextjump` | model repo to download from | | `NEXTJUMP_MODEL_FILE` | `nextjump_all_128.onnx` | checkpoint file in that repo | | `NEXTJUMP_ONNX` | – | local path to use instead of downloading | To switch the Space to another checkpoint in the repo, set `NEXTJUMP_MODEL_FILE`. No push is needed. For local testing you can skip the sync. `python hf_spaces/app.py` falls back to the repo root, and it uses your `huggingface-cli login` if no token variable is set. ## Speed **Turbo mode** is on by default in the UI; it's `--turbo` on the command line. It analyses and renders at 30 fps, uses lighter person detection and probing, frames on detector boxes instead of running the pose model, and uses a fast encoder. The social format always uses turbo. How the pipeline overlaps work: - The beep search, model loading and decoding run at the same time. - Frames are decoded once, in order, with preprocessing on a thread pool. The counting model, person detector and pose model run on GPU threads while decoding continues. - The pose crops are decoded during the jumper probe. - Rendering is split across parallel worker processes. The models stay loaded between requests, so after the first request each one skips about 3 s of start-up. On an RTX 3080 laptop (8 cores), a 55 s, 120 fps clip in the social format takes about 36 s end to end, or about 31 s per request once warm. About 18 s of that is rendering. The counting model sees exactly the same frames as before the speed work, so counts don't change. ## Hardware - **CPU (default):** expect a 30 s clip to take several minutes. Rendering uses half the available CPU threads, up to 16 processes. - **GPU:** MoveNet and the person detector use the GPU automatically through torch. For the counting model to use it too, replace `onnxruntime` with `onnxruntime-gpu` in `requirements.txt`, and drop the CPU torch index. - **Rendering is CPU-bound** (overlay drawing plus x264), so pick an instance with plenty of vCPUs. If the ffmpeg build and the driver support NVENC, encoding moves to the GPU automatically (`--encoder auto`), which frees about a third of the render CPU. `--x264_preset superfast` cuts x264 time by about a third with the same visual quality (SSIM), but files come out about 45% larger. - **Uploads:** decode cost grows with resolution. 4K phone videos are several times slower to analyse than 1080p, so have the app upload at 1080p or lower. `NEXTJUMP_MAX_SECONDS` (default 200) caps the upload length.