twentythree-skills 1.0.0
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.
- package/README.md +47 -0
- package/bin/add.js +103 -0
- package/package.json +46 -0
- package/skills/SKILL.md +211 -0
- package/skills/reference/action.md +233 -0
- package/skills/reference/analytics.md +337 -0
- package/skills/reference/app.md +160 -0
- package/skills/reference/audience.md +377 -0
- package/skills/reference/category.md +123 -0
- package/skills/reference/collector.md +103 -0
- package/skills/reference/comment.md +225 -0
- package/skills/reference/openupload.md +138 -0
- package/skills/reference/player.md +192 -0
- package/skills/reference/poll.md +174 -0
- package/skills/reference/presentation.md +99 -0
- package/skills/reference/protection.md +131 -0
- package/skills/reference/session.md +98 -0
- package/skills/reference/setting.md +115 -0
- package/skills/reference/site.md +94 -0
- package/skills/reference/spot.md +188 -0
- package/skills/reference/tag.md +93 -0
- package/skills/reference/thumbnail.md +224 -0
- package/skills/reference/user.md +216 -0
- package/skills/reference/video.md +631 -0
- package/skills/reference/webhook.md +151 -0
- package/skills/reference/webinar.md +1371 -0
- package/skills/workflows/upload-and-publish.md +146 -0
- package/skills/workflows/webinar-lifecycle.md +209 -0
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: video
|
|
3
|
+
description: Manage video assets — upload, list, metadata updates, thumbnails, transcoding status, sections (chapters), and subtitles.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TwentyThree Video Commands
|
|
7
|
+
|
|
8
|
+
> Video is the primary asset type in TwentyThree. Every example uses `--json` for machine-readable output.
|
|
9
|
+
> CLI `video` maps to API `photo` — see Terminology Notes at the bottom of this file.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
Auth scope varies: **read** (list, get, transcoding-progress), **write** (upload, update, delete, replace, frame, all section writes, all subtitle writes).
|
|
14
|
+
Run `twentythree auth credentials` if not already configured.
|
|
15
|
+
Verify: `twentythree auth status --json`
|
|
16
|
+
|
|
17
|
+
> For any flag not listed here, run `twentythree video <cmd> --agent` to get the complete flag list, types, and defaults.
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
### video upload
|
|
22
|
+
|
|
23
|
+
**Auth scope:** write **Side effects:** creates **Output:** key-value (id + admin_url)
|
|
24
|
+
|
|
25
|
+
> **Chunked upload is automatic.** `twentythree video upload <file>` handles chunking internally.
|
|
26
|
+
> `--chunk-size` (default 5 MB) and `--concurrency` (default 5) are tunables — never construct multipart requests directly.
|
|
27
|
+
|
|
28
|
+
After upload the CLI prints the new video ID and its admin URL. Capture `data.id` and `data.admin_url` from the `--json` response.
|
|
29
|
+
|
|
30
|
+
| Flag | Required | Default | Description |
|
|
31
|
+
|------|----------|---------|-------------|
|
|
32
|
+
| `--title` | no | — | Title for the uploaded video |
|
|
33
|
+
| `--description` | no | — | Description for the uploaded video |
|
|
34
|
+
| `--tags` | no | — | Space-separated tags for the uploaded video |
|
|
35
|
+
| `--category-id` | no | — | Category ID (or comma-separated IDs) to assign the video to |
|
|
36
|
+
| `--publish` | no | false | Publish the video immediately after upload |
|
|
37
|
+
| `--chunk-size` | no | 5242880 | Chunk size in bytes (default: 5 MB) |
|
|
38
|
+
| `--concurrency` | no | 5 | Number of chunks to upload in parallel |
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Basic upload
|
|
42
|
+
twentythree video upload ./video.mp4 --title "Demo" --json
|
|
43
|
+
|
|
44
|
+
# Upload with category, tags, and publish immediately
|
|
45
|
+
twentythree video upload ./video.mp4 --title "Q2 Keynote" --category-id <cat-id> --tags "product q2" --publish --json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
### video list
|
|
51
|
+
|
|
52
|
+
**Auth scope:** read **Side effects:** none **Output:** table (ID, Title, Duration, Status, Published, Updated)
|
|
53
|
+
|
|
54
|
+
| Flag | Required | Default | Description |
|
|
55
|
+
|------|----------|---------|-------------|
|
|
56
|
+
| `--limit` | no | — | Maximum number of videos to return (default: all) |
|
|
57
|
+
| `--include-unpublished` | no | — | Include unpublished videos in results |
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# List all published videos
|
|
61
|
+
twentythree video list --json
|
|
62
|
+
|
|
63
|
+
# List up to 20 videos including unpublished
|
|
64
|
+
twentythree video list --limit 20 --include-unpublished --json
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### video get
|
|
70
|
+
|
|
71
|
+
**Auth scope:** read **Side effects:** none **Output:** key-value
|
|
72
|
+
|
|
73
|
+
No additional flags — pass the video ID as a positional argument.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Get details of a specific video
|
|
77
|
+
twentythree video get <id> --json
|
|
78
|
+
|
|
79
|
+
# Example with a real ID
|
|
80
|
+
twentythree video get 12345 --json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### video update
|
|
86
|
+
|
|
87
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
88
|
+
|
|
89
|
+
| Flag | Required | Default | Description |
|
|
90
|
+
|------|----------|---------|-------------|
|
|
91
|
+
| `--title` | no | — | New title for the video |
|
|
92
|
+
| `--description` | no | — | New description for the video |
|
|
93
|
+
| `--tags` | no | — | Space-separated tags (replaces existing tags) |
|
|
94
|
+
| `--category-id` | no | — | Category ID (or comma-separated IDs) to assign the video to |
|
|
95
|
+
| `--publish` | no | — | Publish or unpublish the video |
|
|
96
|
+
| `--promote` | no | — | Promote or demote the video |
|
|
97
|
+
| `--publish-date` | no | — | Scheduled publish date/time (ISO 8601) |
|
|
98
|
+
| `--360` | no | — | Mark as 360° video |
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Update title and description
|
|
102
|
+
twentythree video update <id> --title "New Title" --description "Updated description" --json
|
|
103
|
+
|
|
104
|
+
# Assign to category, add tags, and schedule publish
|
|
105
|
+
twentythree video update <id> --category-id <cat-id> --tags "demo q2" --publish-date "2026-06-01T10:00:00Z" --json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### video delete
|
|
111
|
+
|
|
112
|
+
**Auth scope:** write **Side effects:** destructive **Output:** key-value
|
|
113
|
+
|
|
114
|
+
> **Warning: This action is destructive and cannot be undone.** The video and all associated data (subtitles, sections, analytics) are permanently deleted from the workspace.
|
|
115
|
+
|
|
116
|
+
No additional flags — pass the video ID as a positional argument.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Delete a video (destructive — cannot be undone)
|
|
120
|
+
twentythree video delete <id> --json
|
|
121
|
+
|
|
122
|
+
# Example with a real ID
|
|
123
|
+
twentythree video delete 12345 --json
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
### video replace
|
|
129
|
+
|
|
130
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value (id + admin_url)
|
|
131
|
+
|
|
132
|
+
Replaces the video file while preserving metadata (title, description, subtitles, etc.). After replace the CLI prints the video ID and its admin URL.
|
|
133
|
+
|
|
134
|
+
| Flag | Required | Default | Description |
|
|
135
|
+
|------|----------|---------|-------------|
|
|
136
|
+
| `--chunk-size` | no | 5242880 | Chunk size in bytes (default: 5 MB) |
|
|
137
|
+
| `--concurrency` | no | 5 | Number of chunks to upload in parallel |
|
|
138
|
+
|
|
139
|
+
> **Chunked upload is automatic.** Replacement uses the same chunked engine as upload.
|
|
140
|
+
|
|
141
|
+
After replace, the CLI prints the video ID and its admin URL. Capture `data.id` and `data.admin_url` from the `--json` response.
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Replace a video file
|
|
145
|
+
twentythree video replace <id> ./new-video.mp4 --json
|
|
146
|
+
|
|
147
|
+
# Replace with custom chunk size for large files
|
|
148
|
+
twentythree video replace <id> ./new-video.mp4 --chunk-size 52428800 --concurrency 3 --json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### video frame
|
|
154
|
+
|
|
155
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
156
|
+
|
|
157
|
+
Extracts a frame from the video at a given time offset and sets it as the video thumbnail.
|
|
158
|
+
|
|
159
|
+
| Flag | Required | Default | Description |
|
|
160
|
+
|------|----------|---------|-------------|
|
|
161
|
+
| `--time` | no | — | Time offset in seconds to extract the frame from |
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Extract a frame from the beginning (default time)
|
|
165
|
+
twentythree video frame <id> --json
|
|
166
|
+
|
|
167
|
+
# Extract a frame at 30 seconds and set as thumbnail
|
|
168
|
+
twentythree video frame <id> --time 30 --json
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
### video transcoding-progress
|
|
174
|
+
|
|
175
|
+
**Auth scope:** read **Side effects:** none **Output:** key-value
|
|
176
|
+
|
|
177
|
+
Returns the transcoding status and progress percentage for a video. Poll this after upload to confirm processing is complete before publishing.
|
|
178
|
+
|
|
179
|
+
No additional flags — pass the video ID as a positional argument.
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Check transcoding status
|
|
183
|
+
twentythree video transcoding-progress <id> --json
|
|
184
|
+
|
|
185
|
+
# Example with a real ID
|
|
186
|
+
twentythree video transcoding-progress 12345 --json
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Subtopic: video section
|
|
192
|
+
|
|
193
|
+
Sections are chapter markers on a video. Start time is expressed in seconds from the beginning of the video. Use sections to help viewers navigate long-form content.
|
|
194
|
+
|
|
195
|
+
### video section list
|
|
196
|
+
|
|
197
|
+
**Auth scope:** read **Side effects:** none **Output:** table (ID, Title, Start Time, Description)
|
|
198
|
+
|
|
199
|
+
No additional flags — pass the video ID as a positional argument.
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# List all sections for a video
|
|
203
|
+
twentythree video section list <id> --json
|
|
204
|
+
|
|
205
|
+
# Example with a real ID
|
|
206
|
+
twentythree video section list 12345 --json
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
### video section create
|
|
212
|
+
|
|
213
|
+
**Auth scope:** write **Side effects:** creates **Output:** key-value
|
|
214
|
+
|
|
215
|
+
| Flag | Required | Default | Description |
|
|
216
|
+
|------|----------|---------|-------------|
|
|
217
|
+
| `--title` | yes | — | Section title |
|
|
218
|
+
| `--start-time` | yes | — | Start time in seconds |
|
|
219
|
+
| `--description` | no | — | Section description |
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# Create an intro section at the beginning
|
|
223
|
+
twentythree video section create <id> --title "Introduction" --start-time 0 --json
|
|
224
|
+
|
|
225
|
+
# Create a named chapter at 30 seconds with description
|
|
226
|
+
twentythree video section create <id> --title "Deep Dive" --start-time 30 --description "Technical walkthrough" --json
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
### video section update
|
|
232
|
+
|
|
233
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
234
|
+
|
|
235
|
+
| Flag | Required | Default | Description |
|
|
236
|
+
|------|----------|---------|-------------|
|
|
237
|
+
| `--section-id` | yes | — | Section ID to update |
|
|
238
|
+
| `--title` | no | — | New section title |
|
|
239
|
+
| `--start-time` | no | — | New start time in seconds |
|
|
240
|
+
| `--description` | no | — | New section description |
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Update a section title
|
|
244
|
+
twentythree video section update <id> --section-id <section-id> --title "New Title" --json
|
|
245
|
+
|
|
246
|
+
# Update start time and description
|
|
247
|
+
twentythree video section update <id> --section-id <section-id> --start-time 45 --description "Updated description" --json
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### video section delete
|
|
253
|
+
|
|
254
|
+
**Auth scope:** write **Side effects:** destructive **Output:** key-value
|
|
255
|
+
|
|
256
|
+
| Flag | Required | Default | Description |
|
|
257
|
+
|------|----------|---------|-------------|
|
|
258
|
+
| `--section-id` | yes | — | Section ID to delete |
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# Delete a section from a video
|
|
262
|
+
twentythree video section delete <id> --section-id <section-id> --json
|
|
263
|
+
|
|
264
|
+
# Example with real IDs
|
|
265
|
+
twentythree video section delete 12345 --section-id 67 --json
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
### video section generate
|
|
271
|
+
|
|
272
|
+
**Auth scope:** write **Side effects:** creates **Output:** key-value
|
|
273
|
+
|
|
274
|
+
Automatically generates chapter sections using AI. **Prerequisite:** the video must have a transcript (auto-transcription or manual subtitle upload). The AI reads the transcript and identifies natural chapter boundaries.
|
|
275
|
+
|
|
276
|
+
No additional flags — pass the video ID as a positional argument.
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Generate AI sections from transcript (transcript must exist)
|
|
280
|
+
twentythree video section generate <id> --json
|
|
281
|
+
|
|
282
|
+
# Example with a real ID
|
|
283
|
+
twentythree video section generate 12345 --json
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
### video section set-thumbnail
|
|
289
|
+
|
|
290
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
291
|
+
|
|
292
|
+
Sets the thumbnail image for a video section by extracting a frame at the given time offset.
|
|
293
|
+
|
|
294
|
+
| Flag | Required | Default | Description |
|
|
295
|
+
|------|----------|---------|-------------|
|
|
296
|
+
| `--section-id` | yes | — | Section ID |
|
|
297
|
+
| `--time` | no | — | Time offset in seconds for the thumbnail frame |
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
# Set thumbnail for a section (uses video frame at section start by default)
|
|
301
|
+
twentythree video section set-thumbnail <id> --section-id <section-id> --json
|
|
302
|
+
|
|
303
|
+
# Set thumbnail at a specific time offset
|
|
304
|
+
twentythree video section set-thumbnail <id> --section-id <section-id> --time 15 --json
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Subtopic: video subtitle
|
|
310
|
+
|
|
311
|
+
Subtitle commands manage caption tracks on a video (SRT/WebVTT formats). Use `twentythree video subtitle locales --json` to list all supported locales, and `twentythree video subtitle types --json` to list available subtitle types. Use `--agent` on any subtitle command to inspect the full flag list.
|
|
312
|
+
|
|
313
|
+
### video subtitle list
|
|
314
|
+
|
|
315
|
+
**Auth scope:** read **Side effects:** none **Output:** table (Locale, Language, Type, Status, Primary)
|
|
316
|
+
|
|
317
|
+
| Flag | Required | Default | Description |
|
|
318
|
+
|------|----------|---------|-------------|
|
|
319
|
+
| `--include-drafts` | no | — | Include draft (unpublished) subtitle tracks |
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# List published subtitle tracks for a video
|
|
323
|
+
twentythree video subtitle list <id> --json
|
|
324
|
+
|
|
325
|
+
# List all tracks including drafts
|
|
326
|
+
twentythree video subtitle list <id> --include-drafts --json
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
### video subtitle create
|
|
332
|
+
|
|
333
|
+
**Auth scope:** write **Side effects:** creates **Output:** key-value
|
|
334
|
+
|
|
335
|
+
Creates an empty subtitle track. Use `video subtitle upload` to add content to the track.
|
|
336
|
+
|
|
337
|
+
| Flag | Required | Default | Description |
|
|
338
|
+
|------|----------|---------|-------------|
|
|
339
|
+
| `--locale` | yes | — | Locale for the subtitle track (e.g. `en_US`, `fr_FR`, `auto`) |
|
|
340
|
+
| `--type` | no | general | Subtitle type: `general`, `closedcaptions`, `audiodescriptions` |
|
|
341
|
+
| `--draft` | no | — | Create the subtitle track as a draft (hidden from viewers) |
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# Create an English subtitle track
|
|
345
|
+
twentythree video subtitle create <id> --locale en_US --json
|
|
346
|
+
|
|
347
|
+
# Create a French closed-captions track as a draft
|
|
348
|
+
twentythree video subtitle create <id> --locale fr_FR --type closedcaptions --draft --json
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
### video subtitle upload
|
|
354
|
+
|
|
355
|
+
**Auth scope:** write **Side effects:** creates **Output:** key-value
|
|
356
|
+
|
|
357
|
+
Uploads an SRT or WebVTT subtitle file for a video. Creates the track and populates it with the uploaded file content.
|
|
358
|
+
|
|
359
|
+
| Flag | Required | Default | Description |
|
|
360
|
+
|------|----------|---------|-------------|
|
|
361
|
+
| `--locale` | yes | — | Locale for the subtitle track (e.g. `en_US`, `fr_FR`) |
|
|
362
|
+
| `--type` | no | general | Subtitle type: `general`, `closedcaptions`, `audiodescriptions` |
|
|
363
|
+
| `--draft` | no | — | Upload as a draft (hidden from viewers until published) |
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
# Upload an SRT file for English subtitles
|
|
367
|
+
twentythree video subtitle upload <id> ./subtitles.srt --locale en_US --json
|
|
368
|
+
|
|
369
|
+
# Upload a WebVTT file as French closed captions (draft)
|
|
370
|
+
twentythree video subtitle upload <id> ./captions.vtt --locale fr_FR --type closedcaptions --draft --json
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
### video subtitle update
|
|
376
|
+
|
|
377
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
378
|
+
|
|
379
|
+
| Flag | Required | Default | Description |
|
|
380
|
+
|------|----------|---------|-------------|
|
|
381
|
+
| `--subtitle-id` | yes | — | Locale of the subtitle track to update (e.g. `en_US`) |
|
|
382
|
+
| `--type` | no | — | New subtitle type: `general`, `closedcaptions`, `audiodescriptions` |
|
|
383
|
+
| `--draft` | no | — | Set draft status: true = hidden, false = published |
|
|
384
|
+
| `--default` | no | — | Set this subtitle track as the default |
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
# Publish a draft subtitle track (remove draft status)
|
|
388
|
+
twentythree video subtitle update <id> --subtitle-id en_US --no-draft --json
|
|
389
|
+
|
|
390
|
+
# Change subtitle type and set as default
|
|
391
|
+
twentythree video subtitle update <id> --subtitle-id en_US --type closedcaptions --default --json
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
### video subtitle delete
|
|
397
|
+
|
|
398
|
+
**Auth scope:** write **Side effects:** destructive **Output:** key-value
|
|
399
|
+
|
|
400
|
+
| Flag | Required | Default | Description |
|
|
401
|
+
|------|----------|---------|-------------|
|
|
402
|
+
| `--subtitle-id` | yes | — | Locale of the subtitle track to delete (e.g. `en_US`) |
|
|
403
|
+
| `--type` | no | general | Subtitle type to delete: `general`, `closedcaptions`, `audiodescriptions` |
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
# Delete an English subtitle track
|
|
407
|
+
twentythree video subtitle delete <id> --subtitle-id en_US --json
|
|
408
|
+
|
|
409
|
+
# Delete a specific subtitle type
|
|
410
|
+
twentythree video subtitle delete <id> --subtitle-id en_US --type closedcaptions --json
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
### video subtitle duplicate
|
|
416
|
+
|
|
417
|
+
**Auth scope:** write **Side effects:** creates **Output:** key-value
|
|
418
|
+
|
|
419
|
+
Copies a subtitle track to a new locale. Useful for pre-populating a track before translation.
|
|
420
|
+
|
|
421
|
+
| Flag | Required | Default | Description |
|
|
422
|
+
|------|----------|---------|-------------|
|
|
423
|
+
| `--subtitle-id` | yes | — | Source locale of the subtitle track to duplicate (e.g. `en_US`) |
|
|
424
|
+
| `--target-locale` | yes | — | Target locale for the duplicated track (e.g. `fr_FR`) |
|
|
425
|
+
| `--source-type` | no | general | Source subtitle type |
|
|
426
|
+
| `--target-type` | no | general | Target subtitle type |
|
|
427
|
+
| `--draft` | no | — | Create the duplicated track as a draft |
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
# Duplicate English subtitles to French
|
|
431
|
+
twentythree video subtitle duplicate <id> --subtitle-id en_US --target-locale fr_FR --json
|
|
432
|
+
|
|
433
|
+
# Duplicate to German and keep as draft for review
|
|
434
|
+
twentythree video subtitle duplicate <id> --subtitle-id en_US --target-locale de_DE --draft --json
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
### video subtitle locales
|
|
440
|
+
|
|
441
|
+
**Auth scope:** read **Side effects:** none **Output:** table (Code, Name, Auto Transcribe, Auto Translate, Live)
|
|
442
|
+
|
|
443
|
+
Lists all subtitle locale codes supported by TwentyThree. Use the `Code` value as the `--locale` or `--subtitle-id` argument in other subtitle commands.
|
|
444
|
+
|
|
445
|
+
No additional flags.
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
# List all available locales
|
|
449
|
+
twentythree video subtitle locales --json
|
|
450
|
+
|
|
451
|
+
# Pipe to filter for English locales
|
|
452
|
+
twentythree video subtitle locales --json
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
### video subtitle types
|
|
458
|
+
|
|
459
|
+
**Auth scope:** read **Side effects:** none **Output:** table (Type, Label)
|
|
460
|
+
|
|
461
|
+
Lists all valid subtitle types accepted by the platform.
|
|
462
|
+
|
|
463
|
+
No additional flags.
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
# List available subtitle types
|
|
467
|
+
twentythree video subtitle types --json
|
|
468
|
+
|
|
469
|
+
# Use to verify the type value before creating/updating
|
|
470
|
+
twentythree video subtitle types --json
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
### video subtitle data
|
|
476
|
+
|
|
477
|
+
**Auth scope:** read **Side effects:** none **Output:** key-value
|
|
478
|
+
|
|
479
|
+
Retrieves the raw subtitle content for a track. Use `--format` to select the file format.
|
|
480
|
+
|
|
481
|
+
| Flag | Required | Default | Description |
|
|
482
|
+
|------|----------|---------|-------------|
|
|
483
|
+
| `--subtitle-id` | yes | — | Locale of the subtitle track to retrieve (e.g. `en_US`) |
|
|
484
|
+
| `--format` | no | websrt | Subtitle format: `websrt`, `webvtt`, `json`, `adobe`, `subviewer` |
|
|
485
|
+
| `--type` | no | general | Subtitle type: `general`, `closedcaptions`, `audiodescriptions` |
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
# Get raw subtitle data in default SRT format
|
|
489
|
+
twentythree video subtitle data <id> --subtitle-id en_US --json
|
|
490
|
+
|
|
491
|
+
# Get subtitle data in WebVTT format
|
|
492
|
+
twentythree video subtitle data <id> --subtitle-id en_US --format webvtt --json
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
### video subtitle set-primary
|
|
498
|
+
|
|
499
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
500
|
+
|
|
501
|
+
Sets a subtitle track as the primary (default) language for the video.
|
|
502
|
+
|
|
503
|
+
| Flag | Required | Default | Description |
|
|
504
|
+
|------|----------|---------|-------------|
|
|
505
|
+
| `--subtitle-id` | yes | — | Locale of the subtitle track to set as primary (e.g. `en_US`) |
|
|
506
|
+
|
|
507
|
+
```bash
|
|
508
|
+
# Set English as the primary subtitle language
|
|
509
|
+
twentythree video subtitle set-primary <id> --subtitle-id en_US --json
|
|
510
|
+
|
|
511
|
+
# Set French as primary
|
|
512
|
+
twentythree video subtitle set-primary <id> --subtitle-id fr_FR --json
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
### video subtitle archive
|
|
518
|
+
|
|
519
|
+
**Auth scope:** write (both paths) **Side effects:** creates (without --progress) | none (with --progress) **Output:** key-value
|
|
520
|
+
|
|
521
|
+
Triggers or checks workspace-wide subtitle archive transcription. Without `--progress`, starts transcription. With `--progress`, reports current transcription status.
|
|
522
|
+
|
|
523
|
+
> Note: `--progress` only reads status and has read-only semantics, but both paths require write scope because the command maps to POST endpoints.
|
|
524
|
+
|
|
525
|
+
| Flag | Required | Default | Description |
|
|
526
|
+
|------|----------|---------|-------------|
|
|
527
|
+
| `--progress` | no | false | Check transcription progress instead of triggering transcription |
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
# Trigger workspace subtitle archive transcription
|
|
531
|
+
twentythree video subtitle archive --json
|
|
532
|
+
|
|
533
|
+
# Check transcription progress
|
|
534
|
+
twentythree video subtitle archive --progress --json
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## Common Patterns
|
|
540
|
+
|
|
541
|
+
### Upload, update metadata, and publish
|
|
542
|
+
|
|
543
|
+
```bash
|
|
544
|
+
# 1. Upload video (chunked upload is automatic)
|
|
545
|
+
twentythree video upload ./demo.mp4 --title "Q2 Demo" --json
|
|
546
|
+
# => { "data": { "id": "<video-id>", "admin_url": "..." } }
|
|
547
|
+
|
|
548
|
+
# 2. Update tags and category
|
|
549
|
+
twentythree video update <video-id> --tags "demo q2" --category-id <cat-id> --json
|
|
550
|
+
|
|
551
|
+
# 3. Publish
|
|
552
|
+
twentythree video update <video-id> --publish --json
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Poll for transcoding completion before publishing
|
|
556
|
+
|
|
557
|
+
```bash
|
|
558
|
+
# Check transcoding status (repeat until status is "complete")
|
|
559
|
+
twentythree video transcoding-progress <id> --json
|
|
560
|
+
# => { "data": { "status": "transcoding", "progress": 45 } }
|
|
561
|
+
|
|
562
|
+
# When progress reaches 100 / status is "complete", publish
|
|
563
|
+
twentythree video update <id> --publish --json
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### Extract a thumbnail frame
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
# Set thumbnail at 15 seconds into the video
|
|
570
|
+
twentythree video frame <id> --time 15 --json
|
|
571
|
+
|
|
572
|
+
# Alternatively, use video section set-thumbnail for a section preview
|
|
573
|
+
twentythree video section set-thumbnail <id> --section-id <section-id> --time 15 --json
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Create chapter markers (sections)
|
|
577
|
+
|
|
578
|
+
```bash
|
|
579
|
+
# Create multiple sections for a structured video
|
|
580
|
+
twentythree video section create <id> --title "Introduction" --start-time 0 --json
|
|
581
|
+
twentythree video section create <id> --title "Demo" --start-time 30 --json
|
|
582
|
+
twentythree video section create <id> --title "Q&A" --start-time 180 --json
|
|
583
|
+
|
|
584
|
+
# List all sections to verify
|
|
585
|
+
twentythree video section list <id> --json
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### Generate AI chapters from transcript
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
# Prerequisite: video must have a transcript (subtitle track created or uploaded)
|
|
592
|
+
# First, check if subtitles/transcript exist
|
|
593
|
+
twentythree video subtitle list <id> --json
|
|
594
|
+
|
|
595
|
+
# Generate chapters using AI
|
|
596
|
+
twentythree video section generate <id> --json
|
|
597
|
+
# => Creates sections based on transcript content
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Upload and publish subtitle tracks
|
|
601
|
+
|
|
602
|
+
```bash
|
|
603
|
+
# Upload English SRT subtitles
|
|
604
|
+
twentythree video subtitle upload <id> ./en-subtitles.srt --locale en_US --json
|
|
605
|
+
|
|
606
|
+
# Publish the track (if created as draft)
|
|
607
|
+
twentythree video subtitle update <id> --subtitle-id en_US --no-draft --json
|
|
608
|
+
|
|
609
|
+
# Set as primary language
|
|
610
|
+
twentythree video subtitle set-primary <id> --subtitle-id en_US --json
|
|
611
|
+
|
|
612
|
+
# Duplicate to French for translation
|
|
613
|
+
twentythree video subtitle duplicate <id> --subtitle-id en_US --target-locale fr_FR --draft --json
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
## Terminology Notes
|
|
619
|
+
|
|
620
|
+
CLI `video` = API `photo`. The `api_endpoint` field in `--agent` output uses the API name:
|
|
621
|
+
|
|
622
|
+
- `twentythree video upload` -> `POST /photo/redeem-upload-token`
|
|
623
|
+
- `twentythree video list` -> `GET /photo/list`
|
|
624
|
+
- `twentythree video update` -> `POST /photo/update`
|
|
625
|
+
- `twentythree video delete` -> `POST /photo/delete`
|
|
626
|
+
- `twentythree video replace` -> `POST /photo/replace`
|
|
627
|
+
- `twentythree video frame` -> `POST /photo/frame`
|
|
628
|
+
- `twentythree video transcoding-progress` -> `GET /photo/get-transcoding-progress`
|
|
629
|
+
|
|
630
|
+
When reading the raw OpenAPI spec or debugging API responses, `photo` refers to a video asset.
|
|
631
|
+
When commenting on a video via the `comment` topic, pass `--object-type photo`.
|