# Camtasio
A modern Python API and CLI for programmatically working with Camtasia projects.
## Overview
Camtasio provides a comprehensive toolkit for manipulating Camtasia project files (`.cmproj` directories containing `.tscproj` JSON files). It combines high-level object-oriented APIs with powerful low-level JSON manipulation capabilities for complete control over Camtasia projects.
### Key Features
- **๐ Project Management**: Read, modify, and save Camtasia projects (.tscproj files)
- **๐ฌ Timeline Operations**: List tracks, analyze clips, and manage markers
- **๐ Spatial Scaling**: Resize projects to different resolutions (`xyscale`)
- **โฑ๏ธ Temporal Scaling**: Change playback speed with audio preservation (`timescale`)
- **๐ Media Management**: List, clean, and replace media files (`media-ls`, `media-rm`, `media-replace`)
- **๐ฏ Batch Processing**: Apply operations across multiple projects (`batch`)
- **๐ง Rich CLI Tools**: Command-line interface with beautiful terminal output
- **๐ Project Analysis**: Detailed statistics, complexity scoring, and recommendations
- **โ
Version Compatibility**: Support for Camtasia 2018-2025+ (v1.0-v9.0)
## Installation
```bash
pip install camtasio
```
For development:
```bash
git clone https://github.com/yourusername/camtasio.git
cd camtasio
uv venv
uv sync
```
## Quick Start
### Command Line Interface
```bash
# Get project information
camtasio info my_project.tscproj --detailed
# Scale project spatially by 1.5x
camtasio xyscale my_project.tscproj 1.5 scaled_project.tscproj
# Scale timeline temporally (double speed)
camtasio timescale my_project.tscproj 2.0 fast_project.tscproj
# List and clean media
camtasio media_ls my_project.tscproj --detailed
camtasio media_rm my_project.tscproj # Remove unused media
# Batch process multiple projects
camtasio batch "projects/*.tscproj" info --detailed
# List timeline tracks and markers
camtasio track_ls my_project.tscproj --detailed
camtasio marker_ls my_project.tscproj
# Generate comprehensive analysis report
camtasio analyze my_project.tscproj
```
### Python API
```python
from camtasio import ProjectLoader, ProjectSaver, PropertyTransformer, TransformConfig, TransformType
from camtasio.serialization import load_json_file
# Load a project (low-level JSON approach)
project_data = load_json_file("my_project.tscproj")
# Scale spatially using transform engine
config = TransformConfig(TransformType.SPATIAL, factor=1.5)
transformer = PropertyTransformer(config)
scaled_data = transformer.transform_dict(project_data)
# Save result
saver = ProjectSaver()
saver.save_dict(scaled_data, "scaled_project.tscproj")
# Alternative: Using high-level Project model
from camtasio import Project
# Load using model-based approach
loader = ProjectLoader()
project_data = loader.load("my_project.tscproj")
project = Project.from_dict(project_data)
# Scale the project
scaled_project = project.scale_spatial(1.5)
# Convert back to dict and save
scaled_data = scaled_project.to_dict()
saver.save_dict(scaled_data, "scaled_project.tscproj")
```
## Available Commands
| Command | Description | Example |
|---------|-------------|---------|
| `info` | Show project information and statistics | `camtasio info project.tscproj --detailed` |
| `validate` | Check project integrity | `camtasio validate project.tscproj` |
| `xyscale` | Scale project dimensions | `camtasio xyscale project.tscproj 1.5` |
| `timescale` | Scale timeline duration | `camtasio timescale project.tscproj 0.5` |
| `media_ls` | List media bin contents | `camtasio media_ls project.tscproj --detailed` |
| `media_rm` | Remove unused media | `camtasio media_rm project.tscproj` |
| `media_replace` | Replace media paths | `camtasio media_replace project.tscproj old.mp4 new.mp4` |
| `track_ls` | List timeline tracks | `camtasio track_ls project.tscproj --detailed` |
| `marker_ls` | List timeline markers | `camtasio marker_ls project.tscproj` |
| `analyze` | Generate analysis report | `camtasio analyze project.tscproj` |
| `batch` | Process multiple files | `camtasio batch "*.tscproj" info` |
| `version` | Show version info | `camtasio version` |
## Project Structure
A Camtasia project (`.cmproj`) is a directory containing:
- `project.tscproj` - Main JSON project file
- `media/` - Imported media files
- macOS metadata files (bookmarks.plist, docPrefs)
The `.tscproj` file contains:
- Canvas dimensions and frame rate
- Source media bin with imported files
- Timeline with scenes, tracks, and clips
- Effects and annotations
## Advanced Usage
### Spatial Scaling
Resize projects while maintaining relative positions and proportions:
```python
from camtasio import ProjectLoader, ProjectSaver, Project
# Load project
loader = ProjectLoader()
project_data = loader.load("tutorial.tscproj")
project = Project.from_dict(project_data)
# Calculate scale factor for 1080p to 4K conversion
current_width = project.canvas.width # e.g., 1920
target_width = 3840
scale_factor = target_width / current_width
# Scale the project
scaled_project = project.scale_spatial(scale_factor)
# Save result
saver = ProjectSaver()
saver.save_dict(scaled_project.to_dict(), "tutorial_4k.tscproj")
```
### Timeline Manipulation
```python
from camtasio.serialization import load_json_file
# Load project data for analysis
project_data = load_json_file("tutorial.tscproj")
# Analyze timeline structure
timeline = project_data.get("timeline", {})
scene_track = timeline.get("sceneTrack", {})
scenes = scene_track.get("scenes", [])
for scene_idx, scene in enumerate(scenes):
print(f"Scene {scene_idx}: {scene.get('csml', {}).get('duration', 0)} duration")
# Analyze tracks within scene
tracks = scene.get("csml", {}).get("tracks", [])
for track_idx, track in enumerate(tracks):
track_id = track.get("trackId", "unknown")
print(f" Track {track_idx} (ID: {track_id})")
# Analyze media clips
for media_clip in track.get("medias", []):
clip_name = media_clip.get("_name", "unnamed")
start = media_clip.get("_start", 0)
duration = media_clip.get("_duration", 0)
print(f" Clip: {clip_name} (start: {start}, duration: {duration})")
```
### Media Management
```python
from pathlib import Path
from camtasio.serialization import load_json_file
# Load and analyze media bin
project_data = load_json_file("tutorial.tscproj")
source_bin = project_data.get("sourceBin", [])
print(f"Total media items: {len(source_bin)}")
# List all media files and check existence
missing_files = []
for item in source_bin:
name = item.get("_name", "unnamed")
media_type = item.get("_type", "unknown")
if "src" in item:
media_path = Path(item["src"])
exists = media_path.exists()
status = "โ" if exists else "โ"
print(f"{status} {name} ({media_type}): {media_path}")
if not exists:
missing_files.append(str(media_path))
else:
print(f"? {name} ({media_type}): No source path")
if missing_files:
print(f"\nWarning: {len(missing_files)} files not found!")
```
## Architecture
Camtasio provides both high-level and low-level APIs:
- **High-Level API**: Object-oriented interface with `Project`, `Timeline`, `Track`, and `Clip` classes
- **Low-Level API**: Direct JSON manipulation for advanced operations
- **Domain Models**: Structured representations of project components
- **Operations Engine**: Recursive traversal for complex transformations
## Compatibility
- โ
**Camtasia 2018-2025+**: Full support for v1.0-v9.0 formats
- โ
**Cross-platform**: Windows, macOS, Linux
- โ
**Python 3.11+**: Modern Python with type hints
- โ
**Format versions**: v1.0, v4.0, v9.0 and future versions
## Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Acknowledgments
Built with modern Python tooling:
- ๐ฆ `uv` and `hatch` for packaging
- ๐ `ruff` for linting and formatting
- ๐งช `pytest` for testing
- ๐จ `rich` for beautiful CLI output
- ๐ `loguru` for structured logging
Raw data
{
"_id": null,
"home_page": null,
"name": "camtasio",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": "Adam Twardoch <adam+github@twardoch.com>",
"keywords": "automation, camtasia, cmproj, editing, tscproj, video",
"author": null,
"author_email": "Adam Twardoch <adam+github@twardoch.com>",
"download_url": "https://files.pythonhosted.org/packages/ac/3b/8a5352c9789f2ad380c769c65304eb5804236e030cb85812b960dcdf0ced/camtasio-2025.0.7.tar.gz",
"platform": null,
"description": "# Camtasio\n\nA modern Python API and CLI for programmatically working with Camtasia projects.\n\n## Overview\n\nCamtasio provides a comprehensive toolkit for manipulating Camtasia project files (`.cmproj` directories containing `.tscproj` JSON files). It combines high-level object-oriented APIs with powerful low-level JSON manipulation capabilities for complete control over Camtasia projects.\n\n### Key Features\n\n- **\ud83d\udcc1 Project Management**: Read, modify, and save Camtasia projects (.tscproj files)\n- **\ud83c\udfac Timeline Operations**: List tracks, analyze clips, and manage markers\n- **\ud83d\udcd0 Spatial Scaling**: Resize projects to different resolutions (`xyscale`)\n- **\u23f1\ufe0f Temporal Scaling**: Change playback speed with audio preservation (`timescale`)\n- **\ud83d\udcc1 Media Management**: List, clean, and replace media files (`media-ls`, `media-rm`, `media-replace`)\n- **\ud83c\udfaf Batch Processing**: Apply operations across multiple projects (`batch`)\n- **\ud83d\udd27 Rich CLI Tools**: Command-line interface with beautiful terminal output\n- **\ud83d\udcca Project Analysis**: Detailed statistics, complexity scoring, and recommendations\n- **\u2705 Version Compatibility**: Support for Camtasia 2018-2025+ (v1.0-v9.0)\n\n## Installation\n\n```bash\npip install camtasio\n```\n\nFor development:\n```bash\ngit clone https://github.com/yourusername/camtasio.git\ncd camtasio\nuv venv\nuv sync\n```\n\n## Quick Start\n\n### Command Line Interface\n\n```bash\n# Get project information\ncamtasio info my_project.tscproj --detailed\n\n# Scale project spatially by 1.5x\ncamtasio xyscale my_project.tscproj 1.5 scaled_project.tscproj\n\n# Scale timeline temporally (double speed)\ncamtasio timescale my_project.tscproj 2.0 fast_project.tscproj\n\n# List and clean media\ncamtasio media_ls my_project.tscproj --detailed\ncamtasio media_rm my_project.tscproj # Remove unused media\n\n# Batch process multiple projects\ncamtasio batch \"projects/*.tscproj\" info --detailed\n\n# List timeline tracks and markers\ncamtasio track_ls my_project.tscproj --detailed\ncamtasio marker_ls my_project.tscproj\n\n# Generate comprehensive analysis report\ncamtasio analyze my_project.tscproj\n```\n\n### Python API\n\n```python\nfrom camtasio import ProjectLoader, ProjectSaver, PropertyTransformer, TransformConfig, TransformType\nfrom camtasio.serialization import load_json_file\n\n# Load a project (low-level JSON approach)\nproject_data = load_json_file(\"my_project.tscproj\")\n\n# Scale spatially using transform engine\nconfig = TransformConfig(TransformType.SPATIAL, factor=1.5)\ntransformer = PropertyTransformer(config)\nscaled_data = transformer.transform_dict(project_data)\n\n# Save result\nsaver = ProjectSaver()\nsaver.save_dict(scaled_data, \"scaled_project.tscproj\")\n\n# Alternative: Using high-level Project model\nfrom camtasio import Project\n\n# Load using model-based approach \nloader = ProjectLoader()\nproject_data = loader.load(\"my_project.tscproj\")\nproject = Project.from_dict(project_data)\n\n# Scale the project\nscaled_project = project.scale_spatial(1.5)\n\n# Convert back to dict and save\nscaled_data = scaled_project.to_dict()\nsaver.save_dict(scaled_data, \"scaled_project.tscproj\")\n```\n\n## Available Commands\n\n| Command | Description | Example |\n|---------|-------------|---------|\n| `info` | Show project information and statistics | `camtasio info project.tscproj --detailed` |\n| `validate` | Check project integrity | `camtasio validate project.tscproj` |\n| `xyscale` | Scale project dimensions | `camtasio xyscale project.tscproj 1.5` |\n| `timescale` | Scale timeline duration | `camtasio timescale project.tscproj 0.5` |\n| `media_ls` | List media bin contents | `camtasio media_ls project.tscproj --detailed` |\n| `media_rm` | Remove unused media | `camtasio media_rm project.tscproj` |\n| `media_replace` | Replace media paths | `camtasio media_replace project.tscproj old.mp4 new.mp4` |\n| `track_ls` | List timeline tracks | `camtasio track_ls project.tscproj --detailed` |\n| `marker_ls` | List timeline markers | `camtasio marker_ls project.tscproj` |\n| `analyze` | Generate analysis report | `camtasio analyze project.tscproj` |\n| `batch` | Process multiple files | `camtasio batch \"*.tscproj\" info` |\n| `version` | Show version info | `camtasio version` |\n\n## Project Structure\n\nA Camtasia project (`.cmproj`) is a directory containing:\n- `project.tscproj` - Main JSON project file\n- `media/` - Imported media files\n- macOS metadata files (bookmarks.plist, docPrefs)\n\nThe `.tscproj` file contains:\n- Canvas dimensions and frame rate\n- Source media bin with imported files\n- Timeline with scenes, tracks, and clips\n- Effects and annotations\n\n## Advanced Usage\n\n### Spatial Scaling\n\nResize projects while maintaining relative positions and proportions:\n\n```python\nfrom camtasio import ProjectLoader, ProjectSaver, Project\n\n# Load project\nloader = ProjectLoader()\nproject_data = loader.load(\"tutorial.tscproj\")\nproject = Project.from_dict(project_data)\n\n# Calculate scale factor for 1080p to 4K conversion\ncurrent_width = project.canvas.width # e.g., 1920\ntarget_width = 3840\nscale_factor = target_width / current_width\n\n# Scale the project\nscaled_project = project.scale_spatial(scale_factor)\n\n# Save result\nsaver = ProjectSaver()\nsaver.save_dict(scaled_project.to_dict(), \"tutorial_4k.tscproj\")\n```\n\n### Timeline Manipulation\n\n```python\nfrom camtasio.serialization import load_json_file\n\n# Load project data for analysis\nproject_data = load_json_file(\"tutorial.tscproj\")\n\n# Analyze timeline structure\ntimeline = project_data.get(\"timeline\", {})\nscene_track = timeline.get(\"sceneTrack\", {})\nscenes = scene_track.get(\"scenes\", [])\n\nfor scene_idx, scene in enumerate(scenes):\n print(f\"Scene {scene_idx}: {scene.get('csml', {}).get('duration', 0)} duration\")\n \n # Analyze tracks within scene\n tracks = scene.get(\"csml\", {}).get(\"tracks\", [])\n for track_idx, track in enumerate(tracks):\n track_id = track.get(\"trackId\", \"unknown\")\n print(f\" Track {track_idx} (ID: {track_id})\")\n \n # Analyze media clips\n for media_clip in track.get(\"medias\", []):\n clip_name = media_clip.get(\"_name\", \"unnamed\")\n start = media_clip.get(\"_start\", 0)\n duration = media_clip.get(\"_duration\", 0)\n print(f\" Clip: {clip_name} (start: {start}, duration: {duration})\")\n```\n\n### Media Management\n\n```python\nfrom pathlib import Path\nfrom camtasio.serialization import load_json_file\n\n# Load and analyze media bin\nproject_data = load_json_file(\"tutorial.tscproj\")\nsource_bin = project_data.get(\"sourceBin\", [])\n\nprint(f\"Total media items: {len(source_bin)}\")\n\n# List all media files and check existence\nmissing_files = []\nfor item in source_bin:\n name = item.get(\"_name\", \"unnamed\")\n media_type = item.get(\"_type\", \"unknown\")\n \n if \"src\" in item:\n media_path = Path(item[\"src\"])\n exists = media_path.exists()\n status = \"\u2713\" if exists else \"\u2717\"\n \n print(f\"{status} {name} ({media_type}): {media_path}\")\n \n if not exists:\n missing_files.append(str(media_path))\n else:\n print(f\"? {name} ({media_type}): No source path\")\n\nif missing_files:\n print(f\"\\nWarning: {len(missing_files)} files not found!\")\n```\n\n## Architecture\n\nCamtasio provides both high-level and low-level APIs:\n\n- **High-Level API**: Object-oriented interface with `Project`, `Timeline`, `Track`, and `Clip` classes\n- **Low-Level API**: Direct JSON manipulation for advanced operations\n- **Domain Models**: Structured representations of project components\n- **Operations Engine**: Recursive traversal for complex transformations\n\n## Compatibility\n\n- \u2705 **Camtasia 2018-2025+**: Full support for v1.0-v9.0 formats\n- \u2705 **Cross-platform**: Windows, macOS, Linux\n- \u2705 **Python 3.11+**: Modern Python with type hints\n- \u2705 **Format versions**: v1.0, v4.0, v9.0 and future versions\n\n## Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\nBuilt with modern Python tooling:\n- \ud83d\udce6 `uv` and `hatch` for packaging\n- \ud83d\udd0d `ruff` for linting and formatting\n- \ud83e\uddea `pytest` for testing\n- \ud83c\udfa8 `rich` for beautiful CLI output\n- \ud83d\udcdd `loguru` for structured logging",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python toolkit for programmatically manipulating Camtasia project files",
"version": "2025.0.7",
"project_urls": {
"Changelog": "https://github.com/twardoch/camtasio/blob/main/CHANGELOG.md",
"Documentation": "https://github.com/twardoch/camtasio",
"Homepage": "https://github.com/twardoch/camtasio",
"Issues": "https://github.com/twardoch/camtasio/issues",
"Repository": "https://github.com/twardoch/camtasio"
},
"split_keywords": [
"automation",
" camtasia",
" cmproj",
" editing",
" tscproj",
" video"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a9e4cae0406e2873cefbf7ee81032f6465f28d70ea3caf260b50346730372d51",
"md5": "127daabe6854d1a677dcb875f131aaf0",
"sha256": "0b1382ad1345f95b58ca4cd5023d50f9bfbd5e9735bbba8ae4028e4907d06788"
},
"downloads": -1,
"filename": "camtasio-2025.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "127daabe6854d1a677dcb875f131aaf0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 49278,
"upload_time": "2025-08-04T23:11:47",
"upload_time_iso_8601": "2025-08-04T23:11:47.762862Z",
"url": "https://files.pythonhosted.org/packages/a9/e4/cae0406e2873cefbf7ee81032f6465f28d70ea3caf260b50346730372d51/camtasio-2025.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ac3b8a5352c9789f2ad380c769c65304eb5804236e030cb85812b960dcdf0ced",
"md5": "e505661e0b53df4ab09e6f4be06b4058",
"sha256": "76a7c018f987bb74c07f6eb3097faf8b4b0b4982af91a4364603ab087655e567"
},
"downloads": -1,
"filename": "camtasio-2025.0.7.tar.gz",
"has_sig": false,
"md5_digest": "e505661e0b53df4ab09e6f4be06b4058",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 37095,
"upload_time": "2025-08-04T23:11:46",
"upload_time_iso_8601": "2025-08-04T23:11:46.197268Z",
"url": "https://files.pythonhosted.org/packages/ac/3b/8a5352c9789f2ad380c769c65304eb5804236e030cb85812b960dcdf0ced/camtasio-2025.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-04 23:11:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "twardoch",
"github_project": "camtasio",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "camtasio"
}