pymotion-studio 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pymotion_studio-1.0.1/.github/workflows/ci.yml +84 -0
- pymotion_studio-1.0.1/.github/workflows/publish.yml +44 -0
- pymotion_studio-1.0.1/.github/workflows/release.yml +31 -0
- pymotion_studio-1.0.1/.gitignore +61 -0
- pymotion_studio-1.0.1/CHANGELOG.md +142 -0
- pymotion_studio-1.0.1/Dockerfile +18 -0
- pymotion_studio-1.0.1/LICENSE +95 -0
- pymotion_studio-1.0.1/Makefile +19 -0
- pymotion_studio-1.0.1/PKG-INFO +377 -0
- pymotion_studio-1.0.1/README.md +311 -0
- pymotion_studio-1.0.1/docs/api/animation.md +53 -0
- pymotion_studio-1.0.1/docs/api/audio.md +35 -0
- pymotion_studio-1.0.1/docs/api/clips.md +50 -0
- pymotion_studio-1.0.1/docs/api/composition.md +12 -0
- pymotion_studio-1.0.1/docs/api/effects.md +69 -0
- pymotion_studio-1.0.1/docs/api/templates.md +11 -0
- pymotion_studio-1.0.1/docs/api/transitions.md +106 -0
- pymotion_studio-1.0.1/docs/guides/3d-scenes.md +265 -0
- pymotion_studio-1.0.1/docs/guides/audio-mixing.md +244 -0
- pymotion_studio-1.0.1/docs/guides/batch-generation.md +224 -0
- pymotion_studio-1.0.1/docs/guides/effects-pipeline.md +170 -0
- pymotion_studio-1.0.1/docs/guides/getting-started.md +182 -0
- pymotion_studio-1.0.1/docs/guides/keyframe-animation.md +233 -0
- pymotion_studio-1.0.1/docs/guides/particles.md +158 -0
- pymotion_studio-1.0.1/docs/guides/template-system.md +180 -0
- pymotion_studio-1.0.1/docs/guides/text-animation.md +137 -0
- pymotion_studio-1.0.1/docs/guides/transitions.md +161 -0
- pymotion_studio-1.0.1/docs/index.md +78 -0
- pymotion_studio-1.0.1/examples/01_real_estate_tour.py +249 -0
- pymotion_studio-1.0.1/examples/02_tech_review_intro.py +310 -0
- pymotion_studio-1.0.1/examples/03_fitness_social_ad.py +306 -0
- pymotion_studio-1.0.1/examples/04_restaurant_menu_promo.py +337 -0
- pymotion_studio-1.0.1/examples/05_educational_explainer.py +478 -0
- pymotion_studio-1.0.1/examples/assets/ambient_music.wav +0 -0
- pymotion_studio-1.0.1/examples/assets/background_loop.wav +0 -0
- pymotion_studio-1.0.1/examples/assets/click.wav +0 -0
- pymotion_studio-1.0.1/examples/assets/deep_bass.wav +0 -0
- pymotion_studio-1.0.1/examples/assets/ding.wav +0 -0
- pymotion_studio-1.0.1/examples/assets/edu_abstract.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/edu_books.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/edu_classroom.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/fitness_gym.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/fitness_running.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/fitness_weights.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/food_ambiance.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/food_dessert.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/food_plate.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/food_table.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/house_exterior.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/house_garden.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/house_interior.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/house_kitchen.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/tech_circuit.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/tech_device.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/tech_workspace.jpg +0 -0
- pymotion_studio-1.0.1/examples/assets/whoosh.wav +0 -0
- pymotion_studio-1.0.1/examples/download_assets.py +199 -0
- pymotion_studio-1.0.1/mkdocs.yml +37 -0
- pymotion_studio-1.0.1/pymotion/__init__.py +355 -0
- pymotion_studio-1.0.1/pymotion/animation/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/animation/easing.py +579 -0
- pymotion_studio-1.0.1/pymotion/animation/interpolator.py +185 -0
- pymotion_studio-1.0.1/pymotion/animation/keyframe.py +151 -0
- pymotion_studio-1.0.1/pymotion/animation/spring.py +120 -0
- pymotion_studio-1.0.1/pymotion/audio/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/audio/analysis.py +220 -0
- pymotion_studio-1.0.1/pymotion/audio/effects.py +381 -0
- pymotion_studio-1.0.1/pymotion/audio/mixer.py +248 -0
- pymotion_studio-1.0.1/pymotion/cli/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/cli/commands.py +283 -0
- pymotion_studio-1.0.1/pymotion/clip/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/clip/audio.py +336 -0
- pymotion_studio-1.0.1/pymotion/clip/base.py +236 -0
- pymotion_studio-1.0.1/pymotion/clip/color.py +251 -0
- pymotion_studio-1.0.1/pymotion/clip/image.py +207 -0
- pymotion_studio-1.0.1/pymotion/clip/scene3d.py +205 -0
- pymotion_studio-1.0.1/pymotion/clip/shape.py +317 -0
- pymotion_studio-1.0.1/pymotion/clip/text.py +335 -0
- pymotion_studio-1.0.1/pymotion/clip/video.py +342 -0
- pymotion_studio-1.0.1/pymotion/composition.py +271 -0
- pymotion_studio-1.0.1/pymotion/config.py +80 -0
- pymotion_studio-1.0.1/pymotion/effects/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/effects/base.py +34 -0
- pymotion_studio-1.0.1/pymotion/effects/color.py +504 -0
- pymotion_studio-1.0.1/pymotion/effects/distortion.py +243 -0
- pymotion_studio-1.0.1/pymotion/effects/light.py +279 -0
- pymotion_studio-1.0.1/pymotion/effects/visual.py +403 -0
- pymotion_studio-1.0.1/pymotion/export/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/export/encoder.py +290 -0
- pymotion_studio-1.0.1/pymotion/export/presets.py +263 -0
- pymotion_studio-1.0.1/pymotion/particle/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/particle/system.py +690 -0
- pymotion_studio-1.0.1/pymotion/preview/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/preview/server.py +392 -0
- pymotion_studio-1.0.1/pymotion/render/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/render/backend_2d.py +51 -0
- pymotion_studio-1.0.1/pymotion/render/backend_3d.py +1595 -0
- pymotion_studio-1.0.1/pymotion/render/backend_html.py +1 -0
- pymotion_studio-1.0.1/pymotion/render/color_pipeline.py +404 -0
- pymotion_studio-1.0.1/pymotion/render/compositor.py +438 -0
- pymotion_studio-1.0.1/pymotion/render/interface.py +45 -0
- pymotion_studio-1.0.1/pymotion/render/pipeline.py +113 -0
- pymotion_studio-1.0.1/pymotion/security/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/security/validation.py +201 -0
- pymotion_studio-1.0.1/pymotion/template/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/template/base.py +175 -0
- pymotion_studio-1.0.1/pymotion/text/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/text/animated.py +900 -0
- pymotion_studio-1.0.1/pymotion/text/renderer.py +769 -0
- pymotion_studio-1.0.1/pymotion/timeline.py +109 -0
- pymotion_studio-1.0.1/pymotion/transition/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/transition/base.py +44 -0
- pymotion_studio-1.0.1/pymotion/transition/library.py +1023 -0
- pymotion_studio-1.0.1/pymotion/utils/__init__.py +1 -0
- pymotion_studio-1.0.1/pymotion/utils/asset.py +102 -0
- pymotion_studio-1.0.1/pymotion/utils/color.py +202 -0
- pymotion_studio-1.0.1/pymotion/utils/logging.py +51 -0
- pymotion_studio-1.0.1/pymotion/utils/math.py +207 -0
- pymotion_studio-1.0.1/pyproject.toml +96 -0
- pymotion_studio-1.0.1/tests/__init__.py +1 -0
- pymotion_studio-1.0.1/tests/conftest.py +63 -0
- pymotion_studio-1.0.1/tests/integration/__init__.py +1 -0
- pymotion_studio-1.0.1/tests/integration/test_4k_render.py +119 -0
- pymotion_studio-1.0.1/tests/integration/test_encode.py +107 -0
- pymotion_studio-1.0.1/tests/integration/test_phase02_exit.py +232 -0
- pymotion_studio-1.0.1/tests/integration/test_phase03_exit.py +246 -0
- pymotion_studio-1.0.1/tests/integration/test_phase04_exit.py +222 -0
- pymotion_studio-1.0.1/tests/integration/test_render_2d.py +187 -0
- pymotion_studio-1.0.1/tests/performance/__init__.py +1 -0
- pymotion_studio-1.0.1/tests/performance/test_regression.py +117 -0
- pymotion_studio-1.0.1/tests/snapshot/__init__.py +1 -0
- pymotion_studio-1.0.1/tests/snapshot/references/color_solid_blue.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/color_solid_red.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/effect_brightness.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/effect_desaturated.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/effect_gaussian_blur.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/effect_neon_glow.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/effect_vignette.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/effect_wave_warp.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/grade_desaturated.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/grade_warm.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/gradient_linear_rb.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/gradient_radial_wb.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/particles_custom_f10.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/particles_sparkles_f5.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/shape_circle_green.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/shape_rect_yellow.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/text_typewriter.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/transition_dissolve_50.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/transition_iris_in_30.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/references/transition_wipe_diag_50.npy +0 -0
- pymotion_studio-1.0.1/tests/snapshot/test_snapshots.py +274 -0
- pymotion_studio-1.0.1/tests/unit/__init__.py +1 -0
- pymotion_studio-1.0.1/tests/unit/test_3d_extended.py +203 -0
- pymotion_studio-1.0.1/tests/unit/test_3d_features.py +161 -0
- pymotion_studio-1.0.1/tests/unit/test_animated_text.py +131 -0
- pymotion_studio-1.0.1/tests/unit/test_audio_analysis.py +120 -0
- pymotion_studio-1.0.1/tests/unit/test_audio_mixer.py +132 -0
- pymotion_studio-1.0.1/tests/unit/test_backend_3d.py +363 -0
- pymotion_studio-1.0.1/tests/unit/test_cli.py +72 -0
- pymotion_studio-1.0.1/tests/unit/test_cli_doctor.py +31 -0
- pymotion_studio-1.0.1/tests/unit/test_color.py +126 -0
- pymotion_studio-1.0.1/tests/unit/test_color_pipeline.py +202 -0
- pymotion_studio-1.0.1/tests/unit/test_compositor.py +126 -0
- pymotion_studio-1.0.1/tests/unit/test_config.py +73 -0
- pymotion_studio-1.0.1/tests/unit/test_coverage_boost.py +521 -0
- pymotion_studio-1.0.1/tests/unit/test_coverage_boost2.py +811 -0
- pymotion_studio-1.0.1/tests/unit/test_easing.py +93 -0
- pymotion_studio-1.0.1/tests/unit/test_effects.py +365 -0
- pymotion_studio-1.0.1/tests/unit/test_encoder.py +62 -0
- pymotion_studio-1.0.1/tests/unit/test_exr_fallback.py +146 -0
- pymotion_studio-1.0.1/tests/unit/test_hdr_loading.py +138 -0
- pymotion_studio-1.0.1/tests/unit/test_keyframe.py +130 -0
- pymotion_studio-1.0.1/tests/unit/test_math.py +179 -0
- pymotion_studio-1.0.1/tests/unit/test_particle_system.py +244 -0
- pymotion_studio-1.0.1/tests/unit/test_presets.py +89 -0
- pymotion_studio-1.0.1/tests/unit/test_preview_jupyter.py +38 -0
- pymotion_studio-1.0.1/tests/unit/test_renderer.py +66 -0
- pymotion_studio-1.0.1/tests/unit/test_scene3d.py +170 -0
- pymotion_studio-1.0.1/tests/unit/test_security.py +166 -0
- pymotion_studio-1.0.1/tests/unit/test_template.py +99 -0
- pymotion_studio-1.0.1/tests/unit/test_text_renderer.py +214 -0
- pymotion_studio-1.0.1/tests/unit/test_tone_mapping.py +109 -0
- pymotion_studio-1.0.1/tests/unit/test_transitions.py +522 -0
- pymotion_studio-1.0.1/tests/unit/test_v1_api.py +282 -0
- pymotion_studio-1.0.1/tests/unit/test_variable_font.py +114 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
env:
|
|
13
|
+
SYSTEM_DEPS: ffmpeg libcairo2-dev pkg-config libfreetype6-dev libharfbuzz-dev fonts-liberation
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
lint:
|
|
17
|
+
name: Lint & Type Check
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
cache: pip
|
|
25
|
+
- name: Install system dependencies
|
|
26
|
+
run: |
|
|
27
|
+
sudo apt-get update
|
|
28
|
+
sudo apt-get install -y $SYSTEM_DEPS
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: pip install -e ".[dev]"
|
|
31
|
+
- name: Ruff format check
|
|
32
|
+
run: ruff format --check pymotion/ tests/
|
|
33
|
+
- name: Ruff lint
|
|
34
|
+
run: ruff check pymotion/ tests/
|
|
35
|
+
- name: Mypy strict
|
|
36
|
+
run: mypy --strict pymotion/
|
|
37
|
+
|
|
38
|
+
test:
|
|
39
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
strategy:
|
|
42
|
+
fail-fast: false
|
|
43
|
+
matrix:
|
|
44
|
+
python-version: ["3.11", "3.12"]
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
- uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: ${{ matrix.python-version }}
|
|
50
|
+
cache: pip
|
|
51
|
+
- name: Install system dependencies
|
|
52
|
+
run: |
|
|
53
|
+
sudo apt-get update
|
|
54
|
+
sudo apt-get install -y $SYSTEM_DEPS
|
|
55
|
+
- name: Install Python dependencies
|
|
56
|
+
run: pip install -e ".[dev]"
|
|
57
|
+
- name: Run tests
|
|
58
|
+
run: pytest --cov=pymotion --cov-report=xml --cov-fail-under=80 -v
|
|
59
|
+
- name: Upload coverage
|
|
60
|
+
if: matrix.python-version == '3.12'
|
|
61
|
+
uses: actions/upload-artifact@v4
|
|
62
|
+
with:
|
|
63
|
+
name: coverage-report
|
|
64
|
+
path: coverage.xml
|
|
65
|
+
|
|
66
|
+
security:
|
|
67
|
+
name: Security Audit
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/checkout@v4
|
|
71
|
+
- uses: actions/setup-python@v5
|
|
72
|
+
with:
|
|
73
|
+
python-version: "3.12"
|
|
74
|
+
cache: pip
|
|
75
|
+
- name: Install system dependencies
|
|
76
|
+
run: |
|
|
77
|
+
sudo apt-get update
|
|
78
|
+
sudo apt-get install -y $SYSTEM_DEPS
|
|
79
|
+
- name: Install dependencies
|
|
80
|
+
run: |
|
|
81
|
+
pip install pip-audit
|
|
82
|
+
pip install -e .
|
|
83
|
+
- name: pip-audit
|
|
84
|
+
run: pip-audit
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
name: Build Distribution
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- name: Install build tools
|
|
21
|
+
run: pip install build
|
|
22
|
+
- name: Build package
|
|
23
|
+
run: python -m build
|
|
24
|
+
- name: Upload artifacts
|
|
25
|
+
uses: actions/upload-artifact@v4
|
|
26
|
+
with:
|
|
27
|
+
name: dist
|
|
28
|
+
path: dist/
|
|
29
|
+
|
|
30
|
+
publish-pypi:
|
|
31
|
+
name: Publish to PyPI
|
|
32
|
+
needs: build
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
environment:
|
|
35
|
+
name: pypi
|
|
36
|
+
url: https://pypi.org/p/pymotion-studio
|
|
37
|
+
steps:
|
|
38
|
+
- name: Download artifacts
|
|
39
|
+
uses: actions/download-artifact@v4
|
|
40
|
+
with:
|
|
41
|
+
name: dist
|
|
42
|
+
path: dist/
|
|
43
|
+
- name: Publish to PyPI
|
|
44
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
name: Create GitHub Release
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
- name: Extract changelog for this version
|
|
20
|
+
id: changelog
|
|
21
|
+
run: |
|
|
22
|
+
TAG="${GITHUB_REF#refs/tags/v}"
|
|
23
|
+
# Extract section between this version header and the next
|
|
24
|
+
awk "/^## \[${TAG}\]/{found=1; next} /^## \[/{if(found) exit} found{print}" CHANGELOG.md > release_notes.md
|
|
25
|
+
echo "Release notes:"
|
|
26
|
+
cat release_notes.md
|
|
27
|
+
- name: Create GitHub Release
|
|
28
|
+
uses: softprops/action-gh-release@v2
|
|
29
|
+
with:
|
|
30
|
+
body_path: release_notes.md
|
|
31
|
+
generate_release_notes: false
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg-info/
|
|
7
|
+
*.egg
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
eggs/
|
|
11
|
+
*.whl
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.env
|
|
15
|
+
.venv/
|
|
16
|
+
venv/
|
|
17
|
+
ENV/
|
|
18
|
+
|
|
19
|
+
# IDE
|
|
20
|
+
.idea/
|
|
21
|
+
.vscode/
|
|
22
|
+
*.swp
|
|
23
|
+
*.swo
|
|
24
|
+
*~
|
|
25
|
+
|
|
26
|
+
# Type checking
|
|
27
|
+
.mypy_cache/
|
|
28
|
+
|
|
29
|
+
# Linting
|
|
30
|
+
.ruff_cache/
|
|
31
|
+
|
|
32
|
+
# Testing
|
|
33
|
+
htmlcov/
|
|
34
|
+
.coverage
|
|
35
|
+
.coverage.*
|
|
36
|
+
coverage.xml
|
|
37
|
+
*.cover
|
|
38
|
+
.pytest_cache/
|
|
39
|
+
|
|
40
|
+
# OS
|
|
41
|
+
.DS_Store
|
|
42
|
+
Thumbs.db
|
|
43
|
+
|
|
44
|
+
# Build artifacts / rendered output
|
|
45
|
+
*.mp4
|
|
46
|
+
*.mov
|
|
47
|
+
*.webm
|
|
48
|
+
*.gif
|
|
49
|
+
*.avi
|
|
50
|
+
test_output.*
|
|
51
|
+
|
|
52
|
+
# Docs build
|
|
53
|
+
site/
|
|
54
|
+
|
|
55
|
+
# Example output (generated by running examples)
|
|
56
|
+
examples/output/
|
|
57
|
+
|
|
58
|
+
# Internal project documents (not part of the distributed package)
|
|
59
|
+
PYMOTION_STATE.md
|
|
60
|
+
PyMotion_PRD.md
|
|
61
|
+
PyMotion_Framework_Paper.docx
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to PyMotion are documented here.
|
|
4
|
+
|
|
5
|
+
## [1.0.1] — 2026-03-10
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Critical: compositor alpha cache memory aliasing** — `_alpha_cache` in `compositor.py`
|
|
9
|
+
used numpy memory pointers (`ctypes.data`) as cache keys. When numpy reused memory
|
|
10
|
+
addresses for new frame allocations, the cache returned stale alpha info from previous
|
|
11
|
+
frames, causing the compositor to randomly skip text and clip layers (visible as
|
|
12
|
+
flickering/disappearing text in rendered videos). Fixed by clearing the cache at the
|
|
13
|
+
start of each `composite_layers()` call.
|
|
14
|
+
- **Text animation reveal-mask architecture** — Rewrote Typewriter, WordByWord, and
|
|
15
|
+
LetterByLetter presets to use a cached full-text render with a horizontal alpha reveal
|
|
16
|
+
mask. Already-revealed pixels are now bit-for-bit identical across frames. CountUp and
|
|
17
|
+
CountDown use quintic ease-out with frame-stepping (`step_frames=3`) for smooth
|
|
18
|
+
deceleration.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **H.264 encoding quality** — CRF 18 → 10, preset `faster` → `medium` for all H.264
|
|
22
|
+
presets. Added `no-dct-decimate` and `no-fast-pskip` x264 params to eliminate temporal
|
|
23
|
+
text shimmer. Added Lanczos chroma scaling (`-sws_flags lanczos+accurate_rnd+full_chroma_int`)
|
|
24
|
+
for better colored text quality during RGB → YUV420p conversion.
|
|
25
|
+
- **H.265 encoding quality** — CRF 22 → 16, preset `faster` → `medium`.
|
|
26
|
+
- **Instagram/TikTok presets** — Added `-tune animation` for better text/graphics quality.
|
|
27
|
+
- **FreeType text renderer** — Replaced block-character fallback with proper FreeType
|
|
28
|
+
glyph rendering in `_render_text_simple`. Added glyph cache and character position
|
|
29
|
+
measurement for reveal-mask animations.
|
|
30
|
+
|
|
31
|
+
### Improved
|
|
32
|
+
- **Examples rewritten** — All 5 example scripts (`01_real_estate_tour` through
|
|
33
|
+
`05_educational_explainer`) rewritten as complete, production-ready runnable demos
|
|
34
|
+
showcasing real-world niches (real estate, tech review, fitness, restaurant, education).
|
|
35
|
+
Each uses multiple PyMotion features: ImageClip, TextClip, ShapeClip, GradientClip,
|
|
36
|
+
animated text, particles, blend modes, and multi-track composition.
|
|
37
|
+
- **Stock assets** — Added `download_assets.py` script and 19 stock image/audio assets
|
|
38
|
+
for the example scripts.
|
|
39
|
+
|
|
40
|
+
## [1.0.0] — 2026-03-09
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- Complete PRD §8.2 public API: all symbols importable from `import pymotion`
|
|
44
|
+
- `Silence` helper for creating silent audio placeholders
|
|
45
|
+
- `animate()` shorthand for two-keyframe animations
|
|
46
|
+
- `Align` enum for text/element alignment (13 values)
|
|
47
|
+
- Audio effects: `Reverb`, `Delay`, `PitchShift`, `NoiseReduction`, `LowPassFilter`, `HighPassFilter`
|
|
48
|
+
- 3D exports: `Scene3DClip`, `Scene3D`, `Camera`, `PointLight`, `DirectionalLight`, `SpotLight`, `AmbientLight`, `HDRIEnvironment`, `PBRMaterial`
|
|
49
|
+
- Particle exports: `ParticleSystem`, `Emitter`, `Sparkles`, `Confetti`, `Fire`, `Smoke`, `Rain`, `Stars`
|
|
50
|
+
- `ScrambleText` alias for `Scramble` animated text
|
|
51
|
+
- 37 new unit tests for v1.0 API surface
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
- Version bumped to 1.0.0 (stable release)
|
|
55
|
+
- `__init__.py` docstring updated to "v1.0"
|
|
56
|
+
|
|
57
|
+
## [0.9.0-rc] — 2026-03-09
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- `PyMotionConfig` global configuration (network access, cache size, file limits)
|
|
61
|
+
- ACES, Reinhard, and Filmic tone mapping operators
|
|
62
|
+
- `pymotion doctor` CLI command for checking system dependencies
|
|
63
|
+
- Variable font full axis support (ital, opsz, custom axes)
|
|
64
|
+
- Jupyter integration: `export_frame_inline()` and `preview_widget()`
|
|
65
|
+
- MkDocs documentation site with API reference and 5 guides
|
|
66
|
+
- 10 example scripts
|
|
67
|
+
- Dockerfile for containerized usage
|
|
68
|
+
- README with install, quickstart, feature matrix
|
|
69
|
+
- Performance regression test infrastructure
|
|
70
|
+
|
|
71
|
+
### Changed
|
|
72
|
+
- Asset cache size now configurable via `PyMotionConfig.cache_max_bytes`
|
|
73
|
+
- Color pipeline supports tone mapping parameter
|
|
74
|
+
|
|
75
|
+
## [0.4.0-beta] — 2026-03-09
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
- All 39 built-in transitions (19 new: ZoomBlur, Glitch, FilmBurn, etc.)
|
|
79
|
+
- Complete visual effects: MotionBlur, FilmGrain, Sharpen, ChromaticAberration, Glow, Bloom, LensFlare
|
|
80
|
+
- Color effects: Brightness, Contrast, Saturation, HSL, ColorBalance, Curves, LUT, SplitToning, BleachBypass
|
|
81
|
+
- Distortion effects: WaveWarp, Ripple, Twirl, PerspectiveWarp, Fisheye
|
|
82
|
+
- Light effects: LensFlare, GodRays, NeonGlow, LightLeak
|
|
83
|
+
- Particle presets: Stars, Dust, Explosion, Bubbles (9 total)
|
|
84
|
+
- 9 animated text presets (Typewriter, WordByWord, etc.)
|
|
85
|
+
- Variable font support (weight, width, slant axes)
|
|
86
|
+
- Google Fonts download with httpx and domain allowlist
|
|
87
|
+
- Volume keyframe automation and pan automation
|
|
88
|
+
- Waveform-to-keyframe converter
|
|
89
|
+
- Template ABC with field validation
|
|
90
|
+
- Frame sequence export (PNG/EXR)
|
|
91
|
+
- All 15 export presets
|
|
92
|
+
- Frame cache for static layers
|
|
93
|
+
- All 8 blend modes (Multiply, Screen, Overlay, etc.)
|
|
94
|
+
- CLI benchmark, validate, new commands
|
|
95
|
+
- pip-audit in CI
|
|
96
|
+
|
|
97
|
+
## [0.3.0-beta] — 2026-03-09
|
|
98
|
+
|
|
99
|
+
### Added
|
|
100
|
+
- 3D rendering backend (ModernGL headless, PBR shaders, OBJ/GLTF loading)
|
|
101
|
+
- SSAO, Bloom, Depth of Field post-FX
|
|
102
|
+
- ACES/Filmic/Reinhard tone mapping (3D backend)
|
|
103
|
+
- Audio DSP effects (EQ, Compressor, Limiter via pedalboard)
|
|
104
|
+
- Beat detection, onset detection, waveform extraction (librosa)
|
|
105
|
+
- Sidechain compression
|
|
106
|
+
- Particle system with vectorized NumPy updates
|
|
107
|
+
- 5 particle presets (Sparkles, Confetti, Fire, Smoke, Rain)
|
|
108
|
+
- Color pipeline with .cube LUT support and trilinear interpolation
|
|
109
|
+
- Color grading (lift/gamma/gain/saturation)
|
|
110
|
+
- Hot-reload preview server (asyncio + aiohttp + WebSocket)
|
|
111
|
+
- Parallel frame rendering (multiprocessing)
|
|
112
|
+
|
|
113
|
+
## [0.2.0-alpha] — 2026-03-09
|
|
114
|
+
|
|
115
|
+
### Added
|
|
116
|
+
- FontLoader with system font discovery and LRU cache
|
|
117
|
+
- GlyphRenderer with FreeType and HarfBuzz integration
|
|
118
|
+
- TextClip with multiline word-wrap, alignment, stroke, shadow
|
|
119
|
+
- VideoClip (FFmpeg decode, trim, loop, speed, reverse)
|
|
120
|
+
- GradientClip (linear, radial, conic)
|
|
121
|
+
- Complete easing library (30+ functions, spring, cubic bezier, steps)
|
|
122
|
+
- Color interpolation via OKLCH
|
|
123
|
+
- 20 transitions (Fade, CrossDissolve, Slide, Push, Cover, Reveal, Zoom)
|
|
124
|
+
- AudioMixer with add, set_volume, render
|
|
125
|
+
- AudioClip with trim, fade, volume, loop
|
|
126
|
+
- 8 export presets
|
|
127
|
+
- CLI preview command (basic)
|
|
128
|
+
|
|
129
|
+
## [0.1.0-alpha] — 2026-03-09
|
|
130
|
+
|
|
131
|
+
### Added
|
|
132
|
+
- Core architecture: Composition, Track, Clip base class
|
|
133
|
+
- ColorClip, ImageClip, ShapeClip
|
|
134
|
+
- Keyframe animation system with interpolation
|
|
135
|
+
- 2D rendering backend (Cairo)
|
|
136
|
+
- Compositor with alpha blending
|
|
137
|
+
- FFmpeg encoder with subprocess (shell=False)
|
|
138
|
+
- GaussianBlur, Vignette effects
|
|
139
|
+
- Security validators (path, color, asset magic, text sanitize)
|
|
140
|
+
- CLI render and export-frame commands
|
|
141
|
+
- Asset loader with LRU cache
|
|
142
|
+
- structlog-based logging
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
|
|
3
|
+
# System dependencies for Cairo, FreeType, and FFmpeg
|
|
4
|
+
RUN apt-get update && \
|
|
5
|
+
apt-get install -y --no-install-recommends \
|
|
6
|
+
ffmpeg \
|
|
7
|
+
libcairo2-dev \
|
|
8
|
+
pkg-config \
|
|
9
|
+
libfreetype6-dev \
|
|
10
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
11
|
+
|
|
12
|
+
WORKDIR /app
|
|
13
|
+
|
|
14
|
+
# Copy project files and install
|
|
15
|
+
COPY . .
|
|
16
|
+
RUN pip install --no-cache-dir -e .
|
|
17
|
+
|
|
18
|
+
ENTRYPOINT ["pymotion"]
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
PyMotion Source Available License
|
|
2
|
+
Version 1.0, March 2026
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 Ohswedd. All rights reserved.
|
|
5
|
+
|
|
6
|
+
1. DEFINITIONS
|
|
7
|
+
|
|
8
|
+
"Software" means the PyMotion library source code, documentation, and
|
|
9
|
+
associated files in this repository.
|
|
10
|
+
|
|
11
|
+
"You" means any individual or legal entity exercising permissions granted
|
|
12
|
+
by this License.
|
|
13
|
+
|
|
14
|
+
"Derivative Work" means any work that is based on or incorporates the
|
|
15
|
+
Software, including modifications, translations, adaptations, or
|
|
16
|
+
extensions of the Software's source code.
|
|
17
|
+
|
|
18
|
+
"Application" means any software product, service, or system that uses
|
|
19
|
+
the Software as a dependency, library, or component — but is not itself
|
|
20
|
+
a distribution of the Software.
|
|
21
|
+
|
|
22
|
+
2. PERMITTED USES
|
|
23
|
+
|
|
24
|
+
Subject to the conditions below, You are granted a non-exclusive,
|
|
25
|
+
worldwide, royalty-free right to:
|
|
26
|
+
|
|
27
|
+
a) USE the Software in any project, including commercial Applications.
|
|
28
|
+
You may import, call, and depend on the Software in products you
|
|
29
|
+
build and sell.
|
|
30
|
+
|
|
31
|
+
b) FORK and MODIFY the Software for your own internal use, including
|
|
32
|
+
bug fixes, performance improvements, and feature additions.
|
|
33
|
+
|
|
34
|
+
c) CONTRIBUTE modifications back to the original repository via pull
|
|
35
|
+
requests or patches, under this same License.
|
|
36
|
+
|
|
37
|
+
d) STUDY the Software's source code for educational, research, or
|
|
38
|
+
reference purposes.
|
|
39
|
+
|
|
40
|
+
3. RESTRICTIONS
|
|
41
|
+
|
|
42
|
+
You may NOT:
|
|
43
|
+
|
|
44
|
+
a) REDISTRIBUTE the Software, in whole or in substantial part, as a
|
|
45
|
+
standalone library, package, framework, or product — whether in
|
|
46
|
+
original or modified form, and whether for free or for a fee.
|
|
47
|
+
|
|
48
|
+
b) PUBLISH, UPLOAD, or DISTRIBUTE the Software (or a Derivative Work
|
|
49
|
+
of the Software) to any package registry, marketplace, app store,
|
|
50
|
+
or distribution channel as a library or framework.
|
|
51
|
+
|
|
52
|
+
c) SELL, LICENSE, SUBLICENSE, or otherwise commercially exploit the
|
|
53
|
+
Software itself as a product. This includes offering the Software
|
|
54
|
+
as a paid library, a SaaS wrapper around its core functionality, or
|
|
55
|
+
a rebranded/white-labeled distribution.
|
|
56
|
+
|
|
57
|
+
d) REMOVE or ALTER this license notice, copyright notice, or
|
|
58
|
+
attribution from any copy of the Software.
|
|
59
|
+
|
|
60
|
+
4. CONTRIBUTIONS
|
|
61
|
+
|
|
62
|
+
By submitting a contribution (pull request, patch, issue, or other
|
|
63
|
+
material) to the official repository, You grant the copyright holder a
|
|
64
|
+
perpetual, worldwide, royalty-free, irrevocable license to use,
|
|
65
|
+
reproduce, modify, distribute, and sublicense your contribution as part
|
|
66
|
+
of the Software under this License or any future license version.
|
|
67
|
+
|
|
68
|
+
5. CLARIFICATIONS
|
|
69
|
+
|
|
70
|
+
- Using PyMotion as a dependency in your commercial application (e.g.,
|
|
71
|
+
importing it in a video rendering service you sell) is PERMITTED.
|
|
72
|
+
- Forking the repository to fix a bug for your own project is PERMITTED.
|
|
73
|
+
- Publishing a modified version of PyMotion to PyPI, npm, or any
|
|
74
|
+
registry under any name is NOT PERMITTED.
|
|
75
|
+
- Copying substantial portions of the Software into another library
|
|
76
|
+
that serves the same purpose is NOT PERMITTED.
|
|
77
|
+
- Referencing small code snippets (< 50 lines) for educational
|
|
78
|
+
purposes with attribution is PERMITTED.
|
|
79
|
+
|
|
80
|
+
6. NO WARRANTY
|
|
81
|
+
|
|
82
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
83
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
84
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
85
|
+
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES
|
|
86
|
+
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
87
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
88
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
89
|
+
|
|
90
|
+
7. TERMINATION
|
|
91
|
+
|
|
92
|
+
This License and the rights granted hereunder will terminate
|
|
93
|
+
automatically if You fail to comply with any of its terms. Upon
|
|
94
|
+
termination, You must cease all use and destroy all copies of the
|
|
95
|
+
Software in your possession.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.PHONY: lint test render clean format
|
|
2
|
+
|
|
3
|
+
lint: format
|
|
4
|
+
ruff check pymotion/ tests/
|
|
5
|
+
mypy --strict pymotion/
|
|
6
|
+
|
|
7
|
+
format:
|
|
8
|
+
ruff format pymotion/ tests/
|
|
9
|
+
|
|
10
|
+
test:
|
|
11
|
+
pytest -v
|
|
12
|
+
|
|
13
|
+
render:
|
|
14
|
+
python examples/01_real_estate_tour.py
|
|
15
|
+
|
|
16
|
+
clean:
|
|
17
|
+
rm -rf __pycache__ .mypy_cache .ruff_cache htmlcov dist build *.egg-info .pytest_cache .coverage
|
|
18
|
+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
|
19
|
+
find . -type f -name "*.pyc" -delete 2>/dev/null || true
|