MotionPNGTuber
April 13, 2026 ยท View on GitHub
MotionPNGTuber
Developer Preview --- 2026/04/10 Experimental Build This is a development snapshot. Features and APIs may change without notice.
Beyond PNGTuber, before Live2D --- Video-based real-time lip sync system
By using looping video, you can achieve rich expressions like hair swaying and clothing fluttering that traditional PNGTubers can't deliver. No specialized knowledge like Live2D is required --- just an MP4 video and mouth sprites to get started.
๐ How to use (YouTube)
๐ข Updates
| Date | Details |
|---|---|
| 2026/04/13 | Fixed a critical bug where selecting a video in Create mouth PNG sprites could immediately fail with Analysis error because the auto detector script path was resolved incorrectly. Added a regression test for script-path lookup |
| 2026/04/10 | Developer snapshot release. HUD display now defaults to OFF. Internal refactoring and bug fixes |
| 2026/04/05 | Ubuntu 22.04 experimental support (Linux microphone input now available). Added mouth PNG color correction (brightness/saturation/color temperature sliders + auto-correction button). Improved GUI stability |
| 2026/04/04 | Improved GUI usability. Fixed file opening and Japanese path issues on Mac. Added mouth placement margin factor to advanced settings. Added lightweight preview to check appearance before full export |
| 2026/04/03 | Improved mouth PNG extraction GUI usability |
| 2026/01/09 | Migrated package management to uv |
โจ Features
| Feature | Description |
|---|---|
| ๐ค Real-time lip sync | Character's mouth moves in sync with microphone input |
| ๐ญ Auto emotion detection | Estimates emotion from voice and auto-switches expressions |
| ๐จ Hair & physics motion | Looping video enables natural hair and clothing movement |
| ๐จ Mouth PNG color blending | Adjust brightness, saturation, color temperature via sliders + auto-correction |
| ๐ macOS support | Runs on Apple Silicon (M1/M2/M3/M4) (experimental) |
| ๐ง Ubuntu support | Experimental support for Ubuntu 22.04 x86_64 |
๐ Table of Contents
๐ Quick Start
Requirements
- Python 3.10
- uv (package manager)
- Windows:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" - macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
- Windows:
3 Steps to Try
# 1. Install
uv sync
# 2. Launch GUI
uv run python mouth_track_gui.py
# 3. Try with samples
# Video: assets/asmr_tomari/asmr_loop.mp4
# Mouth: assets/asmr_tomari/mouth
# โ (1) Analyze โ Calibrate โ (2) Generate mouthless video โ (3) Live run
Note: some older articles still refer to
assets01/assets03. The current sample set onmainisassets/asmr_tomari/.
๐ง Installation
Windows
Click to expand
1. Prerequisites
- Python 3.10 (check "Add Python to PATH" during installation)
- uv:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
2. Install
# Run in the project directory
uv sync
3. Verify
uv run python -c "import cv2; import torch; print('OK')"
macOS (Experimental)
Click to expand (Apple Silicon: M1/M2/M3/M4)
1. Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
2. Prepare pyproject.toml
macOS uses a dedicated dependency file (the default pyproject.toml contains dependencies that are not compatible with macOS).
cp pyproject.toml pyproject.win.toml
cp pyproject.macos.toml pyproject.toml
3. Base packages
uv venv .venv && uv sync
uv pip install pip setuptools wheel torch==2.0.1 torchvision==0.15.2
4. Build xtcocotools from source
mkdir -p deps && cd deps
git clone https://github.com/jin-s13/xtcocoapi.git
cd xtcocoapi && ../../.venv/bin/python -m pip install -e . && cd ../..
5. Build mmcv-full from source (~5 minutes)
cd deps
curl -L https://github.com/open-mmlab/mmcv/archive/refs/tags/v1.7.0.tar.gz -o mmcv-1.7.0.tar.gz
tar xzf mmcv-1.7.0.tar.gz && cd mmcv-1.7.0
MMCV_WITH_OPS=1 FORCE_CUDA=0 ../../.venv/bin/python setup.py develop
MMCV_WITH_OPS=1 FORCE_CUDA=0 ../../.venv/bin/python setup.py build_ext --inplace
cd ../..
6. Remaining packages
uv pip install --no-build-isolation anime-face-detector
uv pip install mmdet==2.28.0 mmpose==0.29.0
7. Launch
.venv/bin/python mouth_track_gui.py
Notes
- Do not delete the
deps/directory - Use
+/-keys for calibration zoom (scroll wheel may not work)
Ubuntu 22.04 (Experimental)
Click to expand (x86_64 / NVIDIA)
1. Prerequisites
- Ubuntu 22.04 LTS
- Python 3.10
- NVIDIA GPU / CUDA 11.7 compatible environment recommended
2. Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
3. System packages
sudo apt-get update
sudo apt-get install -y libportaudio2 pulseaudio-utils
4. Install
uv sync
5. Verify
uv run python -c "import cv2; import torch; print('OK')"
6. Launch
uv run python mouth_track_gui.py
Notes
- Linux audio input enumeration can differ from Windows/macOS.
- If your USB mic does not appear as a normal
sd:device, try apa:... (via pulse)item in the audio list. - If
pactlis unavailable, Linux audio fallback support is limited.
๐ฎ Usage
Main GUI
uv run python mouth_track_gui.py
๐ On macOS, set up dependencies via the macOS installation steps before launching.
Workflow
- Create mouth PNG sprites --- only if the mouth folder doesn't exist yet
- Select video โ choose a loop video
- Select mouth folder โ choose the folder containing mouth sprites
- (1) Analyze โ Calibrate โ adjust mouth position and press Space to confirm (controls)
- Visual check (lightweight) โ preview margin factor / mouth-erase range without full export
- (2) Generate mouthless video โ generates video with mouth erased
- (3) Live run โ speak into the mic and the mouth moves!
- If the mouth color looks off โ press auto color-blending or adjust sliders manually (details)
Default Settings (changed 2026/04/10)
| Setting | Description | Default |
|---|---|---|
| Shadow blending (mouth erase) | Smoothly blends the boundary where the mouth was erased, making seams less noticeable | ON |
| HUD display | Shows FPS, mouth open/close state, and other info on screen during live run | OFF |
Both can be toggled via checkboxes in the GUI. If a value is already saved in the session, the saved value takes precedence.
๐๏ธ Mouth PNG Creation GUI
uv run python mouth_sprite_extractor_gui.py
If you don't have a mouth folder yet, it's recommended to create one here first. You can also launch it from the "Create mouth PNG sprites (recommended)" button in the main GUI. During analysis after selecting a video, the Processing Status area at the top shows the current step with a progress bar.
๐ Visual Check (Lightweight)
A preview for quickly checking the margin factor and mouth-erase range before exporting the full mouthless video.
- Uses existing
mouth_track.npz/mouth_track_calibrated.npzas-is, so you can skip heavy processing - If
open.pngis found, you can also see how the mouth PNG overlays - Press
Enterto apply the selected settings to the GUI - โ ๏ธ If you change the margin factor, you need to re-run (1) Analyze โ Calibrate
Key Controls
| Key | Function |
|---|---|
Top buttons / 1 2 3 | Select margin factor candidate |
r / f | Increase / decrease mouth-erase range |
a / d | Previous / next frame |
[ / ] | Jump 10 frames back / forward |
Space | Play / pause |
Apply to GUI button / Enter | Apply margin factor / mouth-erase range to GUI |
Esc / q | Close without applying |
โ๏ธ Advanced Settings
Advanced settings can usually be left closed.
The main setting is the mouth placement margin factor, which affects mouth placement size during (1) Analyze โ Calibrate.
| Symptom | Fix |
|---|---|
| Mouth PNG looks too small / edges are clipped | Increase slightly (e.g., 2.3 ~ 2.6) |
| Mouth is too large / picks up jaw or cheeks | Decrease slightly (e.g., 1.8 ~ 2.0) |
The default value of 2.1 usually works fine.
Recommended workflow:
- Run (1) Analyze โ Calibrate with
2.1 - Visual check (lightweight) --- compare values around
1.9 / 2.1 / 2.3 - Apply the best value โ re-run (1) Analyze โ Calibrate
- Proceed to (2) Generate mouthless video
โ ๏ธ The margin factor is used during analysis, so changing it requires re-running (1) Analyze โ Calibrate.
๐จ Mouth PNG Color Correction
Adjusts color blending between mouth PNGs and the base video. Moving the sliders during live run reflects changes in real time (~hundreds of ms) without restarting the runtime.
Adjustable Parameters
| Parameter | Description |
|---|---|
| Mouth PNG brightness | Overall mouth brightness |
| Mouth PNG saturation | Color vividness |
| Mouth PNG warm/cool | Color temperature |
| Correction intensity | Overall correction strength |
| Edge priority | How strongly correction applies to mouth edges |
| Edge correction width | Range of edge correction effect |
| Preview: color diff highlight | Makes subtle color mismatches easier to spot (preview only; does not modify assets) |
How edge priority works: Correction is not applied uniformly across the entire mouth PNG --- it applies more strongly to the outer edges. This helps reduce issues like "only the mouth edges look out of place" or "the skin boundary doesn't blend."
Auto Color Blending
Press the "Auto color blending" button during live run to automatically compare the background video's mouth area with the mouth PNG's edge colors and suggest correction values. You can still fine-tune with sliders after auto-correction.
- Transparent areas of the mouth PNG are ignored; only the colored edge areas are analyzed
- The auto-correction button is only available during live run
- Changes are auto-saved
Recommended Workflow
- Start (3) Live run
- Optionally increase color diff highlight to check for color mismatches
- Press Auto color blending
- Fine-tune with sliders
๐ Detailed Reference
๐ฆ What You Need
Video (.mp4)
- A short looping video (a few seconds)
- Face should not be obscured
Mouth Sprites (.png x 5)
| File | Description |
|---|---|
open.png | Mouth open |
closed.png | Mouth closed |
half.png | Half open |
e.png | Custom shape |
u.png | Custom shape |
- Format: PNG (with transparency)
- Recommended size: ~128px width
- Having just
open.pngcan sometimes compensate for missing sprites, but having all 5 is more stable
๐ฏ Calibration Controls
Mouse
| Action | Function |
|---|---|
| Left drag | Move |
| Scroll wheel | Zoom in/out |
| Right drag | Rotate |
Keyboard
| Key | Function |
|---|---|
| Arrow keys | Fine movement |
W/A/S/D | Fine movement (alternative when arrow keys don't work on Mac) |
+/- | Zoom in/out |
z/x | Rotate |
Space / Enter | Confirm |
Esc | Cancel |
๐ญ Emotion Detection
| Emotion | Detection Criteria |
|---|---|
| neutral | Default state |
| happy | High pitch, bright tone |
| angry | Strong voice, high energy |
| sad | Low voice, quiet tone |
| excited | Very high energy |
Presets
| Preset | Characteristics |
|---|---|
| Stable | Slow emotion changes (for streaming) |
| Standard | Balanced |
| Responsive | Fast reactions (for gaming) |
๐ Browser Output
After completing (2) Generate mouthless video, the following files are exported to the same folder:
mouth_track.json*_mouthless_h264.mp4(ifffmpegis found)
Use these when passing mouth track data to a browser implementation.
mouth_track.jsonis the main track export*_mouthless_h264.mp4is recommended for browser / player use whenffmpegis available- If
ffmpegis missing, the GUI still exportsmouth_track.jsonand logs that H.264 export was skipped
For MotionPNGTuber_Player and other browser implementations that use AudioWorklet, opening files via file:// may block mic / worklet loading. In that case, serve the folder locally:
python -m http.server 8000
# then open http://localhost:8000
โจ๏ธ Command Line Usage
# Face tracking
uv run python auto_mouth_track_v2.py --video loop.mp4 --out mouth_track.npz
# Calibration
uv run python calibrate_mouth_track.py --video loop.mp4 --track mouth_track.npz --sprite open.png
# Generate mouthless video
uv run python auto_erase_mouth.py --video loop.mp4 --track mouth_track_calibrated.npz --out loop_mouthless.mp4
# Real-time execution
uv run python loop_lipsync_runtime_patched_emotion_auto.py \
--loop-video loop_mouthless.mp4 \
--mouth-dir mouth_dir/Char \
--track mouth_track_calibrated.npz
๐ Directory Structure
MotionPNGTuber/
โโโ mouth_track_gui.py # Main GUI (entry point)
โโโ mouth_track_gui/ # Main GUI package
โ โโโ __init__.py
โ โโโ __main__.py
โ โโโ _paths.py # Path definitions
โ โโโ app.py # Application core
โ โโโ ui.py # UI construction
โ โโโ state.py # Session management
โ โโโ services.py # File/device helpers
โ โโโ actions.py # Command assembly
โ โโโ runner.py # Subprocess execution
โ โโโ preview.py # Lightweight preview
โ โโโ live_ipc.py # Live runtime IPC
โโโ mouth_sprite_extractor_gui.py # Mouth PNG creation GUI
โโโ mouth_sprite_extractor.py # CLI wrapper for mouth sprite extraction
โโโ auto_mouth_track_v2.py # Mouth position tracking
โโโ calibrate_mouth_track.py # Calibration
โโโ auto_erase_mouth.py # Mouthless video generation
โโโ erase_mouth_offline.py # Mouth erase core processing
โโโ loop_lipsync_runtime_patched_emotion_auto.py # Live runtime
โโโ face_track_anime_detector.py # Anime face detection
โโโ motionpngtuber/ # Shared library package
โ โโโ __init__.py
โ โโโ mouth_sprite_extractor.py # Core mouth sprite extraction logic
โ โโโ python_exec.py # Python executable resolver
โ โโโ audio_linux.py # Linux audio helper (PulseAudio/PipeWire)
โ โโโ mouth_color_adjust.py # Mouth PNG color correction logic
โ โโโ lipsync_core.py # Shared module
โ โโโ image_io.py # Image I/O (Unicode path support)
โ โโโ platform_open.py # Platform-specific open handling
โ โโโ auto_crop_estimator.py # Auto crop estimation
โ โโโ mouth_auto_classifier.py # Mouth shape auto classification
โ โโโ mouth_feature_analyzer.py # Mouth feature analysis
โ โโโ realtime_emotion_audio.py # Real-time emotion audio analysis
โ โโโ workflow_validation.py # Workflow validation
โโโ convert_npz_to_json.py # npz โ JSON conversion
โโโ tests/ # Test suite
โโโ assets/ # Sample assets
โโโ mouth_dir/ # Mouth sprites (sample)
โโโ pyproject.toml # Dependencies (Windows / Linux)
โโโ pyproject.macos.toml # Dependencies (macOS)
โ Troubleshooting
Mouth position is misaligned
- First try Recalibrate only
- If still too small / too large, use Visual check (lightweight) to compare margin factor values
- Then adjust the margin factor in advanced settings slightly if needed
Black smudge in mouth erase
- Try turning Shadow blending OFF
uv sync fails
uv cache clean
uv sync
CUDA not recognized
uv run python -c "import torch; print(torch.cuda.is_available())"
Analysis stops on RTX 50-series / newer GPUs
- Root cause: the current Torch / CUDA build may not fully match your GPU architecture
- Prevention: the GUI now starts analysis with
--device auto, which tries CUDA first and then CPU fallback - If analysis still fails, rerun from CLI with
--device cpuand check the log for CUDA compatibility messages
Analysis looks frozen
- Initial analysis can take time, especially on long videos
- If GPU fallback switches to CPU, processing becomes much slower but is still expected
- Check the progress area and log before assuming the app has hung
Analysis error appears immediately after selecting a video in the mouth PNG GUI
- Root cause (fixed on 2026-04-13): the GUI could fail before tracking started if the bundled detector script path was resolved incorrectly
- Prevention: the detector launcher now searches both the package directory and the repository root, and this lookup is covered by a regression test
- If you still see the error after updating, check the log pane for the exact exception and verify that
face_track_anime_detector.pyexists in the project
๐ Bonus Tools
Mouth Sprite Extraction CLI
uv run python mouth_sprite_extractor.py --video loop.mp4 --out mouth/
Extract mouth sprites (5 PNGs) directly from the command line without the GUI.
๐งช Tests
# All tests
uv run python -m unittest discover -s tests -v
# E2E smoke only
uv run python -m unittest discover -s tests -p "test_e2e_smoke.py" -v
Note: keep -s tests. Plain python -m unittest discover may collect 0 tests
in this repository layout depending on the launch directory.
As of 2026-04-13: verified with 261 tests / 3 skip passing.
๐ License
MIT License