Metadata-Version: 2.4
Name: cliprange
Version: 0.6.0
Summary: Plan media time ranges into byte ranges and fetch partial media data.
Project-URL: Homepage, https://github.com/buzhidaoqusm/cliprange
Project-URL: Repository, https://github.com/buzhidaoqusm/cliprange
Project-URL: Issues, https://github.com/buzhidaoqusm/cliprange/issues
Project-URL: Changelog, https://github.com/buzhidaoqusm/cliprange/blob/master/CHANGELOG.md
Author: cliprange contributors
License-Expression: MIT
License-File: LICENSE
Keywords: byte-range,ffmpeg,http-range,media,mp4,torrent,video
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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
Classifier: Typing :: Typed
Requires-Python: >=3.11
Provides-Extra: dev
Requires-Dist: build<2.0.0,>=1.2.0; extra == 'dev'
Requires-Dist: pillow<13.0.0,>=10.0.0; extra == 'dev'
Requires-Dist: pytest<9.0.0,>=8.0.0; extra == 'dev'
Requires-Dist: ruff<1.0.0,>=0.5.0; extra == 'dev'
Requires-Dist: twine<7.0.0,>=5.0.0; extra == 'dev'
Provides-Extra: torrent
Requires-Dist: libtorrent<2.1.0,>=2.0.13; extra == 'torrent'
Description-Content-Type: text/markdown

# cliprange

`cliprange` maps media time ranges to byte ranges and provides optional fetchers for partial media workflows.

The first version focuses on MP4/M4V/MOV planning and libtorrent-based piece fetching. It is intentionally independent from QQBot, NapCat, OneBot, ZIP packaging, and chat-bot task state.

## Install

For planner-only usage:

```powershell
pip install cliprange
```

Torrent support requires the optional `torrent` extra:

```powershell
pip install "cliprange[torrent]"
```

Clip extraction requires `ffmpeg` and `ffprobe` to be available on `PATH`.

For local development from a checkout:

```powershell
pip install -e ".[dev,torrent]"
```

## Example

```python
from cliprange import ClipRequest, plan_mp4_clip_ranges

plan = plan_mp4_clip_ranges(
    "video.mp4",
    ClipRequest(start_seconds=600, duration_seconds=120),
)

print(plan.ranges)
print(plan.estimated_bytes)
```

## HTTP Range Example

```python
from cliprange import ClipRequest, HttpRangeFetcher, plan_mp4_clip_ranges

plan = plan_mp4_clip_ranges(
    "video.mp4",
    ClipRequest(start_seconds=600, duration_seconds=120),
)

fetcher = HttpRangeFetcher("https://example.com/video.mp4")
result = await fetcher.fetch_ranges(plan.ranges, "partial-video.mp4")

print(result.bytes_written)
```

The HTTP fetcher requires the server to support `Range` requests and return `206 Partial Content`. It will not fall back to downloading a full file when a server ignores the `Range` header.

## CLI

Editable installs expose three commands:

```powershell
cliprange-plan video.mp4 --start 00:10:00 --duration 00:02:00
cliprange-clip video.mp4 --start 00:10:00 --duration 00:02:00 --out clip.mp4
cliprange-torrent "magnet:?xt=..." --file-largest-video --middle 120 --out clip.mp4
cliprange-preview "magnet:?xt=..." --time 00:10:23 --out preview.jpg
```

`cliprange-torrent` requires the optional `torrent` extra and only downloads pieces needed for the selected clip. Users are responsible for accessing only media they are authorized to use.

`cliprange-preview` also requires the optional `torrent` extra. It currently supports MP4/M4V/MOV files and writes one JPEG frame for the requested timestamp.

## Magnet Preview Example

```python
from cliprange import FramePreviewRequest, TorrentConfig, preview_frame_from_magnet

result = await preview_frame_from_magnet(
    "magnet:?xt=...",
    request=FramePreviewRequest(timestamp_seconds=623.0),
    output_path="preview.jpg",
    config=TorrentConfig(download_dir="downloads"),
)

print(result.output_path)
print(result.piece_indexes)
print(result.cache_key)
```

## Real-World Smoke Test

The default test suite does not access external networks. To validate the library against a real public MP4 URL, run:

```powershell
python scripts/smoke_real_world.py
```

The smoke script checks HTTP Range support, downloads a small public MP4, plans byte ranges, fetches those ranges, runs the CLI planner, extracts a short clip, and verifies the output duration.

To run the same check through pytest:

```powershell
$env:CLIPRANGE_RUN_REAL_WORLD = "1"
pytest -m integration
```

## Public API

The stable import surface for the current internal version is the package root:

```python
from cliprange import (
    ByteRange,
    ClipPlan,
    ClipRangeError,
    ClipRequest,
    FfmpegError,
    FramePreviewError,
    FramePreviewPlan,
    FramePreviewRequest,
    FramePreviewResult,
    HttpRangeConfig,
    HttpRangeError,
    HttpRangeFetcher,
    HttpRangeFetchResult,
    MediaRangeError,
    Mp4IndexError,
    PieceDownloadProgress,
    PreviewDownloadTooLargeError,
    TorrentConfig,
    TorrentFile,
    TorrentMetadata,
    TorrentRangeError,
    TorrentRangeFetcher,
    UnsupportedPreviewFormatError,
    extract_clip_to_mp4,
    extract_frame_to_jpeg,
    is_magnet_uri,
    magnet_info_hash,
    piece_indexes_for_ranges,
    plan_mp4_clip_ranges,
    plan_mp4_frame_preview_ranges,
    preview_frame_from_magnet,
    preview_frame_from_torrent,
    probe_duration_seconds,
    probe_piece_indexes,
    ratio_buffer_piece_indexes,
)
```

Internal MP4 box parsing helpers are intentionally private and may change without notice.

## Scope

- MP4/M4V/MOV time range planning.
- Byte ranges to torrent piece indexes.
- HTTP Range fetching for planned byte ranges.
- Optional libtorrent metadata and piece fetching.
- Optional ffmpeg helpers for clip extraction.
- Optional magnet/torrent JPEG preview frame extraction for MP4/M4V/MOV files.

Future versions may add object-storage fetchers.

## Boundaries

This library does not choose application-specific defaults such as "middle two minutes", create ZIP files, upload files, store bot task state, or format chat messages. Applications should keep those decisions in their own code.

## Roadmap

The plan for turning this internal prototype into a publishable library is tracked in [docs/roadmap-to-1.0.md](docs/roadmap-to-1.0.md).

## Documentation

- [API reference](docs/api-reference.md)
- [Limitations](docs/limitations.md)
- [Troubleshooting](docs/troubleshooting.md)
- [Responsible use](docs/responsible-use.md)
- [Versioning](docs/versioning.md)
- [Publishing](docs/publishing.md)
