Metadata-Version: 2.4
Name: concinno-skills-video
Version: 0.1.0
Summary: YouTube + video workflow agent skills for Concinno — yt-dlp (Unlicense), youtube-transcript-api (MIT), moviepy (MIT). Requires system ffmpeg.
Project-URL: Homepage, https://github.com/aiking931931/concinno
Project-URL: Issues, https://github.com/aiking931931/concinno/issues
Project-URL: Changelog, https://github.com/aiking931931/concinno/blob/main/projects/concinno-skills-video/CHANGELOG.md
Author-email: "AI King (Chen-Xuan Wang)" <me@ai-king.dev>
License-Expression: Apache-2.0
Keywords: agent,concinno,moviepy,skills,transcript,video,youtube,yt-dlp
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: concinno>=2.15.1
Requires-Dist: moviepy>=2.0
Requires-Dist: youtube-transcript-api>=0.6
Requires-Dist: yt-dlp>=2024.10
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.7; extra == 'dev'
Description-Content-Type: text/markdown

# concinno-skills-video

YouTube + video workflow agent skills for
[Concinno](https://pypi.org/project/concinno/).

## Status

MVP (0.1.0) — three tools covering the public-video workflow end-to-end:

| Tool | Library | Purpose |
|------|---------|---------|
| `YouTubeDownload` | [`yt-dlp`](https://github.com/yt-dlp/yt-dlp) (Unlicense) | download video / extract audio / fetch metadata |
| `YouTubeTranscript` | [`youtube-transcript-api`](https://github.com/jdepoix/youtube-transcript-api) (MIT) | fetch YouTube-provided captions (no STT) |
| `VideoEdit` | [`moviepy`](https://zulko.github.io/moviepy/) (MIT) | subclip / concat / thumbnail |

Private / playlist / upload support is deliberately **not** in 0.1.0 —
those paths need OAuth and will land in a later minor release. The
`_auth.py` placeholder exists so 0.2.0 can add them without reshuffling
the package layout.

## Install

```bash
pip install concinno-skills-video
```

You **must** also install `ffmpeg` — the package does not bundle it.

- macOS: `brew install ffmpeg`
- Debian / Ubuntu: `sudo apt install ffmpeg`
- Windows: `choco install ffmpeg` or download from <https://ffmpeg.org/>

Each tool checks `shutil.which("ffmpeg")` on first use and returns a
structured error if it's missing rather than crashing.

## Legal & operational notes

- **yt-dlp is Unlicense** — you can embed it freely, but **downloading
  YouTube content may still violate YouTube's Terms of Service and your
  local copyright law**. This library does not grant you permission to
  download content you don't have rights to. DMCA takedowns, IP bans,
  and content-policy enforcement are entirely downstream of this code.
- **youtube-transcript-api** hits YouTube's public caption endpoints;
  sustained bursty use can trigger IP throttling or short bans. The
  tool is marked `is_concurrency_safe = False` for this reason.
- **Size cap**: `YouTubeDownload` refuses any request whose expected
  filesize exceeds 500 MB unless you pass `force=True`. This is a
  guardrail to prevent agent-triggered accidental bandwidth burn, not a
  security boundary.
- **Path containment**: all file paths (`output_dir`, `input_path`,
  `output_path`) must resolve under `Path.home()` or `Path.cwd()` —
  arbitrary absolute paths are rejected (Concinno BoundaryGuard rule).

## Usage via Concinno `ToolRegistry`

When the consumer sets `CONCINNO_LOAD_PLUGINS=1`, the default registry
auto-mounts all three tools:

```python
import os
os.environ["CONCINNO_LOAD_PLUGINS"] = "1"

from concinno.tools.registry import get_default_registry

reg = get_default_registry()
assert {"YouTubeDownload", "YouTubeTranscript", "VideoEdit"} <= set(reg.list_deferred())

tool = reg.get("YouTubeTranscript")
tool.call(action="get", video_id="dQw4w9WgXcQ", lang="en")
```

## Direct Python usage

```python
from concinno_skills_video import (
    YouTubeDownload, YouTubeTranscript, VideoEdit,
)

# Metadata only (no download)
info = YouTubeDownload().call(
    action="info",
    url="https://youtu.be/dQw4w9WgXcQ",
)

# Audio extract
YouTubeDownload().call(
    action="audio",
    url="https://youtu.be/dQw4w9WgXcQ",
    output_dir="~/Downloads",
)

# Transcript
segs = YouTubeTranscript().call(
    action="get",
    video_id="dQw4w9WgXcQ",
    lang="en",
)

# Edit: cut a segment
VideoEdit().call(
    action="subclip",
    input_path="~/Downloads/input.mp4",
    output_path="~/Downloads/cut.mp4",
    start=10.0,
    end=20.0,
)

# Edit: concat
VideoEdit().call(
    action="concat",
    input_paths=["~/Downloads/a.mp4", "~/Downloads/b.mp4"],
    output_path="~/Downloads/merged.mp4",
)

# Edit: extract a frame as PNG/JPEG
VideoEdit().call(
    action="thumbnail",
    input_path="~/Downloads/input.mp4",
    output_path="~/Downloads/thumb.png",
    time=5.0,
)
```

All methods return either `{"ok": True, ...}` on success or
`{"error": "..."}` on failure — same shape as the other Concinno
built-in tools.

## License

Apache-2.0. See `LICENSE` in the Concinno monorepo.
