tscprojpy
tscprojpy is a Python package for parsing and manipulating Camtasia .tscproj project files programmatically. It enables automated workflows for video project management, scaling, and transformation.
Quick Start
Installation
pip install tscprojpy
Basic Usage
# Scale a project to 150%
tscprojpy xyscale --input project.tscproj --scale 150.0
# Scale to 4K with custom output
tscprojpy xyscale --input project.tscproj --scale 200.0 --output project_4k.tscproj
Why tscprojpy?
The Problem
Camtasia is a powerful screen recording and video editing tool, but it lacks programmatic access to project files. When you need to:
- Convert projects between different resolutions (1080p → 4K)
- Batch process multiple projects
- Integrate Camtasia into automated workflows
- Analyze project structure programmatically
You're stuck doing everything manually through the GUI.
The Solution
tscprojpy treats Camtasia project files (.tscproj) as data, enabling:
- Automated scaling: Resize projects without manual adjustment
- Batch operations: Process multiple files programmatically
- Integration: Build Camtasia into larger video production pipelines
- Analysis: Extract project metadata and structure
How It Works
Understanding .tscproj Files
Camtasia project files are JSON documents containing:
- Canvas settings: Resolution, frame rate
- Media library: All imported assets (sourceBin)
- Timeline: Tracks, clips, effects, and animations
- Metadata: Project info and settings
The Scaling Process
When you scale a project:
- Canvas dimensions are multiplied by the scale factor
- All positions (x, y coordinates) are scaled proportionally
- All sizes (width, height) are scaled to match
- Animations maintain their relative positions
- Effects preserve their visual relationships
This ensures your project looks identical at the new resolution.
Detailed Usage
Command Line Interface
xyscale - Spatial Scaling
Scales all spatial properties in a project:
# Basic scaling
tscprojpy xyscale --input project.tscproj --scale 150.0
# Options
--input PATH Input .tscproj file (required)
--scale FLOAT Scale percentage, e.g., 150.0 for 150% (required)
--output PATH Output file (optional, auto-generated if omitted)
--verbose Enable detailed logging
What gets scaled:
- Canvas width and height
- Object positions (translation0, translation1)
- Object sizes (scale0, scale1)
- Rectangle arrays (rect, trackRect)
- Crop values (geometryCrop0-3)
- Callout dimensions and styling
- Keyframe values for animations
Auto-generated filenames:
project.tscproj→project_150pct.tscprojvideo.tscproj→video_200pct.tscproj
Python API (Future)
from tscprojpy import Project
# Load a project
project = Project.load("my_video.tscproj")
# Scale to 4K
project.scale(2.0) # 200%
# Save
project.save("my_video_4k.tscproj")
Technical Architecture
Core Components
tscprojpy/
├── cli.py # Command-line interface (Fire-based)
├── scaler.py # Core scaling engine
├── __init__.py # Package initialization
└── _version.py # Version management (hatch-vcs)
Scaling Engine Design
The TscprojScaler class uses a recursive traversal pattern:
class TscprojScaler:
# Property sets for different scaling rules
SCALE_PROPERTIES = {'width', 'height', 'translation0', ...}
MULTIPLY_SCALE_PROPERTIES = {'scale0', 'scale1', ...}
DIMENSION_ARRAYS = {'rect', 'trackRect'}
Key design decisions:
- Recursive traversal: Handles arbitrary nesting depth
- Property detection: Uses sets for O(1) lookup performance
- Type-aware scaling: Different rules for different property types
- Preservation: Non-spatial properties remain untouched
Property Scaling Rules
| Property Type | Scaling Rule | Example |
|---|---|---|
| Dimensions | Direct multiplication | width: 1920 → width: 2880 (1.5x) |
| Positions | Direct multiplication | translation0: 100 → translation0: 150 |
| Scales | Multiplication | scale0: 0.5 → scale0: 0.75 |
| Arrays | Element-wise | rect: [0,0,1920,1080] → rect: [0,0,2880,1620] |
| Time values | No change | start: 1000 → start: 1000 |
| Colors/Opacity | No change | opacity: 0.5 → opacity: 0.5 |
Version Compatibility
| Camtasia Version | .tscproj Version | Support Status |
|---|---|---|
| 2020 and earlier | 4.0 | ✅ Full support |
| 2021-2025 | 9.0 | ✅ Full support |
| Future versions | Unknown | ⚠️ Best effort |
Development Guide
Setting Up Development Environment
# Clone the repository
git clone https://github.com/yourusername/tscprojpy.git
cd tscprojpy
# Install with development dependencies
pip install -e ".[dev]"
# Or use uv (recommended)
uv sync
Project Structure
tscprojpy/
├── src/tscprojpy/ # Source code
├── tests/ # Test suite
├── docs/ # Documentation
│ └── tscproj-format.md # File format specification
├── example/ # Sample .tscproj files
└── pyproject.toml # Project configuration
Code Style and Quality
# Run linter
python -m ruff check src/
# Format code
python -m ruff format src/
# Run tests
python -m pytest
# Type checking (future)
python -m mypy src/
Testing Strategy
- Unit tests: Test individual scaling functions
- Integration tests: Test CLI commands end-to-end
- Property tests: Verify scaling mathematics
- Regression tests: Use example files to prevent breaks
Adding New Operations
To add a new operation (e.g., rotate):
- Create operation class inheriting from base:
class ProjectRotator(TscprojScaler):
def rotate_project(self, angle: float):
# Implementation
- Add CLI command:
def rotate(input: str, angle: float, output: str = None):
"""Rotate all content by angle degrees."""
# Implementation
- Register in Fire CLI:
fire.Fire({
"xyscale": xyscale,
"rotate": rotate, # New command
})
Debugging Tips
- Use verbose mode:
--verboseenables detailed logging - Check JSON diff: Compare input/output with a JSON diff tool
- Validate in Camtasia: Always test output files in Camtasia
- Small test files: Create minimal test cases for debugging
Future Roadmap
Planned Features
- Time scaling (
timescale): Change playback speed - Project assembly: Create .tscproj files from scratch
- Batch processing: Process entire directories
- Analysis tools: Extract project statistics
- Python API: Direct programmatic access
Architecture Evolution
Current:
CLI → Scaler → JSON → File
Future:
CLI ─┐
├→ Operations → Project Model → Serializer → File
API ─┘
Maintenance Notes
Version Management
- Uses
hatch-vcsfor version management - Version derived from git tags
- Tag format:
v0.1.0,v1.0.0
Release Process
- Update CHANGELOG.md
- Create git tag:
git tag v0.2.0 - Build:
python -m build - Upload:
python -m twine upload dist/*
Dependency Management
- Minimal dependencies for reliability
- Core:
fire(CLI),rich(UI),loguru(logging) - Development:
pytest,ruff - No heavy dependencies (numpy, pandas, etc.)
Performance Considerations
- JSON parsing is the bottleneck for large files
- Recursive traversal is O(n) where n = total properties
- Memory usage is 2x file size (input + output)
- Consider streaming for very large projects (future)
Troubleshooting
Common Issues
"Input file does not exist"
- Check file path is correct
- Use absolute paths if relative paths fail
"Scale factor must be positive"
- Scale is a percentage: use 150.0 for 150%, not 1.5
Output looks wrong in Camtasia
- Ensure you're using a compatible Camtasia version
- Check if project has custom effects that need manual adjustment
Large file performance
- Use
--verboseto see progress - Consider breaking very large projects into smaller ones
Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Areas for Contribution
- Additional operations (crop, rotate, effects)
- Performance optimizations
- Test coverage improvements
- Documentation and examples
- Bug fixes and edge cases
License
MIT License - see LICENSE file for details.
Acknowledgments
- Inspired by the need for automated video production workflows
- Thanks to the Camtasia community for file format insights
- Built with modern Python tooling (Fire, Rich, Ruff)
Release files for tscprojpy 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tscprojpy-1.0.2.tar.gz | 24.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tscprojpy-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.4 kB
Release files / tscprojpy-1.0.2.tar.gz
| Download URL | tscprojpy-1.0.2.tar.gz |
|---|---|
| Size | 24.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2060bb64e10a9acd5cd537553c66dd473a2f8a560c835d283d08f9b59dda1014
|
|
BLAKE2b-256 checksum How to use checksums |
126a66d23e2846a8e92084cb3975d40f43ad02347357533bb0e4eb33934f4d1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-httpx/0.28.1
|
Release files / tscprojpy-1.0.2-py3-none-any.whl
| Download URL | tscprojpy-1.0.2-py3-none-any.whl |
|---|---|
| Size | 32.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
382fb36d5cd91750bb4898a29f1cda7d705fcfe9d64c9e55b243683c289679fc
|
|
BLAKE2b-256 checksum How to use checksums |
fb2068e11ae79db29ef35fd224dcbd0f538217c461977fe3e4b176b9cb54f91d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-httpx/0.28.1
|