clipkly 0.1.0__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.
clipkly-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Judlup Luna
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 @@
1
+ include README.md
clipkly-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,210 @@
1
+ Metadata-Version: 2.4
2
+ Name: clipkly
3
+ Version: 0.1.0
4
+ Summary: Corta automáticamente clips de video a partir de subtítulos o timecodes definidos en un JSON.
5
+ Home-page: https://github.com/judlup/clipkly
6
+ Author: Julian Dario Luna Patiño
7
+ Author-email: judlup@trycatch.tv
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: pandas
15
+ Requires-Dist: tqdm
16
+ Requires-Dist: openpyxl
17
+ Dynamic: author
18
+ Dynamic: author-email
19
+ Dynamic: classifier
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: license-file
24
+ Dynamic: requires-dist
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+
29
+ # 🎬 Clipkly
30
+
31
+ `Clipkly` es una herramienta en Python para cortar automáticamente clips desde dos versiones de un mismo video (horizontal y vertical), usando un archivo `.json` con los timecodes de los mejores momentos.
32
+
33
+ Soporta desfase (`--offset`) cuando el video vertical empieza en un punto diferente al horizontal (por ejemplo, por edición o plataformas como TikTok).
34
+
35
+ ---
36
+
37
+ ## 🚀 Uso rápido
38
+
39
+ ```bash
40
+ python clipkly.py --offset 403.025 --vertical video_v.mp4
41
+ ```
42
+
43
+ Esto generará clips desde:
44
+
45
+ - `video_v.mp4` (con offset aplicado) → en `clips/vertical/`
46
+
47
+ Si también incluyes `--horizontal`, generará clips desde `video_h.mp4` (sin offset) → en `clips/horizontal/`.
48
+
49
+ ---
50
+
51
+ ## 🧾 Formato del archivo clips.json
52
+
53
+ ```json
54
+ [
55
+ {
56
+ "start": "01:46:31.760",
57
+ "end": "01:47:17.199",
58
+ "slug": "titulo_del_video",
59
+ "titulo": "titulo del video optimizado para SEO",
60
+ "descripcion": "breve descripción del contenido del clip",
61
+ "feeling": "sentimiento del clip",
62
+ "category" : "categoria del clip"
63
+ }
64
+ ]
65
+ ```
66
+
67
+ 🧠 Puedes generar este archivo a partir de los subtítulos de YouTube (ver más abajo).
68
+
69
+ 📥 Cómo obtener los subtítulos (`.srt`):
70
+
71
+ 1. Ve a https://www.downloadyoutubesubtitles.com/es
72
+ 2. Pega el enlace del video de YouTube
73
+ 3. Descarga el archivo en formato `.srt` (idealmente en español)
74
+ 4. Abre Google AI Studio
75
+ 5. Usa este prompt:
76
+
77
+ ```plaintext
78
+ Estos son los subtítulos de la transmisión, puede darme la lista de los mejores momentos para sacar los clips, también en formato JSON:
79
+
80
+ {
81
+ "start": "01:46:31.760",
82
+ "end": "01:47:17.199",
83
+ "slug": "titulo_del_video",
84
+ "titulo": "titulo del video optimizado para seo",
85
+ "description": "descripción o sinapsis del video",
86
+ "feeling": "sentimiento del clip",
87
+ "category" : " categoria del clip"
88
+ }
89
+ ```
90
+
91
+ ---
92
+
93
+ ## ⚙️ Argumentos del script
94
+
95
+ ```bash
96
+ python clipkly.py [opciones]
97
+ ```
98
+
99
+ | Opción | Descripción |
100
+ |------------------|-----------------------------------------------------------------------------|
101
+ | `--offset` | Offset en segundos solo para el video vertical (default: 0.0) |
102
+ | `--horizontal` | Ruta al video horizontal (opcional) |
103
+ | `--vertical` | Ruta al video vertical (opcional) |
104
+ | `--json` | Ruta al archivo JSON con los timecodes (default: `clips.json`) |
105
+ | `--filter` | Filtra los clips por categoría (`inspiracional`, `tips`, etc.) |
106
+ | `--duracion` | Filtra clips por duración: `muy_corto`, `ideal`, `largo`, `muy_largo` |
107
+ | `--dry-run` | Muestra los comandos sin ejecutarlos |
108
+ | `--version`, `-v`| Muestra la versión del script |
109
+
110
+ ---
111
+
112
+ ## 📁 Estructura generada
113
+
114
+ ```plaintext
115
+ 📁 clips/
116
+ ├── 📁 horizontal/ ← Clips del video horizontal (sin offset)
117
+ ├── 📁 vertical/ ← Clips del video vertical (con offset)
118
+ └── 📄 estado_clips.xlsx ← Archivo Excel con metadatos editoriales
119
+ ```
120
+
121
+ Este Excel incluye:
122
+
123
+ - duración del clip en segundos (`duracion_segundos`)
124
+ - duración en formato `min:seg` (`duracion_mmss`)
125
+ - clasificación automática:
126
+ - `muy_corto`: hasta 30s
127
+ - `ideal`: entre 31s y 90s
128
+ - `largo`: entre 91s y 179s
129
+ - `muy_largo`: más de 3 minutos
130
+
131
+ ---
132
+
133
+ ## 📦 Requisitos
134
+
135
+ - Python 3.7+
136
+ - `ffmpeg` instalado y en el PATH
137
+ - Ejecutar: `pip install -r requirements.txt` para instalar dependencias
138
+
139
+ Dependencias mínimas:
140
+
141
+ ```
142
+ pandas
143
+ tqdm
144
+ openpyxl
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 💡 Funcionalidades
150
+
151
+ - ✂️ Corta clips precisos con FFmpeg sin recodificar (`-c copy`)
152
+ - 🕒 Aplica offset únicamente al video vertical
153
+ - 📁 Genera carpetas separadas para cada versión (`clips/horizontal` y `clips/vertical`)
154
+ - 🧼 Limpia automáticamente los nombres de archivo
155
+ - 🧠 Exporta Excel para planeación editorial (`estado_clips.xlsx`)
156
+ - 🔍 Filtros por duración y categoría
157
+ - 🔄 Modo `--dry-run` para validar sin ejecutar
158
+ - 🧾 Modo CLI personalizable
159
+
160
+ ---
161
+
162
+ ## 🖥️ Alias útil en consola
163
+
164
+ Powershell:
165
+
166
+ ```powershell
167
+ Set-Alias clipkly python ./clipkly.py
168
+ ```
169
+
170
+ Linux/Bash:
171
+
172
+ ```bash
173
+ alias clipkly='python ./clipkly.py'
174
+ ```
175
+
176
+ Entonces puedes correr:
177
+
178
+ ```bash
179
+ clipkly --offset 3.25 --vertical video_v.mp4
180
+ ```
181
+
182
+ ---
183
+
184
+ ## 📌 Ejemplo completo
185
+
186
+ ```bash
187
+ python clipkly.py --offset 403.025 --horizontal video_h.mp4 --vertical video_v.mp4 --json clips.json --duracion ideal
188
+ ```
189
+
190
+ ---
191
+
192
+ ## 🔜 Próximas mejoras sugeridas
193
+
194
+ - 🎞️ Subtítulos quemados en los clips
195
+ - 📸 Generación de miniaturas automáticas
196
+ - 🌐 Interfaz gráfica simple con Gradio
197
+ - 📊 Dashboard para gestión de clips y publicaciones
198
+ - ☁️ Integración con plataformas como Notion o Google Sheets
199
+
200
+ ---
201
+
202
+ ## 🙌 Créditos
203
+
204
+ Este proyecto fue creado por **Julian Dario Luna Patiño**, ingeniero de software, arquitecto de soluciones en la nube y creador de contenido en [TryCatch.tv](https://trycatch.tv).
205
+
206
+ **clipkly** nació como una herramienta práctica para automatizar la creación de clips a partir de transmisiones en vivo, especialmente útil para quienes trabajan con contenido en plataformas como YouTube, TikTok e Instagram.
207
+
208
+ Contacto: [judlup@trycatch.tv](mailto:judlup@trycatch.tv)
209
+
210
+ ✨ Dedicado con cariño a **Nikol Daniela** ❤️
@@ -0,0 +1,183 @@
1
+
2
+ # 🎬 Clipkly
3
+
4
+ `Clipkly` es una herramienta en Python para cortar automáticamente clips desde dos versiones de un mismo video (horizontal y vertical), usando un archivo `.json` con los timecodes de los mejores momentos.
5
+
6
+ Soporta desfase (`--offset`) cuando el video vertical empieza en un punto diferente al horizontal (por ejemplo, por edición o plataformas como TikTok).
7
+
8
+ ---
9
+
10
+ ## 🚀 Uso rápido
11
+
12
+ ```bash
13
+ python clipkly.py --offset 403.025 --vertical video_v.mp4
14
+ ```
15
+
16
+ Esto generará clips desde:
17
+
18
+ - `video_v.mp4` (con offset aplicado) → en `clips/vertical/`
19
+
20
+ Si también incluyes `--horizontal`, generará clips desde `video_h.mp4` (sin offset) → en `clips/horizontal/`.
21
+
22
+ ---
23
+
24
+ ## 🧾 Formato del archivo clips.json
25
+
26
+ ```json
27
+ [
28
+ {
29
+ "start": "01:46:31.760",
30
+ "end": "01:47:17.199",
31
+ "slug": "titulo_del_video",
32
+ "titulo": "titulo del video optimizado para SEO",
33
+ "descripcion": "breve descripción del contenido del clip",
34
+ "feeling": "sentimiento del clip",
35
+ "category" : "categoria del clip"
36
+ }
37
+ ]
38
+ ```
39
+
40
+ 🧠 Puedes generar este archivo a partir de los subtítulos de YouTube (ver más abajo).
41
+
42
+ 📥 Cómo obtener los subtítulos (`.srt`):
43
+
44
+ 1. Ve a https://www.downloadyoutubesubtitles.com/es
45
+ 2. Pega el enlace del video de YouTube
46
+ 3. Descarga el archivo en formato `.srt` (idealmente en español)
47
+ 4. Abre Google AI Studio
48
+ 5. Usa este prompt:
49
+
50
+ ```plaintext
51
+ Estos son los subtítulos de la transmisión, puede darme la lista de los mejores momentos para sacar los clips, también en formato JSON:
52
+
53
+ {
54
+ "start": "01:46:31.760",
55
+ "end": "01:47:17.199",
56
+ "slug": "titulo_del_video",
57
+ "titulo": "titulo del video optimizado para seo",
58
+ "description": "descripción o sinapsis del video",
59
+ "feeling": "sentimiento del clip",
60
+ "category" : " categoria del clip"
61
+ }
62
+ ```
63
+
64
+ ---
65
+
66
+ ## ⚙️ Argumentos del script
67
+
68
+ ```bash
69
+ python clipkly.py [opciones]
70
+ ```
71
+
72
+ | Opción | Descripción |
73
+ |------------------|-----------------------------------------------------------------------------|
74
+ | `--offset` | Offset en segundos solo para el video vertical (default: 0.0) |
75
+ | `--horizontal` | Ruta al video horizontal (opcional) |
76
+ | `--vertical` | Ruta al video vertical (opcional) |
77
+ | `--json` | Ruta al archivo JSON con los timecodes (default: `clips.json`) |
78
+ | `--filter` | Filtra los clips por categoría (`inspiracional`, `tips`, etc.) |
79
+ | `--duracion` | Filtra clips por duración: `muy_corto`, `ideal`, `largo`, `muy_largo` |
80
+ | `--dry-run` | Muestra los comandos sin ejecutarlos |
81
+ | `--version`, `-v`| Muestra la versión del script |
82
+
83
+ ---
84
+
85
+ ## 📁 Estructura generada
86
+
87
+ ```plaintext
88
+ 📁 clips/
89
+ ├── 📁 horizontal/ ← Clips del video horizontal (sin offset)
90
+ ├── 📁 vertical/ ← Clips del video vertical (con offset)
91
+ └── 📄 estado_clips.xlsx ← Archivo Excel con metadatos editoriales
92
+ ```
93
+
94
+ Este Excel incluye:
95
+
96
+ - duración del clip en segundos (`duracion_segundos`)
97
+ - duración en formato `min:seg` (`duracion_mmss`)
98
+ - clasificación automática:
99
+ - `muy_corto`: hasta 30s
100
+ - `ideal`: entre 31s y 90s
101
+ - `largo`: entre 91s y 179s
102
+ - `muy_largo`: más de 3 minutos
103
+
104
+ ---
105
+
106
+ ## 📦 Requisitos
107
+
108
+ - Python 3.7+
109
+ - `ffmpeg` instalado y en el PATH
110
+ - Ejecutar: `pip install -r requirements.txt` para instalar dependencias
111
+
112
+ Dependencias mínimas:
113
+
114
+ ```
115
+ pandas
116
+ tqdm
117
+ openpyxl
118
+ ```
119
+
120
+ ---
121
+
122
+ ## 💡 Funcionalidades
123
+
124
+ - ✂️ Corta clips precisos con FFmpeg sin recodificar (`-c copy`)
125
+ - 🕒 Aplica offset únicamente al video vertical
126
+ - 📁 Genera carpetas separadas para cada versión (`clips/horizontal` y `clips/vertical`)
127
+ - 🧼 Limpia automáticamente los nombres de archivo
128
+ - 🧠 Exporta Excel para planeación editorial (`estado_clips.xlsx`)
129
+ - 🔍 Filtros por duración y categoría
130
+ - 🔄 Modo `--dry-run` para validar sin ejecutar
131
+ - 🧾 Modo CLI personalizable
132
+
133
+ ---
134
+
135
+ ## 🖥️ Alias útil en consola
136
+
137
+ Powershell:
138
+
139
+ ```powershell
140
+ Set-Alias clipkly python ./clipkly.py
141
+ ```
142
+
143
+ Linux/Bash:
144
+
145
+ ```bash
146
+ alias clipkly='python ./clipkly.py'
147
+ ```
148
+
149
+ Entonces puedes correr:
150
+
151
+ ```bash
152
+ clipkly --offset 3.25 --vertical video_v.mp4
153
+ ```
154
+
155
+ ---
156
+
157
+ ## 📌 Ejemplo completo
158
+
159
+ ```bash
160
+ python clipkly.py --offset 403.025 --horizontal video_h.mp4 --vertical video_v.mp4 --json clips.json --duracion ideal
161
+ ```
162
+
163
+ ---
164
+
165
+ ## 🔜 Próximas mejoras sugeridas
166
+
167
+ - 🎞️ Subtítulos quemados en los clips
168
+ - 📸 Generación de miniaturas automáticas
169
+ - 🌐 Interfaz gráfica simple con Gradio
170
+ - 📊 Dashboard para gestión de clips y publicaciones
171
+ - ☁️ Integración con plataformas como Notion o Google Sheets
172
+
173
+ ---
174
+
175
+ ## 🙌 Créditos
176
+
177
+ Este proyecto fue creado por **Julian Dario Luna Patiño**, ingeniero de software, arquitecto de soluciones en la nube y creador de contenido en [TryCatch.tv](https://trycatch.tv).
178
+
179
+ **clipkly** nació como una herramienta práctica para automatizar la creación de clips a partir de transmisiones en vivo, especialmente útil para quienes trabajan con contenido en plataformas como YouTube, TikTok e Instagram.
180
+
181
+ Contacto: [judlup@trycatch.tv](mailto:judlup@trycatch.tv)
182
+
183
+ ✨ Dedicado con cariño a **Nikol Daniela** ❤️
@@ -0,0 +1 @@
1
+ # clipkly/__init__.py
@@ -0,0 +1,152 @@
1
+ import argparse
2
+ import json
3
+ import os
4
+ import pathlib
5
+ import re
6
+ import shlex
7
+ import subprocess
8
+ import unicodedata
9
+ from datetime import datetime
10
+
11
+ import pandas as pd
12
+ from tqdm import tqdm
13
+
14
+
15
+ def main():
16
+ VERSION = "0.1.0"
17
+
18
+ parser = argparse.ArgumentParser(
19
+ description="Recorta clips desde uno o dos videos según un archivo JSON.")
20
+ parser.add_argument("--offset", type=float, default=0.0,
21
+ help="Offset (en segundos) solo para el video vertical")
22
+ parser.add_argument("--horizontal", type=str,
23
+ help="Ruta al archivo de video horizontal (opcional)")
24
+ parser.add_argument("--vertical", type=str,
25
+ help="Ruta al archivo de video vertical (opcional)")
26
+ parser.add_argument("--json", type=str, default="clips.json",
27
+ help="Archivo JSON con la definición de los clips")
28
+ parser.add_argument("--filter", type=str,
29
+ help="Filtrar clips por categoría (opcional)")
30
+ parser.add_argument("--duracion", type=str, choices=[
31
+ "muy_corto", "ideal", "largo", "muy_largo"], help="Filtrar clips por duración clasificada (opcional)")
32
+ parser.add_argument("--dry-run", action="store_true",
33
+ help="Solo mostrar lo que se haría sin ejecutar FFmpeg")
34
+ parser.add_argument("--version", "-v", action="store_true",
35
+ help="Mostrar versión y salir")
36
+ args = parser.parse_args()
37
+
38
+ if args.version:
39
+ print(f"clipkly v{VERSION}")
40
+ exit()
41
+
42
+ OFFSET_SECONDS = args.offset
43
+ VIDEO_H = args.horizontal
44
+ VIDEO_V = args.vertical
45
+ TIMECODES = args.json
46
+ FILTER = args.filter
47
+ DURACION = args.duracion
48
+ DRY_RUN = args.dry_run
49
+
50
+ ROOT_DIR = pathlib.Path("clips")
51
+ OUT_H = ROOT_DIR / "horizontal"
52
+ OUT_V = ROOT_DIR / "vertical"
53
+ OUT_H.mkdir(parents=True, exist_ok=True)
54
+ OUT_V.mkdir(parents=True, exist_ok=True)
55
+
56
+ def slugify(text: str) -> str:
57
+ text = unicodedata.normalize("NFKD", text)
58
+ text = text.encode("ascii", "ignore").decode("ascii")
59
+ text = re.sub(r"\W+", "_", text.lower())
60
+ return re.sub(r"_+", "_", text[:40].strip("_")) or "clip"
61
+
62
+ def hhmmss_to_sec(t: str) -> float:
63
+ dt = datetime.strptime(
64
+ t, "%H:%M:%S.%f") if "." in t else datetime.strptime(t, "%H:%M:%S")
65
+ return dt.hour * 3600 + dt.minute * 60 + dt.second + dt.microsecond / 1e6
66
+
67
+ def sec_to_hhmmss(seconds: float) -> str:
68
+ s = max(0, seconds)
69
+ h = int(s // 3600)
70
+ m = int((s % 3600) // 60)
71
+ s = s % 60
72
+ return f"{h:02}:{m:02}:{s:06.3f}"
73
+
74
+ with open(TIMECODES, encoding="utf-8") as f:
75
+ raw_clips = json.load(f)
76
+
77
+ clips = [c for c in raw_clips if not FILTER or c.get("category") == FILTER]
78
+
79
+ def clasifica(segundos):
80
+ if segundos <= 30:
81
+ return "muy_corto"
82
+ elif segundos <= 90:
83
+ return "ideal"
84
+ elif segundos <= 179:
85
+ return "largo"
86
+ else:
87
+ return "muy_largo"
88
+
89
+ if DURACION:
90
+ clips = [
91
+ c for c in clips
92
+ if clasifica(hhmmss_to_sec(c["end"]) - hhmmss_to_sec(c["start"])) == DURACION
93
+ ]
94
+
95
+ excel_data = []
96
+ for c in clips:
97
+ duracion = round(hhmmss_to_sec(
98
+ c["end"]) - hhmmss_to_sec(c["start"]), 2)
99
+ excel_data.append({
100
+ "slug": c.get("slug"),
101
+ "titulo": c.get("titulo"),
102
+ "descripcion": c.get("descripcion", ""),
103
+ "feeling": c.get("feeling", ""),
104
+ "category": c.get("category", ""),
105
+ "start": c.get("start"),
106
+ "end": c.get("end"),
107
+ "duracion_segundos": duracion,
108
+ "duracion_mmss": f"{int(duracion // 60)}:{int(duracion % 60):02}",
109
+ "clasificacion_duracion": clasifica(duracion),
110
+ "fecha_publicacion": "",
111
+ "estado": "por_publicar"
112
+ })
113
+
114
+ df = pd.DataFrame(excel_data)
115
+ df.to_excel(ROOT_DIR / "estado_clips.xlsx", index=False)
116
+
117
+ if VIDEO_H:
118
+ print("🎬 Procesando clips del video horizontal (sin offset)...")
119
+ for i, c in enumerate(tqdm(clips, desc="Horizontal")):
120
+ start = hhmmss_to_sec(c["start"])
121
+ end = hhmmss_to_sec(c["end"])
122
+ slug = slugify(c.get("slug", f"clip_{i:02d}"))
123
+ out = str(OUT_H / f"{i:02d}_{slug}.mp4").replace("\\", "/")
124
+ cmd = f'ffmpeg -y -hide_banner -loglevel error -ss {sec_to_hhmmss(start)} -to {sec_to_hhmmss(end)} -i "{VIDEO_H}" -c copy "{out}"'
125
+ if DRY_RUN:
126
+ print("[DRY RUN]", cmd)
127
+ else:
128
+ subprocess.run(cmd, shell=True, check=True)
129
+
130
+ if VIDEO_V:
131
+ print("🎬 Procesando clips del video vertical (con offset aplicado)...")
132
+ for i, c in enumerate(tqdm(clips, desc="Vertical")):
133
+ start = hhmmss_to_sec(c["start"]) - OFFSET_SECONDS
134
+ end = hhmmss_to_sec(c["end"]) - OFFSET_SECONDS
135
+ slug = slugify(c.get("slug", f"clip_{i:02d}"))
136
+ out = str(OUT_V / f"{i:02d}_{slug}.mp4").replace("\\", "/")
137
+ cmd = f'ffmpeg -y -hide_banner -loglevel error -ss {sec_to_hhmmss(start)} -to {sec_to_hhmmss(end)} -i "{VIDEO_V}" -c copy "{out}"'
138
+ if DRY_RUN:
139
+ print("[DRY RUN]", cmd)
140
+ else:
141
+ subprocess.run(cmd, shell=True, check=True)
142
+
143
+ print("\n✅ ¡Listo! Clips generados:")
144
+ if VIDEO_H:
145
+ print("📁", OUT_H)
146
+ if VIDEO_V:
147
+ print("📁", OUT_V)
148
+ print("🗂️ Archivo Excel:", ROOT_DIR / "estado_clips.xlsx")
149
+
150
+
151
+ if __name__ == "__main__":
152
+ main()
@@ -0,0 +1,210 @@
1
+ Metadata-Version: 2.4
2
+ Name: clipkly
3
+ Version: 0.1.0
4
+ Summary: Corta automáticamente clips de video a partir de subtítulos o timecodes definidos en un JSON.
5
+ Home-page: https://github.com/judlup/clipkly
6
+ Author: Julian Dario Luna Patiño
7
+ Author-email: judlup@trycatch.tv
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: pandas
15
+ Requires-Dist: tqdm
16
+ Requires-Dist: openpyxl
17
+ Dynamic: author
18
+ Dynamic: author-email
19
+ Dynamic: classifier
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: license-file
24
+ Dynamic: requires-dist
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+
29
+ # 🎬 Clipkly
30
+
31
+ `Clipkly` es una herramienta en Python para cortar automáticamente clips desde dos versiones de un mismo video (horizontal y vertical), usando un archivo `.json` con los timecodes de los mejores momentos.
32
+
33
+ Soporta desfase (`--offset`) cuando el video vertical empieza en un punto diferente al horizontal (por ejemplo, por edición o plataformas como TikTok).
34
+
35
+ ---
36
+
37
+ ## 🚀 Uso rápido
38
+
39
+ ```bash
40
+ python clipkly.py --offset 403.025 --vertical video_v.mp4
41
+ ```
42
+
43
+ Esto generará clips desde:
44
+
45
+ - `video_v.mp4` (con offset aplicado) → en `clips/vertical/`
46
+
47
+ Si también incluyes `--horizontal`, generará clips desde `video_h.mp4` (sin offset) → en `clips/horizontal/`.
48
+
49
+ ---
50
+
51
+ ## 🧾 Formato del archivo clips.json
52
+
53
+ ```json
54
+ [
55
+ {
56
+ "start": "01:46:31.760",
57
+ "end": "01:47:17.199",
58
+ "slug": "titulo_del_video",
59
+ "titulo": "titulo del video optimizado para SEO",
60
+ "descripcion": "breve descripción del contenido del clip",
61
+ "feeling": "sentimiento del clip",
62
+ "category" : "categoria del clip"
63
+ }
64
+ ]
65
+ ```
66
+
67
+ 🧠 Puedes generar este archivo a partir de los subtítulos de YouTube (ver más abajo).
68
+
69
+ 📥 Cómo obtener los subtítulos (`.srt`):
70
+
71
+ 1. Ve a https://www.downloadyoutubesubtitles.com/es
72
+ 2. Pega el enlace del video de YouTube
73
+ 3. Descarga el archivo en formato `.srt` (idealmente en español)
74
+ 4. Abre Google AI Studio
75
+ 5. Usa este prompt:
76
+
77
+ ```plaintext
78
+ Estos son los subtítulos de la transmisión, puede darme la lista de los mejores momentos para sacar los clips, también en formato JSON:
79
+
80
+ {
81
+ "start": "01:46:31.760",
82
+ "end": "01:47:17.199",
83
+ "slug": "titulo_del_video",
84
+ "titulo": "titulo del video optimizado para seo",
85
+ "description": "descripción o sinapsis del video",
86
+ "feeling": "sentimiento del clip",
87
+ "category" : " categoria del clip"
88
+ }
89
+ ```
90
+
91
+ ---
92
+
93
+ ## ⚙️ Argumentos del script
94
+
95
+ ```bash
96
+ python clipkly.py [opciones]
97
+ ```
98
+
99
+ | Opción | Descripción |
100
+ |------------------|-----------------------------------------------------------------------------|
101
+ | `--offset` | Offset en segundos solo para el video vertical (default: 0.0) |
102
+ | `--horizontal` | Ruta al video horizontal (opcional) |
103
+ | `--vertical` | Ruta al video vertical (opcional) |
104
+ | `--json` | Ruta al archivo JSON con los timecodes (default: `clips.json`) |
105
+ | `--filter` | Filtra los clips por categoría (`inspiracional`, `tips`, etc.) |
106
+ | `--duracion` | Filtra clips por duración: `muy_corto`, `ideal`, `largo`, `muy_largo` |
107
+ | `--dry-run` | Muestra los comandos sin ejecutarlos |
108
+ | `--version`, `-v`| Muestra la versión del script |
109
+
110
+ ---
111
+
112
+ ## 📁 Estructura generada
113
+
114
+ ```plaintext
115
+ 📁 clips/
116
+ ├── 📁 horizontal/ ← Clips del video horizontal (sin offset)
117
+ ├── 📁 vertical/ ← Clips del video vertical (con offset)
118
+ └── 📄 estado_clips.xlsx ← Archivo Excel con metadatos editoriales
119
+ ```
120
+
121
+ Este Excel incluye:
122
+
123
+ - duración del clip en segundos (`duracion_segundos`)
124
+ - duración en formato `min:seg` (`duracion_mmss`)
125
+ - clasificación automática:
126
+ - `muy_corto`: hasta 30s
127
+ - `ideal`: entre 31s y 90s
128
+ - `largo`: entre 91s y 179s
129
+ - `muy_largo`: más de 3 minutos
130
+
131
+ ---
132
+
133
+ ## 📦 Requisitos
134
+
135
+ - Python 3.7+
136
+ - `ffmpeg` instalado y en el PATH
137
+ - Ejecutar: `pip install -r requirements.txt` para instalar dependencias
138
+
139
+ Dependencias mínimas:
140
+
141
+ ```
142
+ pandas
143
+ tqdm
144
+ openpyxl
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 💡 Funcionalidades
150
+
151
+ - ✂️ Corta clips precisos con FFmpeg sin recodificar (`-c copy`)
152
+ - 🕒 Aplica offset únicamente al video vertical
153
+ - 📁 Genera carpetas separadas para cada versión (`clips/horizontal` y `clips/vertical`)
154
+ - 🧼 Limpia automáticamente los nombres de archivo
155
+ - 🧠 Exporta Excel para planeación editorial (`estado_clips.xlsx`)
156
+ - 🔍 Filtros por duración y categoría
157
+ - 🔄 Modo `--dry-run` para validar sin ejecutar
158
+ - 🧾 Modo CLI personalizable
159
+
160
+ ---
161
+
162
+ ## 🖥️ Alias útil en consola
163
+
164
+ Powershell:
165
+
166
+ ```powershell
167
+ Set-Alias clipkly python ./clipkly.py
168
+ ```
169
+
170
+ Linux/Bash:
171
+
172
+ ```bash
173
+ alias clipkly='python ./clipkly.py'
174
+ ```
175
+
176
+ Entonces puedes correr:
177
+
178
+ ```bash
179
+ clipkly --offset 3.25 --vertical video_v.mp4
180
+ ```
181
+
182
+ ---
183
+
184
+ ## 📌 Ejemplo completo
185
+
186
+ ```bash
187
+ python clipkly.py --offset 403.025 --horizontal video_h.mp4 --vertical video_v.mp4 --json clips.json --duracion ideal
188
+ ```
189
+
190
+ ---
191
+
192
+ ## 🔜 Próximas mejoras sugeridas
193
+
194
+ - 🎞️ Subtítulos quemados en los clips
195
+ - 📸 Generación de miniaturas automáticas
196
+ - 🌐 Interfaz gráfica simple con Gradio
197
+ - 📊 Dashboard para gestión de clips y publicaciones
198
+ - ☁️ Integración con plataformas como Notion o Google Sheets
199
+
200
+ ---
201
+
202
+ ## 🙌 Créditos
203
+
204
+ Este proyecto fue creado por **Julian Dario Luna Patiño**, ingeniero de software, arquitecto de soluciones en la nube y creador de contenido en [TryCatch.tv](https://trycatch.tv).
205
+
206
+ **clipkly** nació como una herramienta práctica para automatizar la creación de clips a partir de transmisiones en vivo, especialmente útil para quienes trabajan con contenido en plataformas como YouTube, TikTok e Instagram.
207
+
208
+ Contacto: [judlup@trycatch.tv](mailto:judlup@trycatch.tv)
209
+
210
+ ✨ Dedicado con cariño a **Nikol Daniela** ❤️
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ setup.py
6
+ clipkly/__init__.py
7
+ clipkly/cli.py
8
+ clipkly.egg-info/PKG-INFO
9
+ clipkly.egg-info/SOURCES.txt
10
+ clipkly.egg-info/dependency_links.txt
11
+ clipkly.egg-info/entry_points.txt
12
+ clipkly.egg-info/requires.txt
13
+ clipkly.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ clipkly = clipkly.cli:main
@@ -0,0 +1,3 @@
1
+ pandas
2
+ tqdm
3
+ openpyxl
@@ -0,0 +1 @@
1
+ clipkly
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
clipkly-0.1.0/setup.py ADDED
@@ -0,0 +1,25 @@
1
+ from setuptools import find_packages, setup
2
+
3
+ setup(
4
+ name="clipkly",
5
+ version="0.1.0",
6
+ packages=find_packages(),
7
+ install_requires=["pandas", "tqdm", "openpyxl"],
8
+ entry_points={
9
+ "console_scripts": [
10
+ "clipkly=clipkly.cli:main"
11
+ ]
12
+ },
13
+ author="Julian Dario Luna Patiño",
14
+ author_email="judlup@trycatch.tv",
15
+ description="Corta automáticamente clips de video a partir de subtítulos o timecodes definidos en un JSON.",
16
+ long_description=open("README.md", encoding="utf-8").read(),
17
+ long_description_content_type="text/markdown",
18
+ url="https://github.com/judlup/clipkly",
19
+ classifiers=[
20
+ "Programming Language :: Python :: 3",
21
+ "License :: OSI Approved :: MIT License",
22
+ "Operating System :: OS Independent",
23
+ ],
24
+ python_requires=">=3.7",
25
+ )