2
2
from dataclasses import dataclass
3
3
from typing import List , Optional
4
4
from enum import Enum , auto
5
+ import time
6
+
5
7
6
8
@dataclass
7
9
class Asset :
8
10
name : str
9
11
url : str
10
12
13
+
11
14
class JobStatus (Enum ):
12
15
PENDING = auto ()
13
16
COMPLETED = auto ()
14
17
FAILED = auto ()
15
18
UPLOADING = auto ()
16
19
20
+
17
21
@dataclass
18
22
class JobEntity :
19
23
id : int
20
24
status : JobStatus
21
25
created_at : str
22
26
assets : Optional [List [Asset ]] = None
23
27
28
+
24
29
class StreamPotClient :
25
30
def __init__ (self , secret : str , base_url : str = 'https://api.streampot.io/v1' ):
26
31
self .secret = secret
27
32
self .base_url = base_url
28
33
self .actions = []
29
34
30
- def check_status (self , job_id : str ) -> dict :
35
+ def get_job (self , job_id : int ) -> dict :
31
36
response = requests .get (f"{ self .base_url } /jobs/{ job_id } " , headers = self ._auth_header ())
32
37
response .raise_for_status ()
33
38
return response .json ()
34
39
35
40
def run (self ) -> JobEntity :
36
41
response = requests .post (f"{ self .base_url } /" , headers = self ._auth_header (json = True ), json = self .actions )
37
42
response .raise_for_status ()
38
-
43
+
39
44
job_data = response .json ()
40
45
job_data ['status' ] = JobStatus [job_data ['status' ].upper ()]
41
-
46
+
42
47
return JobEntity (** job_data )
43
48
49
+ def run_and_wait (self , interval_ms : int = 1000 ) -> JobEntity :
50
+ job = self .run ()
51
+ while job .status not in [JobStatus .COMPLETED , JobStatus .FAILED ]:
52
+ time .sleep (interval_ms / 1000 )
53
+ job = self .get_job (job .id )
54
+ return job
55
+
44
56
def _auth_header (self , json : bool = False ) -> dict :
45
57
headers = {"Authorization" : f"Bearer { self .secret } " }
46
58
if json :
47
59
headers ['Accept' ] = 'application/json'
48
60
headers ['Content-Type' ] = 'application/json'
49
61
return headers
50
62
51
- def add_action (self , name : str , * values ):
63
+ def _add_action (self , name : str , * values ):
52
64
self .actions .append ({"name" : name , "value" : values })
53
65
54
- # All the actions methods
55
-
56
66
def merge_add (self , source : str ):
57
- self .add_action ('mergeAdd' , source )
58
- return self
59
-
60
-
67
+ return self ._add_action ('mergeAdd' , source )
68
+
69
+ def add_input (self , source : str ):
70
+ return self ._add_action ('addInput' , source )
71
+
72
+ def input (self , source : str ):
73
+ return self ._add_action ('input' , source )
74
+
75
+ def with_input_format (self , format_name : str ):
76
+ return self ._add_action ('withInputFormat' , format_name )
77
+
78
+ def input_format (self , format_name : str ):
79
+ return self ._add_action ('inputFormat' , format_name )
80
+
81
+ def from_format (self , format_name : str ):
82
+ return self ._add_action ('fromFormat' , format_name )
83
+
84
+ def with_input_fps (self , fps : int ):
85
+ return self ._add_action ('withInputFps' , fps )
86
+
87
+ def with_fps_input (self , fps : int ):
88
+ return self ._add_action ('withFpsInput' , fps )
89
+
90
+ def input_fps (self , fps : int ):
91
+ return self ._add_action ('inputFPS' , fps )
92
+
93
+ def fps_input (self , fps : int ):
94
+ return self ._add_action ('fpsInput' , fps )
95
+
96
+ def native_framerate (self ):
97
+ return self ._add_action ('nativeFramerate' )
98
+
99
+ def with_native_framerate (self ):
100
+ return self ._add_action ('withNativeFramerate' )
101
+
102
+ def native (self ):
103
+ return self ._add_action ('native' )
104
+
105
+ def set_start_time (self , seek ):
106
+ return self ._add_action ('setStartTime' , seek )
107
+
108
+ def seek_input (self , seek ):
109
+ return self ._add_action ('seekInput' , seek )
110
+
111
+ def loop (self , duration = None ):
112
+ return self ._add_action ('loop' , duration )
113
+
114
+ def with_no_audio (self ):
115
+ return self ._add_action ('withNoAudio' )
116
+
117
+ def no_audio (self ):
118
+ return self ._add_action ('noAudio' )
119
+
120
+ def with_audio_codec (self , codec : str ):
121
+ return self ._add_action ('withAudioCodec' , codec )
122
+
123
+ def audio_codec (self , codec : str ):
124
+ return self ._add_action ('audioCodec' , codec )
125
+
126
+ def with_audio_bitrate (self , bitrate ):
127
+ return self ._add_action ('withAudioBitrate' , bitrate )
128
+
129
+ def audio_bitrate (self , bitrate ):
130
+ return self ._add_action ('audioBitrate' , bitrate )
131
+
132
+ def with_audio_channels (self , channels : int ):
133
+ return self ._add_action ('withAudioChannels' , channels )
134
+
135
+ def audio_channels (self , channels : int ):
136
+ return self ._add_action ('audioChannels' , channels )
137
+
138
+ def with_audio_frequency (self , freq : int ):
139
+ return self ._add_action ('withAudioFrequency' , freq )
140
+
141
+ def audio_frequency (self , freq : int ):
142
+ return self ._add_action ('audioFrequency' , freq )
143
+
144
+ def with_audio_quality (self , quality : int ):
145
+ return self ._add_action ('withAudioQuality' , quality )
146
+
147
+ def audio_quality (self , quality : int ):
148
+ return self ._add_action ('audioQuality' , quality )
149
+
150
+ def with_audio_filter (self , filters ):
151
+ return self ._add_action ('withAudioFilter' , filters )
152
+
153
+ def with_audio_filters (self , filters ):
154
+ return self ._add_action ('withAudioFilters' , filters )
155
+
156
+ def audio_filter (self , filters ):
157
+ return self ._add_action ('audioFilter' , filters )
158
+
159
+ def audio_filters (self , filters ):
160
+ return self ._add_action ('audioFilters' , filters )
161
+
162
+ def with_no_video (self ):
163
+ return self ._add_action ('withNoVideo' )
164
+
165
+ def no_video (self ):
166
+ return self ._add_action ('noVideo' )
167
+
168
+ def with_video_codec (self , codec : str ):
169
+ return self ._add_action ('withVideoCodec' , codec )
170
+
171
+ def video_codec (self , codec : str ):
172
+ return self ._add_action ('videoCodec' , codec )
173
+
174
+ def with_video_bitrate (self , bitrate , constant = None ):
175
+ return self ._add_action ('withVideoBitrate' , bitrate , constant )
176
+
177
+ def video_bitrate (self , bitrate , constant = None ):
178
+ return self ._add_action ('videoBitrate' , bitrate , constant )
179
+
180
+ def with_video_filter (self , filters ):
181
+ return self ._add_action ('withVideoFilter' , filters )
182
+
183
+ def with_video_filters (self , filters ):
184
+ return self ._add_action ('withVideoFilters' , filters )
185
+
186
+ def video_filter (self , filters ):
187
+ return self ._add_action ('videoFilter' , filters )
188
+
189
+ def video_filters (self , filters ):
190
+ return self ._add_action ('videoFilters' , filters )
191
+
192
+ def with_output_fps (self , fps : int ):
193
+ return self ._add_action ('withOutputFps' , fps )
194
+
195
+ def with_fps_output (self , fps : int ):
196
+ return self ._add_action ('withFpsOutput' , fps )
197
+
198
+ def with_fps (self , fps : int ):
199
+ return self ._add_action ('withFps' , fps )
200
+
201
+ def output_fps (self , fps : int ):
202
+ return self ._add_action ('outputFPS' , fps )
203
+
204
+ def fps_output (self , fps : int ):
205
+ return self ._add_action ('fpsOutput' , fps )
206
+
207
+ def fps (self , fps : int ):
208
+ return self ._add_action ('fps' , fps )
209
+
210
+ def take_frames (self , frames : int ):
211
+ return self ._add_action ('takeFrames' , frames )
212
+
213
+ def with_frames (self , frames : int ):
214
+ return self ._add_action ('withFrames' , frames )
215
+
216
+ def frames (self , frames : int ):
217
+ return self ._add_action ('frames' , frames )
218
+
219
+ def keep_pixel_aspect (self ):
220
+ return self ._add_action ('keepPixelAspect' )
221
+
222
+ def keep_display_aspect (self ):
223
+ return self ._add_action ('keepDisplayAspect' )
224
+
225
+ def keep_display_aspect_ratio (self ):
226
+ return self ._add_action ('keepDisplayAspectRatio' )
227
+
228
+ def keep_dar (self ):
229
+ return self ._add_action ('keepDAR' )
230
+
231
+ def with_size (self , size : str ):
232
+ return self ._add_action ('withSize' , size )
233
+
234
+ def set_size (self , size : str ):
235
+ return self ._add_action ('setSize' , size )
236
+
237
+ def size (self , size : str ):
238
+ return self ._add_action ('size' , size )
239
+
240
+ def with_aspect (self , aspect ):
241
+ return self ._add_action ('withAspect' , aspect )
242
+
243
+ def with_aspect_ratio (self , aspect ):
244
+ return self ._add_action ('withAspectRatio' , aspect )
245
+
246
+ def set_aspect (self , aspect ):
247
+ return self ._add_action ('setAspect' , aspect )
248
+
249
+ def set_aspect_ratio (self , aspect ):
250
+ return self ._add_action ('setAspectRatio' , aspect )
251
+
252
+ def aspect (self , aspect ):
253
+ return self ._add_action ('aspect' , aspect )
254
+
255
+ def aspect_ratio (self , aspect ):
256
+ return self ._add_action ('aspectRatio' , aspect )
257
+
258
+ def apply_autopadding (self , pad , color ):
259
+ return self ._add_action ('applyAutopadding' , pad , color )
260
+
261
+ def apply_auto_padding (self , pad , color ):
262
+ return self ._add_action ('applyAutoPadding' , pad , color )
263
+
264
+ def apply_autopad (self , pad , color ):
265
+ return self ._add_action ('applyAutopad' , pad , color )
266
+
267
+ def apply_auto_pad (self , pad , color ):
268
+ return self ._add_action ('applyAutoPad' , pad , color )
269
+
270
+ def with_autopadding (self , pad , color ):
271
+ return self ._add_action ('withAutopadding' , pad , color )
272
+
273
+ def with_auto_padding (self , pad , color ):
274
+ return self ._add_action ('withAutoPadding' , pad , color )
275
+
276
+ def with_autopad (self , pad , color ):
277
+ return self ._add_action ('withAutopad' , pad , color )
278
+
279
+ def with_auto_pad (self , pad , color ):
280
+ return self ._add_action ('withAutoPad' , pad , color )
281
+
282
+ def auto_pad (self , pad , color ):
283
+ return self ._add_action ('autoPad' , pad , color )
284
+
285
+ def autopad (self , pad , color ):
286
+ return self ._add_action ('autopad' , pad , color )
287
+
288
+ def add_output (self , target : str ):
289
+ return self ._add_action ('addOutput' , target )
290
+
291
+ def output (self , target : str ):
292
+ return self ._add_action ('output' , target )
293
+
294
+ def seek_output (self , seek ):
295
+ return self ._add_action ('seekOutput' , seek )
296
+
297
+ def seek (self , seek ):
298
+ return self ._add_action ('seek' , seek )
299
+
300
+ def with_duration (self , duration ):
301
+ return self ._add_action ('withDuration' , duration )
302
+
303
+ def set_duration (self , duration ):
304
+ return self ._add_action ('setDuration' , duration )
305
+
306
+ def duration (self , duration ):
307
+ return self ._add_action ('duration' , duration )
308
+
309
+ def to_format (self , format_name : str ):
310
+ return self ._add_action ('toFormat' , format_name )
311
+
312
+ def with_output_format (self , format_name : str ):
313
+ return self ._add_action ('withOutputFormat' , format_name )
314
+
315
+ def output_format (self , format_name : str ):
316
+ return self ._add_action ('outputFormat' , format_name )
317
+
318
+ def format (self , format_name : str ):
319
+ return self ._add_action ('format' , format_name )
320
+
321
+ def map (self , spec : str ):
322
+ return self ._add_action ('map' , spec )
323
+
324
+ def update_flv_metadata (self ):
325
+ return self ._add_action ('updateFlvMetadata' )
326
+
327
+ def flvmeta (self ):
328
+ return self ._add_action ('flvmeta' )
329
+
330
+ def add_input_option (self , * options ):
331
+ return self ._add_action ('addInputOption' , * options )
332
+
333
+ def with_input_options (self , * options ):
334
+ return self ._add_action ('withInputOptions' , * options )
335
+
336
+ def with_input_option (self , * options ):
337
+ return self ._add_action ('withInputOption' , * options )
338
+
339
+ def input_option (self , * options ):
340
+ return self ._add_action ('inputOption' , * options )
341
+
342
+ def add_input_options (self , * options ):
343
+ return self ._add_action ('addInputOptions' , * options )
344
+
345
+ def add_output_option (self , * options ):
346
+ return self ._add_action ('addOutputOption' , * options )
347
+
348
+ def add_output_options (self , * options ):
349
+ return self ._add_action ('addOutputOptions' , * options )
350
+
351
+ def add_option (self , * options ):
352
+ return self ._add_action ('addOption' , * options )
353
+
354
+ def with_output_option (self , * options ):
355
+ return self ._add_action ('withOutputOption' , * options )
356
+
357
+ def with_output_options (self , * options ):
358
+ return self ._add_action ('withOutputOptions' , * options )
359
+
360
+ def with_option (self , * options ):
361
+ return self ._add_action ('withOption' , * options )
362
+
363
+ def with_options (self , * options ):
364
+ return self ._add_action ('withOptions' , * options )
365
+
366
+ def output_option (self , * options ):
367
+ return self ._add_action ('outputOption' , * options )
368
+
369
+ def output_options (self , * options ):
370
+ return self ._add_action ('outputOptions' , * options )
371
+
372
+ # def filter_graph(self, spec, map=None):
373
+ # return self._add_action('filterGraph', spec, map)
374
+ #
375
+ # def complex_filter(self, spec, map=None):
376
+ # return self._add_action('complexFilter', spec, map)
0 commit comments