mediasense 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mediasense-0.4.1/.gitattributes +8 -0
- mediasense-0.4.1/.github/workflows/ci.yml +34 -0
- mediasense-0.4.1/.github/workflows/release.yml +58 -0
- mediasense-0.4.1/.gitignore +14 -0
- mediasense-0.4.1/LICENSE +21 -0
- mediasense-0.4.1/PKG-INFO +263 -0
- mediasense-0.4.1/README.md +219 -0
- mediasense-0.4.1/README.pt-BR.md +137 -0
- mediasense-0.4.1/docs/demo.gif +0 -0
- mediasense-0.4.1/docs/make_demo.py +165 -0
- mediasense-0.4.1/install.ps1 +123 -0
- mediasense-0.4.1/install.sh +67 -0
- mediasense-0.4.1/mcpb/.mcpbignore +5 -0
- mediasense-0.4.1/mcpb/icon.png +0 -0
- mediasense-0.4.1/mcpb/make_icon.py +47 -0
- mediasense-0.4.1/mcpb/manifest.json +69 -0
- mediasense-0.4.1/mcpb/pyproject.toml +6 -0
- mediasense-0.4.1/mcpb/src/server.py +6 -0
- mediasense-0.4.1/pyproject.toml +61 -0
- mediasense-0.4.1/skill/mediasense/SKILL.md +84 -0
- mediasense-0.4.1/src/mediasense/__init__.py +5 -0
- mediasense-0.4.1/src/mediasense/__main__.py +5 -0
- mediasense-0.4.1/src/mediasense/api.py +278 -0
- mediasense-0.4.1/src/mediasense/cli.py +372 -0
- mediasense-0.4.1/src/mediasense/edit.py +411 -0
- mediasense-0.4.1/src/mediasense/export.py +270 -0
- mediasense-0.4.1/src/mediasense/fetch.py +204 -0
- mediasense-0.4.1/src/mediasense/jobs.py +124 -0
- mediasense-0.4.1/src/mediasense/mcp_server.py +480 -0
- mediasense-0.4.1/src/mediasense/media.py +338 -0
- mediasense-0.4.1/src/mediasense/models.py +239 -0
- mediasense-0.4.1/src/mediasense/setup.py +264 -0
- mediasense-0.4.1/src/mediasense/skill.py +55 -0
- mediasense-0.4.1/src/mediasense/transcribe.py +514 -0
- mediasense-0.4.1/src/mediasense/video.py +159 -0
- mediasense-0.4.1/tests/conftest.py +89 -0
- mediasense-0.4.1/tests/test_backends.py +239 -0
- mediasense-0.4.1/tests/test_interfaces.py +118 -0
- mediasense-0.4.1/tests/test_jobs.py +72 -0
- mediasense-0.4.1/tests/test_media.py +181 -0
- mediasense-0.4.1/tests/test_setup.py +117 -0
- mediasense-0.4.1/tests/test_skill.py +54 -0
- mediasense-0.4.1/tests/test_text.py +155 -0
- mediasense-0.4.1/tests/test_understand.py +202 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
15
|
+
python: ["3.10", "3.13"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v5
|
|
18
|
+
- uses: actions/setup-python@v6
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python }}
|
|
21
|
+
|
|
22
|
+
- name: Install FFmpeg (Linux)
|
|
23
|
+
if: runner.os == 'Linux'
|
|
24
|
+
run: sudo apt-get update && sudo apt-get install -y ffmpeg
|
|
25
|
+
- name: Install FFmpeg (macOS)
|
|
26
|
+
if: runner.os == 'macOS'
|
|
27
|
+
run: brew install ffmpeg
|
|
28
|
+
- name: Install FFmpeg (Windows)
|
|
29
|
+
if: runner.os == 'Windows'
|
|
30
|
+
run: choco install ffmpeg -y --no-progress
|
|
31
|
+
|
|
32
|
+
- run: pip install -e ".[dev,mcp]"
|
|
33
|
+
- run: ruff check src tests
|
|
34
|
+
- run: pytest -q
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Push a tag like v0.4.1 to publish:
|
|
4
|
+
# - the Python package on PyPI (trusted publishing, see README "Releasing")
|
|
5
|
+
# - a GitHub release with the wheel, the Claude skill zip and the Claude Desktop extension (.mcpb)
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
tags: ["v*"]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
release:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write # create the GitHub release
|
|
15
|
+
id-token: write # PyPI trusted publishing
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v5
|
|
18
|
+
- uses: actions/setup-python@v6
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
- uses: actions/setup-node@v5
|
|
22
|
+
with:
|
|
23
|
+
node-version: "22"
|
|
24
|
+
|
|
25
|
+
- name: Check the tag matches the package version
|
|
26
|
+
run: |
|
|
27
|
+
V=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
|
|
28
|
+
test "v$V" = "$GITHUB_REF_NAME" || { echo "tag $GITHUB_REF_NAME != version $V in pyproject.toml"; exit 1; }
|
|
29
|
+
echo "VERSION=$V" >> "$GITHUB_ENV"
|
|
30
|
+
|
|
31
|
+
- name: Build the Python package
|
|
32
|
+
run: pip install build && python -m build
|
|
33
|
+
|
|
34
|
+
- name: Skill zip (upload in Claude → Settings → Skills)
|
|
35
|
+
run: |
|
|
36
|
+
mkdir -p out/skill
|
|
37
|
+
cp -r skill/mediasense out/skill/
|
|
38
|
+
(cd out/skill && zip -r ../mediasense-skill.zip mediasense)
|
|
39
|
+
|
|
40
|
+
- name: Claude Desktop extension (.mcpb)
|
|
41
|
+
run: |
|
|
42
|
+
cp -r mcpb out/ext
|
|
43
|
+
sed -i "s/\"version\": \"0.0.0\"/\"version\": \"$VERSION\"/" out/ext/manifest.json
|
|
44
|
+
sed -i "s/0\.0\.0/$VERSION/g" out/ext/pyproject.toml
|
|
45
|
+
npx -y @anthropic-ai/mcpb validate out/ext/manifest.json
|
|
46
|
+
npx -y @anthropic-ai/mcpb pack out/ext out/mediasense.mcpb
|
|
47
|
+
|
|
48
|
+
- name: Publish to PyPI
|
|
49
|
+
# needs the one-time trusted-publisher setup on pypi.org; the GitHub release is made either way
|
|
50
|
+
continue-on-error: true
|
|
51
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
52
|
+
|
|
53
|
+
- name: Create GitHub release
|
|
54
|
+
env:
|
|
55
|
+
GH_TOKEN: ${{ github.token }}
|
|
56
|
+
run: |
|
|
57
|
+
gh release create "$GITHUB_REF_NAME" dist/*.whl dist/*.tar.gz out/mediasense-skill.zip out/mediasense.mcpb \
|
|
58
|
+
--title "mediasense $GITHUB_REF_NAME" --generate-notes
|
mediasense-0.4.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mediasense contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: mediasense
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Give Claude ears and eyes: understand, summarize and edit audio/video files or links (TikTok, YouTube…) with word-level timestamps. MCP server + CLI, runs locally.
|
|
5
|
+
Project-URL: Homepage, https://github.com/joaoestella/mediasense
|
|
6
|
+
Project-URL: Issues, https://github.com/joaoestella/mediasense/issues
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: claude,ffmpeg,mcp,subtitles,transcription,video editing,whisper,word timestamps
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
14
|
+
Classifier: Topic :: Multimedia :: Video :: Non-Linear Editor
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Requires-Dist: pillow>=9.0
|
|
17
|
+
Provides-Extra: all
|
|
18
|
+
Requires-Dist: faster-whisper>=1.0; extra == 'all'
|
|
19
|
+
Requires-Dist: mcp>=1.2; extra == 'all'
|
|
20
|
+
Requires-Dist: numpy; extra == 'all'
|
|
21
|
+
Requires-Dist: yt-dlp[curl-cffi,default]>=2024.1; extra == 'all'
|
|
22
|
+
Provides-Extra: api
|
|
23
|
+
Requires-Dist: openai>=1.30; extra == 'api'
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: numpy; extra == 'dev'
|
|
26
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
27
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
28
|
+
Provides-Extra: ffmpeg
|
|
29
|
+
Requires-Dist: static-ffmpeg>=2.5; extra == 'ffmpeg'
|
|
30
|
+
Provides-Extra: gpu
|
|
31
|
+
Requires-Dist: nvidia-cublas-cu12; extra == 'gpu'
|
|
32
|
+
Requires-Dist: nvidia-cuda-runtime-cu12; extra == 'gpu'
|
|
33
|
+
Requires-Dist: nvidia-cudnn-cu12<10,>=9; extra == 'gpu'
|
|
34
|
+
Provides-Extra: mcp
|
|
35
|
+
Requires-Dist: mcp>=1.2; extra == 'mcp'
|
|
36
|
+
Provides-Extra: url
|
|
37
|
+
Requires-Dist: yt-dlp[curl-cffi,default]>=2024.1; extra == 'url'
|
|
38
|
+
Provides-Extra: whisper
|
|
39
|
+
Requires-Dist: faster-whisper>=1.0; extra == 'whisper'
|
|
40
|
+
Requires-Dist: numpy; extra == 'whisper'
|
|
41
|
+
Provides-Extra: whisperx
|
|
42
|
+
Requires-Dist: whisperx>=3.1; extra == 'whisperx'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# mediasense
|
|
46
|
+
|
|
47
|
+
**Give Claude ears and eyes.** Paste a TikTok, YouTube or Instagram link (or point at a file) in Claude
|
|
48
|
+
Code or Claude Desktop and ask in plain language. Claude can then summarize the video, explain what
|
|
49
|
+
happens in it, find the moment something is said, or edit it.
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
you: summarize this https://www.tiktok.com/@someone/video/7350…
|
|
53
|
+
you: what does he show at 0:30? and what tool is he talking about?
|
|
54
|
+
you: clean up ~/Desktop/podcast.m4a — remove the "um"s and long pauses
|
|
55
|
+
you: make short captions for ~/Videos/reel.mp4
|
|
56
|
+
you: put intro.mp3 under the first 5 seconds of talk.mp4, ducked
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
<sub>Real output for a 17-second TikTok by @elim.doc, shown with the creator's permission. Regenerate the
|
|
62
|
+
animation with `python docs/make_demo.py`.</sub>
|
|
63
|
+
|
|
64
|
+
mediasense runs **on your computer**: it downloads the link, transcribes speech in ~99 languages with a
|
|
65
|
+
timestamp for every word, picks key frames at scene changes, and hands Claude a transcript, a shot list
|
|
66
|
+
and contact-sheet images. Nothing is uploaded anywhere.
|
|
67
|
+
|
|
68
|
+
[Português 🇧🇷](README.pt-BR.md)
|
|
69
|
+
|
|
70
|
+
## Setup
|
|
71
|
+
|
|
72
|
+
**Windows** – paste in PowerShell:
|
|
73
|
+
|
|
74
|
+
```powershell
|
|
75
|
+
irm https://raw.githubusercontent.com/joaoestella/mediasense/main/install.ps1 | iex
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**macOS / Linux** – paste in a terminal:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
curl -LsSf https://raw.githubusercontent.com/joaoestella/mediasense/main/install.sh | sh
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Then **quit Claude Desktop completely** (tray/menu-bar icon → Quit), open it again and ask
|
|
85
|
+
*"summarize this video: <link>"*. The first transcription downloads the speech model (≈ 500 MB).
|
|
86
|
+
|
|
87
|
+
<details>
|
|
88
|
+
<summary>Prefer to read the script before running it?</summary>
|
|
89
|
+
|
|
90
|
+
```powershell
|
|
91
|
+
irm https://raw.githubusercontent.com/joaoestella/mediasense/main/install.ps1 -OutFile install.ps1
|
|
92
|
+
notepad install.ps1
|
|
93
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
(macOS/Linux: `curl -LsSfO …/install.sh`, read it, then `sh install.sh`.)
|
|
97
|
+
|
|
98
|
+
The installer only installs what is missing — Python 3.12 and FFmpeg via `winget` (Homebrew/apt on
|
|
99
|
+
macOS/Linux) and `pipx` via pip — then `pipx install`s mediasense from this repository and runs
|
|
100
|
+
`mediasense setup`. It stops at the first failed step.
|
|
101
|
+
</details>
|
|
102
|
+
|
|
103
|
+
<details>
|
|
104
|
+
<summary>Manual setup (no script)</summary>
|
|
105
|
+
|
|
106
|
+
```powershell
|
|
107
|
+
winget install ffmpeg # macOS: brew install ffmpeg · Linux: sudo apt install ffmpeg
|
|
108
|
+
python -m pip install --user pipx
|
|
109
|
+
python -m pipx ensurepath # then close and reopen the terminal
|
|
110
|
+
python -m pipx install "mediasense[all]"
|
|
111
|
+
mediasense setup -n # preview what setup will change
|
|
112
|
+
mediasense setup
|
|
113
|
+
mediasense doctor
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Use `python -m pipx …` rather than plain `pipx` right after installing it: the `pipx` command only
|
|
117
|
+
appears on PATH in a new terminal. No Git needed.
|
|
118
|
+
</details>
|
|
119
|
+
|
|
120
|
+
<details>
|
|
121
|
+
<summary>One-click Claude Desktop extension (experimental)</summary>
|
|
122
|
+
|
|
123
|
+
Download **[mediasense.mcpb](https://github.com/joaoestella/mediasense/releases/latest/download/mediasense.mcpb)**
|
|
124
|
+
and double-click it (or drag it into Claude Desktop → Settings → Extensions). No Python, pipx or
|
|
125
|
+
FFmpeg needed: Claude Desktop sets up Python by itself, and FFmpeg is downloaded on first use. The
|
|
126
|
+
first start takes a few minutes while it installs everything. This uses Claude Desktop's new "UV"
|
|
127
|
+
extension type, so if it doesn't work on your version, use the installer above.
|
|
128
|
+
</details>
|
|
129
|
+
|
|
130
|
+
### What `mediasense setup` changes
|
|
131
|
+
|
|
132
|
+
- **Claude Desktop:** adds one entry, `mcpServers.mediasense`, to `claude_desktop_config.json`
|
|
133
|
+
(`%APPDATA%\Claude\` – or `%LOCALAPPDATA%\Claude-Data\claude_…\` for the Microsoft Store app –
|
|
134
|
+
`~/Library/Application Support/Claude/` on macOS, `~/.config/Claude/` on Linux; Claude Desktop →
|
|
135
|
+
Settings → Developer → Edit Config opens the one your app uses). Everything else in the file is kept, and the previous file is saved next to it as
|
|
136
|
+
`claude_desktop_config.json.<date>.bak`. If the file isn't valid JSON, setup stops without touching it.
|
|
137
|
+
- **Claude Code** (if installed): runs `claude mcp add --scope user mediasense -- <path>\mediasense mcp`.
|
|
138
|
+
- Nothing else. `mediasense setup -n` shows the exact changes without making them; `--desktop` or
|
|
139
|
+
`--code` limits it to one app. To undo: remove the `mediasense` entry from the config file and run
|
|
140
|
+
`claude mcp remove mediasense --scope user`.
|
|
141
|
+
|
|
142
|
+
Updating on Windows and pipx says a file "is being used by another process"? Claude Desktop is still
|
|
143
|
+
running the old server: `Get-Process mediasense | Stop-Process -Force`, then install again (the
|
|
144
|
+
installer script does this for you).
|
|
145
|
+
|
|
146
|
+
Something not working? `mediasense doctor` checks FFmpeg, the speech model, the GPU, link downloads and
|
|
147
|
+
the Claude connection.
|
|
148
|
+
|
|
149
|
+
### Teach Claude when to use it (recommended)
|
|
150
|
+
|
|
151
|
+
mediasense comes with a **skill**: a short guide that makes Claude reach for mediasense whenever you
|
|
152
|
+
paste a video link, instead of trying to open the page (TikTok & co. block that).
|
|
153
|
+
|
|
154
|
+
- **Claude Code:** installed automatically by `mediasense setup`.
|
|
155
|
+
- **Claude Desktop / claude.ai:** download
|
|
156
|
+
[mediasense-skill.zip](https://github.com/joaoestella/mediasense/releases/latest/download/mediasense-skill.zip)
|
|
157
|
+
(the installer also saves it to `Downloads/mediasense/`), then in Claude open **Settings → Skills** and
|
|
158
|
+
upload it. One time only; it syncs to all your devices.
|
|
159
|
+
|
|
160
|
+
> **Note:** Claude Desktop sends files you attach in the chat to the model, not to your computer, so give
|
|
161
|
+
> mediasense a **link or a file path** instead (in Claude Code you can drag the file into the terminal).
|
|
162
|
+
|
|
163
|
+
### Slash commands
|
|
164
|
+
|
|
165
|
+
The server adds ready-made prompts. In Claude Code they appear as `/mcp__mediasense__summarize` and so on.
|
|
166
|
+
|
|
167
|
+
| Prompt | Does |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `summarize` | gist, key points with timestamps, steps, names and links, call to action |
|
|
170
|
+
| `explain_video` | shot-by-shot explanation, plus how the video is built (hook, structure) |
|
|
171
|
+
| `clean_up` | remove fillers and long pauses, show the plan first, render after your OK |
|
|
172
|
+
| `subtitles` | SRT captions, standard or short 1–3-word style for vertical video |
|
|
173
|
+
|
|
174
|
+
### Tools Claude gets
|
|
175
|
+
|
|
176
|
+
| Tool | What it does |
|
|
177
|
+
|---|---|
|
|
178
|
+
| `understand_media` | **one call**: download link, transcribe, key frames + speech per shot, post title/description |
|
|
179
|
+
| `transcribe` | speech → `<file>.transcript.json` with word timestamps; `vocabulary` fixes brand names |
|
|
180
|
+
| `read_transcript`, `search_transcript` | read a time range or find every time a phrase is said |
|
|
181
|
+
| `plan_edit`, `render_edit` | cut phrases, passages, fillers, silences or ranges; preview, then render |
|
|
182
|
+
| `export_transcript` | SRT, VTT, TXT, CSV, JSON |
|
|
183
|
+
| `place_audio` | insert a clip at a timestamp (mix / duck / replace) |
|
|
184
|
+
| `watch_video`, `get_frame` | contact sheets, or one frame at a given time |
|
|
185
|
+
| `media_info` | duration, resolution, fps, streams |
|
|
186
|
+
| `check_job` | result of long work: new videos and the first run reply "still working" and finish in the background |
|
|
187
|
+
|
|
188
|
+
Long work never hits Claude's tool time limit: if a video takes more than ~30 s (a long video on a
|
|
189
|
+
CPU, or the very first run while the speech model downloads), the tool answers "still working" with a
|
|
190
|
+
progress percentage and Claude checks back with `check_job` until it's done.
|
|
191
|
+
|
|
192
|
+
All tools accept a file path **or a link**. Links are downloaded once to `~/Downloads/mediasense`
|
|
193
|
+
(change with `MEDIASENSE_HOME`) and reused.
|
|
194
|
+
|
|
195
|
+
## Command line
|
|
196
|
+
|
|
197
|
+
Everything also works without Claude:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
mediasense understand "https://youtu.be/…" # transcript + shots + metadata, as text
|
|
201
|
+
mediasense transcribe talk.mp4 -l pt --vocab "Cloudflare, Claude" --also srt
|
|
202
|
+
mediasense search talk.transcript.json "next quarter"
|
|
203
|
+
mediasense edit talk.mp4 --fillers --silences 0.7 -n # -n = only show the plan
|
|
204
|
+
mediasense edit talk.mp4 --fillers --silences 0.7 --srt --edl --fcpxml
|
|
205
|
+
mediasense edit talk.mp4 --cut-between "let me check" "okay so" --cut-range 12:03-12:40
|
|
206
|
+
mediasense export talk.transcript.json captions.srt --words-per-cue 2
|
|
207
|
+
mediasense place video.mp4 voiceover.wav --at 0:12.5 --mode duck
|
|
208
|
+
mediasense storyboard reel.mp4
|
|
209
|
+
mediasense fetch "https://www.tiktok.com/@…/video/…"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Edits never touch the original: results are written as `<name>.edited.*` / `<name>.placed.*`.
|
|
213
|
+
EDL opens in Premiere, Resolve and Avid; FCPXML in Final Cut Pro and Resolve.
|
|
214
|
+
|
|
215
|
+
## Good to know
|
|
216
|
+
|
|
217
|
+
- **Names and jargon.** Whisper may write "Cloud Fair" for Cloudflare. Pass `--vocab` (Claude does this
|
|
218
|
+
automatically when it can infer the names from the title or the screen).
|
|
219
|
+
- **Fillers.** Whisper tends to leave hesitations out; transcribe with `--verbatim` when you want to cut
|
|
220
|
+
them. Real words are protected per language ("um" is an article in Portuguese, so it is never cut
|
|
221
|
+
there). Ambiguous words like "like", "tipo" or "né" are only removed if you list them.
|
|
222
|
+
- **Speed.** Everything works on a plain CPU: short clips take seconds, a few minutes of audio takes
|
|
223
|
+
about as long as the audio with the default `small` model (`base` is faster, `medium` more accurate).
|
|
224
|
+
No GPU? `--backend openai` sends the audio to an OpenAI-compatible transcription API instead
|
|
225
|
+
(fast on any machine, but the audio leaves your computer).
|
|
226
|
+
- **NVIDIA GPU (optional, much faster).** mediasense uses it automatically once the CUDA libraries are
|
|
227
|
+
present; no CUDA toolkit needed:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
python -m pipx inject mediasense nvidia-cublas-cu12 "nvidia-cudnn-cu12>=9,<10" nvidia-cuda-runtime-cu12
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
(≈ 1.5 GB; needs a driver that supports CUDA 12 – `mediasense doctor` checks both). Restart Claude
|
|
234
|
+
Desktop afterwards.
|
|
235
|
+
- **Word timing** is approximate (0.1–0.2 s). For tighter cuts and speaker labels use
|
|
236
|
+
`--backend whisperx` (`pip install "mediasense[whisperx]"`).
|
|
237
|
+
- Downloading from links follows each site's terms. Use it for content you're allowed to download.
|
|
238
|
+
|
|
239
|
+
## Development
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
git clone https://github.com/joaoestella/mediasense && cd mediasense
|
|
243
|
+
pip install -e ".[dev,mcp]"
|
|
244
|
+
pytest
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The tests build synthetic audio/video with FFmpeg and use fake model and downloader libraries, so they
|
|
248
|
+
run in seconds with nothing to download. Ideas welcome: more filler words for your language, a
|
|
249
|
+
one-click Claude Desktop extension (`.mcpb`), and a GUI.
|
|
250
|
+
|
|
251
|
+
## Releasing
|
|
252
|
+
|
|
253
|
+
1. Bump `version` in `pyproject.toml` and `src/mediasense/__init__.py`, commit.
|
|
254
|
+
2. `git tag vX.Y.Z && git push origin vX.Y.Z`. The Release workflow publishes to PyPI and creates a
|
|
255
|
+
GitHub release with the wheel, `mediasense-skill.zip` and `mediasense.mcpb`.
|
|
256
|
+
|
|
257
|
+
One-time PyPI setup (trusted publishing, no token): on pypi.org → *Your account → Publishing → Add a
|
|
258
|
+
new pending publisher*: project `mediasense`, owner `joaoestella`, repository `mediasense`, workflow
|
|
259
|
+
`release.yml`, environment left empty.
|
|
260
|
+
|
|
261
|
+
## License
|
|
262
|
+
|
|
263
|
+
MIT
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# mediasense
|
|
2
|
+
|
|
3
|
+
**Give Claude ears and eyes.** Paste a TikTok, YouTube or Instagram link (or point at a file) in Claude
|
|
4
|
+
Code or Claude Desktop and ask in plain language. Claude can then summarize the video, explain what
|
|
5
|
+
happens in it, find the moment something is said, or edit it.
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
you: summarize this https://www.tiktok.com/@someone/video/7350…
|
|
9
|
+
you: what does he show at 0:30? and what tool is he talking about?
|
|
10
|
+
you: clean up ~/Desktop/podcast.m4a — remove the "um"s and long pauses
|
|
11
|
+
you: make short captions for ~/Videos/reel.mp4
|
|
12
|
+
you: put intro.mp3 under the first 5 seconds of talk.mp4, ducked
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
<sub>Real output for a 17-second TikTok by @elim.doc, shown with the creator's permission. Regenerate the
|
|
18
|
+
animation with `python docs/make_demo.py`.</sub>
|
|
19
|
+
|
|
20
|
+
mediasense runs **on your computer**: it downloads the link, transcribes speech in ~99 languages with a
|
|
21
|
+
timestamp for every word, picks key frames at scene changes, and hands Claude a transcript, a shot list
|
|
22
|
+
and contact-sheet images. Nothing is uploaded anywhere.
|
|
23
|
+
|
|
24
|
+
[Português 🇧🇷](README.pt-BR.md)
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
**Windows** – paste in PowerShell:
|
|
29
|
+
|
|
30
|
+
```powershell
|
|
31
|
+
irm https://raw.githubusercontent.com/joaoestella/mediasense/main/install.ps1 | iex
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**macOS / Linux** – paste in a terminal:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
curl -LsSf https://raw.githubusercontent.com/joaoestella/mediasense/main/install.sh | sh
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Then **quit Claude Desktop completely** (tray/menu-bar icon → Quit), open it again and ask
|
|
41
|
+
*"summarize this video: <link>"*. The first transcription downloads the speech model (≈ 500 MB).
|
|
42
|
+
|
|
43
|
+
<details>
|
|
44
|
+
<summary>Prefer to read the script before running it?</summary>
|
|
45
|
+
|
|
46
|
+
```powershell
|
|
47
|
+
irm https://raw.githubusercontent.com/joaoestella/mediasense/main/install.ps1 -OutFile install.ps1
|
|
48
|
+
notepad install.ps1
|
|
49
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
(macOS/Linux: `curl -LsSfO …/install.sh`, read it, then `sh install.sh`.)
|
|
53
|
+
|
|
54
|
+
The installer only installs what is missing — Python 3.12 and FFmpeg via `winget` (Homebrew/apt on
|
|
55
|
+
macOS/Linux) and `pipx` via pip — then `pipx install`s mediasense from this repository and runs
|
|
56
|
+
`mediasense setup`. It stops at the first failed step.
|
|
57
|
+
</details>
|
|
58
|
+
|
|
59
|
+
<details>
|
|
60
|
+
<summary>Manual setup (no script)</summary>
|
|
61
|
+
|
|
62
|
+
```powershell
|
|
63
|
+
winget install ffmpeg # macOS: brew install ffmpeg · Linux: sudo apt install ffmpeg
|
|
64
|
+
python -m pip install --user pipx
|
|
65
|
+
python -m pipx ensurepath # then close and reopen the terminal
|
|
66
|
+
python -m pipx install "mediasense[all]"
|
|
67
|
+
mediasense setup -n # preview what setup will change
|
|
68
|
+
mediasense setup
|
|
69
|
+
mediasense doctor
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Use `python -m pipx …` rather than plain `pipx` right after installing it: the `pipx` command only
|
|
73
|
+
appears on PATH in a new terminal. No Git needed.
|
|
74
|
+
</details>
|
|
75
|
+
|
|
76
|
+
<details>
|
|
77
|
+
<summary>One-click Claude Desktop extension (experimental)</summary>
|
|
78
|
+
|
|
79
|
+
Download **[mediasense.mcpb](https://github.com/joaoestella/mediasense/releases/latest/download/mediasense.mcpb)**
|
|
80
|
+
and double-click it (or drag it into Claude Desktop → Settings → Extensions). No Python, pipx or
|
|
81
|
+
FFmpeg needed: Claude Desktop sets up Python by itself, and FFmpeg is downloaded on first use. The
|
|
82
|
+
first start takes a few minutes while it installs everything. This uses Claude Desktop's new "UV"
|
|
83
|
+
extension type, so if it doesn't work on your version, use the installer above.
|
|
84
|
+
</details>
|
|
85
|
+
|
|
86
|
+
### What `mediasense setup` changes
|
|
87
|
+
|
|
88
|
+
- **Claude Desktop:** adds one entry, `mcpServers.mediasense`, to `claude_desktop_config.json`
|
|
89
|
+
(`%APPDATA%\Claude\` – or `%LOCALAPPDATA%\Claude-Data\claude_…\` for the Microsoft Store app –
|
|
90
|
+
`~/Library/Application Support/Claude/` on macOS, `~/.config/Claude/` on Linux; Claude Desktop →
|
|
91
|
+
Settings → Developer → Edit Config opens the one your app uses). Everything else in the file is kept, and the previous file is saved next to it as
|
|
92
|
+
`claude_desktop_config.json.<date>.bak`. If the file isn't valid JSON, setup stops without touching it.
|
|
93
|
+
- **Claude Code** (if installed): runs `claude mcp add --scope user mediasense -- <path>\mediasense mcp`.
|
|
94
|
+
- Nothing else. `mediasense setup -n` shows the exact changes without making them; `--desktop` or
|
|
95
|
+
`--code` limits it to one app. To undo: remove the `mediasense` entry from the config file and run
|
|
96
|
+
`claude mcp remove mediasense --scope user`.
|
|
97
|
+
|
|
98
|
+
Updating on Windows and pipx says a file "is being used by another process"? Claude Desktop is still
|
|
99
|
+
running the old server: `Get-Process mediasense | Stop-Process -Force`, then install again (the
|
|
100
|
+
installer script does this for you).
|
|
101
|
+
|
|
102
|
+
Something not working? `mediasense doctor` checks FFmpeg, the speech model, the GPU, link downloads and
|
|
103
|
+
the Claude connection.
|
|
104
|
+
|
|
105
|
+
### Teach Claude when to use it (recommended)
|
|
106
|
+
|
|
107
|
+
mediasense comes with a **skill**: a short guide that makes Claude reach for mediasense whenever you
|
|
108
|
+
paste a video link, instead of trying to open the page (TikTok & co. block that).
|
|
109
|
+
|
|
110
|
+
- **Claude Code:** installed automatically by `mediasense setup`.
|
|
111
|
+
- **Claude Desktop / claude.ai:** download
|
|
112
|
+
[mediasense-skill.zip](https://github.com/joaoestella/mediasense/releases/latest/download/mediasense-skill.zip)
|
|
113
|
+
(the installer also saves it to `Downloads/mediasense/`), then in Claude open **Settings → Skills** and
|
|
114
|
+
upload it. One time only; it syncs to all your devices.
|
|
115
|
+
|
|
116
|
+
> **Note:** Claude Desktop sends files you attach in the chat to the model, not to your computer, so give
|
|
117
|
+
> mediasense a **link or a file path** instead (in Claude Code you can drag the file into the terminal).
|
|
118
|
+
|
|
119
|
+
### Slash commands
|
|
120
|
+
|
|
121
|
+
The server adds ready-made prompts. In Claude Code they appear as `/mcp__mediasense__summarize` and so on.
|
|
122
|
+
|
|
123
|
+
| Prompt | Does |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `summarize` | gist, key points with timestamps, steps, names and links, call to action |
|
|
126
|
+
| `explain_video` | shot-by-shot explanation, plus how the video is built (hook, structure) |
|
|
127
|
+
| `clean_up` | remove fillers and long pauses, show the plan first, render after your OK |
|
|
128
|
+
| `subtitles` | SRT captions, standard or short 1–3-word style for vertical video |
|
|
129
|
+
|
|
130
|
+
### Tools Claude gets
|
|
131
|
+
|
|
132
|
+
| Tool | What it does |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `understand_media` | **one call**: download link, transcribe, key frames + speech per shot, post title/description |
|
|
135
|
+
| `transcribe` | speech → `<file>.transcript.json` with word timestamps; `vocabulary` fixes brand names |
|
|
136
|
+
| `read_transcript`, `search_transcript` | read a time range or find every time a phrase is said |
|
|
137
|
+
| `plan_edit`, `render_edit` | cut phrases, passages, fillers, silences or ranges; preview, then render |
|
|
138
|
+
| `export_transcript` | SRT, VTT, TXT, CSV, JSON |
|
|
139
|
+
| `place_audio` | insert a clip at a timestamp (mix / duck / replace) |
|
|
140
|
+
| `watch_video`, `get_frame` | contact sheets, or one frame at a given time |
|
|
141
|
+
| `media_info` | duration, resolution, fps, streams |
|
|
142
|
+
| `check_job` | result of long work: new videos and the first run reply "still working" and finish in the background |
|
|
143
|
+
|
|
144
|
+
Long work never hits Claude's tool time limit: if a video takes more than ~30 s (a long video on a
|
|
145
|
+
CPU, or the very first run while the speech model downloads), the tool answers "still working" with a
|
|
146
|
+
progress percentage and Claude checks back with `check_job` until it's done.
|
|
147
|
+
|
|
148
|
+
All tools accept a file path **or a link**. Links are downloaded once to `~/Downloads/mediasense`
|
|
149
|
+
(change with `MEDIASENSE_HOME`) and reused.
|
|
150
|
+
|
|
151
|
+
## Command line
|
|
152
|
+
|
|
153
|
+
Everything also works without Claude:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
mediasense understand "https://youtu.be/…" # transcript + shots + metadata, as text
|
|
157
|
+
mediasense transcribe talk.mp4 -l pt --vocab "Cloudflare, Claude" --also srt
|
|
158
|
+
mediasense search talk.transcript.json "next quarter"
|
|
159
|
+
mediasense edit talk.mp4 --fillers --silences 0.7 -n # -n = only show the plan
|
|
160
|
+
mediasense edit talk.mp4 --fillers --silences 0.7 --srt --edl --fcpxml
|
|
161
|
+
mediasense edit talk.mp4 --cut-between "let me check" "okay so" --cut-range 12:03-12:40
|
|
162
|
+
mediasense export talk.transcript.json captions.srt --words-per-cue 2
|
|
163
|
+
mediasense place video.mp4 voiceover.wav --at 0:12.5 --mode duck
|
|
164
|
+
mediasense storyboard reel.mp4
|
|
165
|
+
mediasense fetch "https://www.tiktok.com/@…/video/…"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Edits never touch the original: results are written as `<name>.edited.*` / `<name>.placed.*`.
|
|
169
|
+
EDL opens in Premiere, Resolve and Avid; FCPXML in Final Cut Pro and Resolve.
|
|
170
|
+
|
|
171
|
+
## Good to know
|
|
172
|
+
|
|
173
|
+
- **Names and jargon.** Whisper may write "Cloud Fair" for Cloudflare. Pass `--vocab` (Claude does this
|
|
174
|
+
automatically when it can infer the names from the title or the screen).
|
|
175
|
+
- **Fillers.** Whisper tends to leave hesitations out; transcribe with `--verbatim` when you want to cut
|
|
176
|
+
them. Real words are protected per language ("um" is an article in Portuguese, so it is never cut
|
|
177
|
+
there). Ambiguous words like "like", "tipo" or "né" are only removed if you list them.
|
|
178
|
+
- **Speed.** Everything works on a plain CPU: short clips take seconds, a few minutes of audio takes
|
|
179
|
+
about as long as the audio with the default `small` model (`base` is faster, `medium` more accurate).
|
|
180
|
+
No GPU? `--backend openai` sends the audio to an OpenAI-compatible transcription API instead
|
|
181
|
+
(fast on any machine, but the audio leaves your computer).
|
|
182
|
+
- **NVIDIA GPU (optional, much faster).** mediasense uses it automatically once the CUDA libraries are
|
|
183
|
+
present; no CUDA toolkit needed:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
python -m pipx inject mediasense nvidia-cublas-cu12 "nvidia-cudnn-cu12>=9,<10" nvidia-cuda-runtime-cu12
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
(≈ 1.5 GB; needs a driver that supports CUDA 12 – `mediasense doctor` checks both). Restart Claude
|
|
190
|
+
Desktop afterwards.
|
|
191
|
+
- **Word timing** is approximate (0.1–0.2 s). For tighter cuts and speaker labels use
|
|
192
|
+
`--backend whisperx` (`pip install "mediasense[whisperx]"`).
|
|
193
|
+
- Downloading from links follows each site's terms. Use it for content you're allowed to download.
|
|
194
|
+
|
|
195
|
+
## Development
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
git clone https://github.com/joaoestella/mediasense && cd mediasense
|
|
199
|
+
pip install -e ".[dev,mcp]"
|
|
200
|
+
pytest
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The tests build synthetic audio/video with FFmpeg and use fake model and downloader libraries, so they
|
|
204
|
+
run in seconds with nothing to download. Ideas welcome: more filler words for your language, a
|
|
205
|
+
one-click Claude Desktop extension (`.mcpb`), and a GUI.
|
|
206
|
+
|
|
207
|
+
## Releasing
|
|
208
|
+
|
|
209
|
+
1. Bump `version` in `pyproject.toml` and `src/mediasense/__init__.py`, commit.
|
|
210
|
+
2. `git tag vX.Y.Z && git push origin vX.Y.Z`. The Release workflow publishes to PyPI and creates a
|
|
211
|
+
GitHub release with the wheel, `mediasense-skill.zip` and `mediasense.mcpb`.
|
|
212
|
+
|
|
213
|
+
One-time PyPI setup (trusted publishing, no token): on pypi.org → *Your account → Publishing → Add a
|
|
214
|
+
new pending publisher*: project `mediasense`, owner `joaoestella`, repository `mediasense`, workflow
|
|
215
|
+
`release.yml`, environment left empty.
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|