Name | clipsmith JSON |
Version |
0.1.4
JSON |
| download |
home_page | https://github.com/mm21/clipsmith |
Summary | Utility to work with video clips, especially suited for creating timelapses from dashcam footage |
upload_time | 2024-12-17 05:10:33 |
maintainer | None |
docs_url | None |
author | mm21 |
requires_python | <3.14,>=3.11 |
license | None |
keywords |
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
<!-- TODO: logo using glyphsynth -->
# ClipSmith
Utility to work with video clips, especially suited for dashcam footage
[](https://pypi.org/project/clipsmith)
[](https://pypi.org/project/clipsmith)
[]()
[]()
[](https://github.com/psf/black)
- [ClipSmith](#clipsmith)
- [Overview](#overview)
- [Getting started](#getting-started)
- [CLI](#cli)
- [Forging clips](#forging-clips)
- [Concatenating](#concatenating)
- [Trimming](#trimming)
- [Rescaling](#rescaling)
- [Input folder caching](#input-folder-caching)
- [API](#api)
- [Context](#context)
- [Clips](#clips)
## Overview
This project leverages [FFmpeg](https://ffmpeg.org/) and [doit](https://pydoit.org/) to provide a user-friendly utility for working with video clips and orchestrating pipelines of video editing operations. Clips can be readily concatenated, trimmed, and/or rescaled in a single command. This is especially useful for working with dashcam footage wherein there are many short video files to manage.
## Getting started
First, ensure you have ffmpeg installed:
```bash
# Ubuntu/Debian
sudo apt install ffmpeg
# macOS
brew install ffmpeg
# Windows
# Download from https://ffmpeg.org/download.html
```
Then install using pip:
```bash
pip install clipsmith
```
## CLI
### Forging clips
The command `clipsmith forge` is the entry point for creating new clips. Operations for concatenation, duration trimming, duration scaling, resolution scaling, and audio can be specified together in one command.
<!-- include doc/cli/forge.md -->
```
Usage: clipsmith forge [OPTIONS] INPUTS... OUTPUT
Create a video from one or more videos with specified operations applied
╭─ Arguments ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * inputs INPUTS... One or more paths to input video(s) or folder(s) of videos [default: None] [required] │
│ * output PATH Path to output video [default: None] [required] │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --trim-start FLOAT Start offset (seconds) in input file(s) [default: None] │
│ --trim-end FLOAT End offset (seconds) in input file(s) [default: None] │
│ --dur-scale FLOAT Scale duration by scale factor [default: None] │
│ --dur-target FLOAT Scale duration to target (seconds) [default: None] │
│ --res-scale FLOAT Scale resolution by scale factor [default: None] │
│ --res-target TEXT Scale resolution to target as WIDTH:HEIGHT [default: None] │
│ --audio --no-audio Whether to pass through audio to output (not yet supported with time scaling) [default: audio] │
│ --cache --no-cache Whether to store a cache of video metadata in input folders [default: no-cache] │
│ --log-level TEXT Log level passed to ffmpeg [default: info] │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```
<!-- include end -->
#### Concatenating
Concatenate multiple clips into a single one:
```bash
# Combine specific files
clipsmith forge clip1.mp4 clip2.mp4 combined.mp4
# Combine all clips from a folder
clipsmith forge input_folder/ combined.mp4
```
For any folders passed as inputs, their contents are recursively scanned depth-first to aggregate input videos.
#### Trimming
Trim clips using start and end time offsets:
```bash
# Trim to specific time range
clipsmith forge --trim-start 1.0 --trim-end 5.0 input.mp4 output.mp4
# Trim just the start
clipsmith forge --trim-start 1.0 input.mp4 output.mp4
# Trim just the end
clipsmith forge --trim-end 5.0 input.mp4 output.mp4
```
#### Rescaling
Rescale video duration and resolution:
```bash
# Speed up by factor (e.g. 2x faster)
clipsmith forge --dur-scale 2.0 --no-audio input.mp4 output.mp4
# Slow down by factor (e.g. 2x slower)
clipsmith forge --dur-scale 0.5 --no-audio input.mp4 output.mp4
# Rescale duration to specific value in seconds
clipsmith forge --dur-target 60.0 --no-audio input.mp4 output.mp4
# Rescale resolution by factor
clipsmith forge --res-scale 0.5 input.mp4 output.mp4
# Rescale resolution to specific value as WIDTH:HEIGHT
clipsmith forge --res-target 480:270 input.mp4 output.mp4
```
<!-- TODO:
### Clip playbooks
-->
### Input folder caching
For input folders with many videos, the process of scanning and validating input files can be time-consuming. In such cases, pass `--cache` to cache video metadata per folder. In case of multiple or interrupted invocations, ClipSmith will use this cache to quickly begin its work.
## API
### Context
The `Context` class provides the main interface for working with clips. It implements a task orchestration pattern using `doit`:
```python
from pathlib import Path
from clipsmith import Context
# Create a context
context = Context()
# Forge a new clip from input files
context.forge("output.mp4", [Path("input1.mp4"), Path("input2.mp4")])
# Execute all pending operations
context.doit()
```
### Clips
Clips can be manipulated using operation parameters for duration and resolution. A clip can be "reforged" into another clip, with `doit` managing orchestration of `ffmpeg` invocations.
```python
from clipsmith import (
Context,
OperationParams,
DurationParams,
ResolutionParams
)
context = Context()
inputs = [Path("input1.mp4"), Path("input2.mp4")]
# Trimming
clip1 = context.forge(
"output1.mp4",
inputs,
OperationParams(
duration_params=DurationParams(
trim_start=1.0, # Start at 1 second
trim_end=5.0, # End at 5 seconds
),
)
)
# Time scaling
clip2 = context.forge(
"output2.mp4",
inputs,
OperationParams(
duration_params=DurationParams(
scale=2.0, # Speed up by 2x
),
audio=False
)
)
# Resolution scaling
clip3 = context.forge(
"output3.mp4",
inputs,
OperationParams(
resolution_params=ResolutionParams(
target=(480, 270) # Scale to specific resolution
)
)
)
# Chain operations by reforging trimmed clip
clip4 = clip1.reforge(
"output4.mp4",
OperationParams(
resolution_params=ResolutionParams(
scale=0.5 # Scale resolution by factor
)
)
)
# Execute all operations
context.doit()
```
Raw data
{
"_id": null,
"home_page": "https://github.com/mm21/clipsmith",
"name": "clipsmith",
"maintainer": null,
"docs_url": null,
"requires_python": "<3.14,>=3.11",
"maintainer_email": null,
"keywords": null,
"author": "mm21",
"author_email": "mm21.dev@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/51/e5/12a104c13457f69a0a6fa2e6bbcfde1e4f6b06fb8c07c409e4b7d5309719/clipsmith-0.1.4.tar.gz",
"platform": null,
"description": "<!-- TODO: logo using glyphsynth -->\n\n# ClipSmith\nUtility to work with video clips, especially suited for dashcam footage\n\n[](https://pypi.org/project/clipsmith)\n[](https://pypi.org/project/clipsmith)\n[]()\n[]()\n[](https://github.com/psf/black)\n\n- [ClipSmith](#clipsmith)\n - [Overview](#overview)\n - [Getting started](#getting-started)\n - [CLI](#cli)\n - [Forging clips](#forging-clips)\n - [Concatenating](#concatenating)\n - [Trimming](#trimming)\n - [Rescaling](#rescaling)\n - [Input folder caching](#input-folder-caching)\n - [API](#api)\n - [Context](#context)\n - [Clips](#clips)\n\n## Overview\n\nThis project leverages [FFmpeg](https://ffmpeg.org/) and [doit](https://pydoit.org/) to provide a user-friendly utility for working with video clips and orchestrating pipelines of video editing operations. Clips can be readily concatenated, trimmed, and/or rescaled in a single command. This is especially useful for working with dashcam footage wherein there are many short video files to manage.\n\n## Getting started\n\nFirst, ensure you have ffmpeg installed:\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n\n# Windows\n# Download from https://ffmpeg.org/download.html\n```\n\nThen install using pip:\n\n```bash\npip install clipsmith\n```\n\n## CLI\n\n### Forging clips\n\nThe command `clipsmith forge` is the entry point for creating new clips. Operations for concatenation, duration trimming, duration scaling, resolution scaling, and audio can be specified together in one command.\n\n<!-- include doc/cli/forge.md -->\n```\nUsage: clipsmith forge [OPTIONS] INPUTS... OUTPUT \n \n Create a video from one or more videos with specified operations applied \n \n\u256d\u2500 Arguments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 * inputs INPUTS... One or more paths to input video(s) or folder(s) of videos [default: None] [required] \u2502\n\u2502 * output PATH Path to output video [default: None] [required] \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --trim-start FLOAT Start offset (seconds) in input file(s) [default: None] \u2502\n\u2502 --trim-end FLOAT End offset (seconds) in input file(s) [default: None] \u2502\n\u2502 --dur-scale FLOAT Scale duration by scale factor [default: None] \u2502\n\u2502 --dur-target FLOAT Scale duration to target (seconds) [default: None] \u2502\n\u2502 --res-scale FLOAT Scale resolution by scale factor [default: None] \u2502\n\u2502 --res-target TEXT Scale resolution to target as WIDTH:HEIGHT [default: None] \u2502\n\u2502 --audio --no-audio Whether to pass through audio to output (not yet supported with time scaling) [default: audio] \u2502\n\u2502 --cache --no-cache Whether to store a cache of video metadata in input folders [default: no-cache] \u2502\n\u2502 --log-level TEXT Log level passed to ffmpeg [default: info] \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n```\n\n<!-- include end -->\n\n#### Concatenating\n\nConcatenate multiple clips into a single one:\n\n```bash\n# Combine specific files\nclipsmith forge clip1.mp4 clip2.mp4 combined.mp4\n\n# Combine all clips from a folder\nclipsmith forge input_folder/ combined.mp4\n```\n\nFor any folders passed as inputs, their contents are recursively scanned depth-first to aggregate input videos.\n\n#### Trimming\n\nTrim clips using start and end time offsets:\n\n```bash\n# Trim to specific time range\nclipsmith forge --trim-start 1.0 --trim-end 5.0 input.mp4 output.mp4\n\n# Trim just the start\nclipsmith forge --trim-start 1.0 input.mp4 output.mp4\n\n# Trim just the end\nclipsmith forge --trim-end 5.0 input.mp4 output.mp4\n```\n\n#### Rescaling\n\nRescale video duration and resolution:\n\n```bash\n# Speed up by factor (e.g. 2x faster)\nclipsmith forge --dur-scale 2.0 --no-audio input.mp4 output.mp4\n\n# Slow down by factor (e.g. 2x slower)\nclipsmith forge --dur-scale 0.5 --no-audio input.mp4 output.mp4\n\n# Rescale duration to specific value in seconds\nclipsmith forge --dur-target 60.0 --no-audio input.mp4 output.mp4\n\n# Rescale resolution by factor\nclipsmith forge --res-scale 0.5 input.mp4 output.mp4\n\n# Rescale resolution to specific value as WIDTH:HEIGHT\nclipsmith forge --res-target 480:270 input.mp4 output.mp4\n```\n\n<!-- TODO:\n### Clip playbooks\n-->\n\n### Input folder caching\n\nFor input folders with many videos, the process of scanning and validating input files can be time-consuming. In such cases, pass `--cache` to cache video metadata per folder. In case of multiple or interrupted invocations, ClipSmith will use this cache to quickly begin its work.\n\n## API\n\n### Context\n\nThe `Context` class provides the main interface for working with clips. It implements a task orchestration pattern using `doit`:\n\n```python\nfrom pathlib import Path\nfrom clipsmith import Context\n\n# Create a context\ncontext = Context()\n\n# Forge a new clip from input files\ncontext.forge(\"output.mp4\", [Path(\"input1.mp4\"), Path(\"input2.mp4\")])\n\n# Execute all pending operations\ncontext.doit()\n```\n\n### Clips\n\nClips can be manipulated using operation parameters for duration and resolution. A clip can be \"reforged\" into another clip, with `doit` managing orchestration of `ffmpeg` invocations.\n\n```python\nfrom clipsmith import (\n Context, \n OperationParams,\n DurationParams,\n ResolutionParams\n)\n\ncontext = Context()\ninputs = [Path(\"input1.mp4\"), Path(\"input2.mp4\")]\n\n# Trimming\nclip1 = context.forge(\n \"output1.mp4\",\n inputs,\n OperationParams(\n duration_params=DurationParams(\n trim_start=1.0, # Start at 1 second\n trim_end=5.0, # End at 5 seconds\n ),\n )\n)\n\n# Time scaling\nclip2 = context.forge(\n \"output2.mp4\",\n inputs,\n OperationParams(\n duration_params=DurationParams(\n scale=2.0, # Speed up by 2x\n ),\n audio=False\n )\n)\n\n# Resolution scaling\nclip3 = context.forge(\n \"output3.mp4\", \n inputs,\n OperationParams(\n resolution_params=ResolutionParams(\n target=(480, 270) # Scale to specific resolution\n )\n )\n)\n\n# Chain operations by reforging trimmed clip\nclip4 = clip1.reforge(\n \"output4.mp4\",\n OperationParams(\n resolution_params=ResolutionParams(\n scale=0.5 # Scale resolution by factor\n )\n )\n)\n\n# Execute all operations\ncontext.doit()\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "Utility to work with video clips, especially suited for creating timelapses from dashcam footage",
"version": "0.1.4",
"project_urls": {
"Homepage": "https://github.com/mm21/clipsmith"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "478ea0453078c5b4971232757327fa47279f3cb6678de0ea4803fc3bccee51aa",
"md5": "0034fcd770e2f5d25952d07305024ba3",
"sha256": "0e71db31612063d991ef53c06503d2b5a7349a7f3fda5533f70fd59336378ef6"
},
"downloads": -1,
"filename": "clipsmith-0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0034fcd770e2f5d25952d07305024ba3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.14,>=3.11",
"size": 16819,
"upload_time": "2024-12-17T05:10:30",
"upload_time_iso_8601": "2024-12-17T05:10:30.138861Z",
"url": "https://files.pythonhosted.org/packages/47/8e/a0453078c5b4971232757327fa47279f3cb6678de0ea4803fc3bccee51aa/clipsmith-0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "51e512a104c13457f69a0a6fa2e6bbcfde1e4f6b06fb8c07c409e4b7d5309719",
"md5": "419179d5eec3908536b2ef2b14417064",
"sha256": "b6e7d7091ceb1bf3d0fe5a9b6dc13133dcb4448c6bd960f080dbab38cc172102"
},
"downloads": -1,
"filename": "clipsmith-0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "419179d5eec3908536b2ef2b14417064",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.14,>=3.11",
"size": 15135,
"upload_time": "2024-12-17T05:10:33",
"upload_time_iso_8601": "2024-12-17T05:10:33.471321Z",
"url": "https://files.pythonhosted.org/packages/51/e5/12a104c13457f69a0a6fa2e6bbcfde1e4f6b06fb8c07c409e4b7d5309719/clipsmith-0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-17 05:10:33",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "mm21",
"github_project": "clipsmith",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"tox": true,
"lcname": "clipsmith"
}