0
# Clip Management
1
2
Creation and management of video clips extracted from live streams or DVR sessions, allowing users to create highlights and shareable content segments.
3
4
## Capabilities
5
6
### Listing Clips
7
8
Retrieves a list of video clips with pagination and filtering capabilities.
9
10
```python { .api }
11
def list_clips(
12
self,
13
request: Union[ListClipsRequest, dict] = None,
14
*,
15
parent: str = None,
16
retry: OptionalRetry = gapic_v1.method.DEFAULT,
17
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
18
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
19
) -> pagers.ListClipsPager:
20
"""
21
Returns a list of all clips in the specified channel.
22
23
Args:
24
request: The request object containing parent, page_size, page_token, filter, order_by
25
parent: Required. The parent channel (projects/{project}/locations/{location}/channels/{channel})
26
retry: Retry configuration for the request
27
timeout: Request timeout in seconds
28
metadata: Additional metadata for the request
29
30
Returns:
31
pagers.ListClipsPager: Pager for iterating over clip results
32
33
Raises:
34
google.api_core.exceptions.GoogleAPICallError: If the request fails
35
"""
36
```
37
38
### Getting Clip Details
39
40
Retrieves detailed information about a specific clip including its manifest URI, time range, and processing state.
41
42
```python { .api }
43
def get_clip(
44
self,
45
request: Union[GetClipRequest, dict] = None,
46
*,
47
name: str = None,
48
retry: OptionalRetry = gapic_v1.method.DEFAULT,
49
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
50
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
51
) -> Clip:
52
"""
53
Returns the specified clip.
54
55
Args:
56
request: The request object containing name
57
name: Required. The clip name (projects/{project}/locations/{location}/channels/{channel}/clips/{clip})
58
retry: Retry configuration for the request
59
timeout: Request timeout in seconds
60
metadata: Additional metadata for the request
61
62
Returns:
63
Clip: The clip resource
64
65
Raises:
66
google.api_core.exceptions.GoogleAPICallError: If the request fails
67
"""
68
```
69
70
### Creating Clips
71
72
Creates a new video clip from a specified time range within a live stream or DVR session.
73
74
```python { .api }
75
def create_clip(
76
self,
77
request: Union[CreateClipRequest, dict] = None,
78
*,
79
parent: str = None,
80
clip: Clip = None,
81
clip_id: str = None,
82
retry: OptionalRetry = gapic_v1.method.DEFAULT,
83
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
84
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
85
) -> operation.Operation:
86
"""
87
Creates a clip with the provided unique ID in the specified channel.
88
89
Args:
90
request: The request object containing parent, clip_id, clip, and request_id
91
parent: Required. The parent channel (projects/{project}/locations/{location}/channels/{channel})
92
clip: Required. The clip resource to create
93
clip_id: Required. The ID to use for the clip (must be unique within parent)
94
retry: Retry configuration for the request
95
timeout: Request timeout in seconds
96
metadata: Additional metadata for the request
97
98
Returns:
99
google.api_core.operation.Operation: Long-running operation
100
101
Raises:
102
google.api_core.exceptions.GoogleAPICallError: If the request fails
103
"""
104
```
105
106
### Deleting Clips
107
108
Permanently removes a video clip and all associated manifest and segment data.
109
110
```python { .api }
111
def delete_clip(
112
self,
113
request: Union[DeleteClipRequest, dict] = None,
114
*,
115
name: str = None,
116
retry: OptionalRetry = gapic_v1.method.DEFAULT,
117
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
118
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
119
) -> operation.Operation:
120
"""
121
Deletes the specified clip.
122
123
Args:
124
request: The request object containing name and request_id
125
name: Required. The clip name (projects/{project}/locations/{location}/channels/{channel}/clips/{clip})
126
retry: Retry configuration for the request
127
timeout: Request timeout in seconds
128
metadata: Additional metadata for the request
129
130
Returns:
131
google.api_core.operation.Operation: Long-running operation
132
133
Raises:
134
google.api_core.exceptions.GoogleAPICallError: If the request fails
135
"""
136
```
137
138
## Clip Configuration Types
139
140
### Clip Resource
141
142
```python { .api }
143
class Clip:
144
"""
145
Clip resource represents a video segment extracted from a live stream.
146
147
Attributes:
148
name (str): Clip resource name
149
create_time (google.protobuf.timestamp_pb2.Timestamp): Creation timestamp
150
update_time (google.protobuf.timestamp_pb2.Timestamp): Last update timestamp
151
labels (MutableMapping[str, str]): User-defined labels
152
start_time_offset (google.protobuf.duration_pb2.Duration): Start time offset from stream beginning
153
end_time_offset (google.protobuf.duration_pb2.Duration): End time offset from stream beginning
154
clip_manifest_uri (str): Output only. URI of the clip's HLS manifest
155
state (State): Current clip processing state
156
error (google.rpc.status_pb2.Status): Any processing errors
157
"""
158
159
class State(proto.Enum):
160
"""Clip state enumeration."""
161
STATE_UNSPECIFIED = 0
162
CREATING = 1
163
ACTIVE = 2
164
FAILED = 3
165
```
166
167
### Request Types
168
169
```python { .api }
170
class CreateClipRequest:
171
"""
172
Request message for CreateClip.
173
174
Attributes:
175
parent (str): Required. The parent channel resource name
176
clip_id (str): Required. The ID to use for the clip
177
clip (Clip): Required. The clip resource to create
178
request_id (str): Optional. Idempotency key for request deduplication
179
"""
180
181
class ListClipsRequest:
182
"""
183
Request message for ListClips.
184
185
Attributes:
186
parent (str): Required. The parent channel resource name
187
page_size (int): Optional. Maximum number of clips to return per page
188
page_token (str): Optional. Token for pagination
189
filter (str): Optional. Filter expression for clips
190
order_by (str): Optional. Field to sort clips by
191
"""
192
193
class ListClipsResponse:
194
"""
195
Response message for ListClips.
196
197
Attributes:
198
clips (MutableSequence[Clip]): List of clips
199
next_page_token (str): Token for next page of results
200
unreachable (MutableSequence[str]): Locations that could not be reached
201
"""
202
203
class GetClipRequest:
204
"""
205
Request message for GetClip.
206
207
Attributes:
208
name (str): Required. The clip resource name
209
"""
210
211
class DeleteClipRequest:
212
"""
213
Request message for DeleteClip.
214
215
Attributes:
216
name (str): Required. The clip resource name
217
request_id (str): Optional. Idempotency key for request deduplication
218
"""
219
```
220
221
## Usage Examples
222
223
### Creating a Clip from Live Stream
224
225
```python
226
from google.cloud.video import live_stream_v1
227
from google.protobuf import duration_pb2
228
229
client = live_stream_v1.LivestreamServiceClient()
230
231
# Create 30-second clip starting 5 minutes into the stream
232
start_offset = duration_pb2.Duration(seconds=5*60) # 5 minutes
233
end_offset = duration_pb2.Duration(seconds=5*60 + 30) # 5 minutes 30 seconds
234
235
clip = live_stream_v1.Clip(
236
start_time_offset=start_offset,
237
end_time_offset=end_offset
238
)
239
240
request = live_stream_v1.CreateClipRequest(
241
parent="projects/my-project/locations/us-central1/channels/my-channel",
242
clip_id="highlight-clip-1",
243
clip=clip
244
)
245
246
operation = client.create_clip(request=request)
247
clip_result = operation.result()
248
print(f"Created clip: {clip_result.name}")
249
print(f"Clip manifest URI: {clip_result.clip_manifest_uri}")
250
```
251
252
### Creating Multiple Clips for Highlights
253
254
```python
255
# Create multiple highlight clips
256
highlights = [
257
{"start": 60, "duration": 30, "name": "goal-1"}, # 1:00-1:30
258
{"start": 300, "duration": 45, "name": "goal-2"}, # 5:00-5:45
259
{"start": 600, "duration": 20, "name": "save-1"}, # 10:00-10:20
260
]
261
262
clips_created = []
263
264
for highlight in highlights:
265
start_offset = duration_pb2.Duration(seconds=highlight["start"])
266
end_offset = duration_pb2.Duration(seconds=highlight["start"] + highlight["duration"])
267
268
clip = live_stream_v1.Clip(
269
start_time_offset=start_offset,
270
end_time_offset=end_offset,
271
labels={
272
"type": "highlight",
273
"category": highlight["name"].split("-")[0]
274
}
275
)
276
277
request = live_stream_v1.CreateClipRequest(
278
parent="projects/my-project/locations/us-central1/channels/sports-broadcast",
279
clip_id=f"highlight-{highlight['name']}",
280
clip=clip
281
)
282
283
operation = client.create_clip(request=request)
284
clip_result = operation.result()
285
clips_created.append(clip_result)
286
print(f"Created {highlight['name']}: {clip_result.clip_manifest_uri}")
287
```
288
289
### Monitoring Clip Processing
290
291
```python
292
# Check clip processing status
293
clip_name = "projects/my-project/locations/us-central1/channels/my-channel/clips/my-clip"
294
295
get_request = live_stream_v1.GetClipRequest(name=clip_name)
296
clip = client.get_clip(request=get_request)
297
298
print(f"Clip state: {clip.state}")
299
if clip.state == live_stream_v1.Clip.State.ACTIVE:
300
print(f"Clip ready: {clip.clip_manifest_uri}")
301
elif clip.state == live_stream_v1.Clip.State.FAILED:
302
print(f"Clip failed: {clip.error.message}")
303
elif clip.state == live_stream_v1.Clip.State.CREATING:
304
print("Clip is still processing...")
305
```
306
307
### Listing and Managing Clips
308
309
```python
310
# List all clips in a channel
311
list_request = live_stream_v1.ListClipsRequest(
312
parent="projects/my-project/locations/us-central1/channels/my-channel",
313
page_size=50
314
)
315
316
print("Available clips:")
317
for clip in client.list_clips(request=list_request):
318
duration_seconds = clip.end_time_offset.seconds - clip.start_time_offset.seconds
319
print(f"- {clip.name}: {duration_seconds}s clip ({clip.state})")
320
if clip.state == live_stream_v1.Clip.State.ACTIVE:
321
print(f" Manifest: {clip.clip_manifest_uri}")
322
323
# Filter clips by label
324
filtered_request = live_stream_v1.ListClipsRequest(
325
parent="projects/my-project/locations/us-central1/channels/my-channel",
326
filter='labels.type="highlight"'
327
)
328
329
print("\nHighlight clips:")
330
for clip in client.list_clips(request=filtered_request):
331
print(f"- {clip.name}")
332
```
333
334
### Clip Cleanup Operations
335
336
```python
337
# Delete old clips
338
import datetime
339
from google.protobuf import timestamp_pb2
340
341
# Delete clips older than 7 days
342
cutoff_time = datetime.datetime.now() - datetime.timedelta(days=7)
343
cutoff_timestamp = timestamp_pb2.Timestamp()
344
cutoff_timestamp.FromDatetime(cutoff_time)
345
346
list_request = live_stream_v1.ListClipsRequest(
347
parent="projects/my-project/locations/us-central1/channels/my-channel"
348
)
349
350
for clip in client.list_clips(request=list_request):
351
if clip.create_time < cutoff_timestamp:
352
print(f"Deleting old clip: {clip.name}")
353
delete_request = live_stream_v1.DeleteClipRequest(name=clip.name)
354
delete_operation = client.delete_clip(request=delete_request)
355
delete_operation.result() # Wait for completion
356
print(f"Deleted: {clip.name}")
357
```
358
359
### Creating Clips with Custom Time Ranges
360
361
```python
362
# Create clip from DVR session with precise timing
363
from google.protobuf import timestamp_pb2
364
365
# Clip from 2:15:30 to 2:18:45 (2 hours 15 minutes 30 seconds to 2 hours 18 minutes 45 seconds)
366
start_seconds = 2*3600 + 15*60 + 30 # 2:15:30
367
end_seconds = 2*3600 + 18*60 + 45 # 2:18:45
368
369
clip = live_stream_v1.Clip(
370
start_time_offset=duration_pb2.Duration(seconds=start_seconds),
371
end_time_offset=duration_pb2.Duration(seconds=end_seconds),
372
labels={
373
"event": "interview_segment",
374
"speaker": "guest_expert",
375
"topic": "technology_trends"
376
}
377
)
378
379
request = live_stream_v1.CreateClipRequest(
380
parent="projects/my-project/locations/us-central1/channels/interview-show",
381
clip_id="tech-trends-interview",
382
clip=clip
383
)
384
385
operation = client.create_clip(request=request)
386
clip_result = operation.result()
387
print(f"Interview clip created: {clip_result.clip_manifest_uri}")
388
```