Skip to main content

nominal_api/conjure/endpoints/scout/video/
video_service.rs

1use conjure_http::endpoint;
2/// The video service manages videos and video metadata.
3#[conjure_http::conjure_endpoints(name = "VideoService", use_legacy_error_serialization)]
4pub trait VideoService<#[request_body] I, #[response_writer] O> {
5    ///The body type returned by the `get_playlist` method.
6    type GetPlaylistBody: conjure_http::server::WriteBody<O> + 'static;
7    ///The body type returned by the `get_playlist_in_bounds` method.
8    type GetPlaylistInBoundsBody: conjure_http::server::WriteBody<O> + 'static;
9    ///The body type returned by the `get_playlist_in_bounds_v2` method.
10    type GetPlaylistInBoundsV2Body: conjure_http::server::WriteBody<O> + 'static;
11    ///The body type returned by the `get_playlist_v2` method.
12    type GetPlaylistV2Body: conjure_http::server::WriteBody<O> + 'static;
13    /// Returns video metadata associated with a video rid.
14    #[endpoint(
15        method = GET,
16        path = "/video/v1/videos/{videoRid}",
17        name = "get",
18        produces = conjure_http::server::StdResponseSerializer
19    )]
20    fn get(
21        &self,
22        #[auth]
23        auth_: conjure_object::BearerToken,
24        #[path(
25            name = "videoRid",
26            decoder = conjure_http::server::conjure::FromPlainDecoder,
27            log_as = "videoRid"
28        )]
29        video_rid: conjure_object::ResourceIdentifier,
30    ) -> Result<
31        super::super::super::super::objects::scout::video::api::Video,
32        conjure_http::private::Error,
33    >;
34    /// Returns video metadata about each video given a set of video rids.
35    #[endpoint(
36        method = POST,
37        path = "/video/v1/videos/batchGet",
38        name = "batchGet",
39        produces = conjure_http::server::StdResponseSerializer
40    )]
41    fn batch_get(
42        &self,
43        #[auth]
44        auth_: conjure_object::BearerToken,
45        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
46        request: super::super::super::super::objects::scout::video::api::GetVideosRequest,
47    ) -> Result<
48        super::super::super::super::objects::scout::video::api::GetVideosResponse,
49        conjure_http::private::Error,
50    >;
51    /// Returns metadata about videos that match a given query.
52    #[endpoint(
53        method = POST,
54        path = "/video/v1/videos/search",
55        name = "search",
56        produces = conjure_http::server::StdResponseSerializer
57    )]
58    fn search(
59        &self,
60        #[auth]
61        auth_: conjure_object::BearerToken,
62        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
63        request: super::super::super::super::objects::scout::video::api::SearchVideosRequest,
64    ) -> Result<
65        super::super::super::super::objects::scout::video::api::SearchVideosResponse,
66        conjure_http::private::Error,
67    >;
68    /// Creates and persists a video entity with the given metadata.
69    #[endpoint(
70        method = POST,
71        path = "/video/v1/videos",
72        name = "create",
73        produces = conjure_http::server::StdResponseSerializer
74    )]
75    fn create(
76        &self,
77        #[auth]
78        auth_: conjure_object::BearerToken,
79        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
80        request: super::super::super::super::objects::scout::video::api::CreateVideoRequest,
81    ) -> Result<
82        super::super::super::super::objects::scout::video::api::Video,
83        conjure_http::private::Error,
84    >;
85    /// Updates the metadata for a video associated with the given video rid.
86    #[endpoint(
87        method = PUT,
88        path = "/video/v1/videos/{videoRid}",
89        name = "updateMetadata",
90        produces = conjure_http::server::StdResponseSerializer
91    )]
92    fn update_metadata(
93        &self,
94        #[auth]
95        auth_: conjure_object::BearerToken,
96        #[path(
97            name = "videoRid",
98            decoder = conjure_http::server::conjure::FromPlainDecoder,
99            log_as = "videoRid"
100        )]
101        video_rid: conjure_object::ResourceIdentifier,
102        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
103        request: super::super::super::super::objects::scout::video::api::UpdateVideoMetadataRequest,
104    ) -> Result<
105        super::super::super::super::objects::scout::video::api::Video,
106        conjure_http::private::Error,
107    >;
108    #[endpoint(
109        method = PUT,
110        path = "/video/v1/videos/{videoRid}/ingest-status",
111        name = "updateIngestStatus"
112    )]
113    fn update_ingest_status(
114        &self,
115        #[auth]
116        auth_: conjure_object::BearerToken,
117        #[path(
118            name = "videoRid",
119            decoder = conjure_http::server::conjure::FromPlainDecoder,
120            log_as = "videoRid"
121        )]
122        video_rid: conjure_object::ResourceIdentifier,
123        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
124        request: super::super::super::super::objects::scout::video::api::UpdateIngestStatus,
125    ) -> Result<(), conjure_http::private::Error>;
126    #[endpoint(
127        method = GET,
128        path = "/video/v1/videos/{videoRid}/ingest-status",
129        name = "getIngestStatus",
130        produces = conjure_http::server::StdResponseSerializer
131    )]
132    fn get_ingest_status(
133        &self,
134        #[auth]
135        auth_: conjure_object::BearerToken,
136        #[path(
137            name = "videoRid",
138            decoder = conjure_http::server::conjure::FromPlainDecoder,
139            log_as = "videoRid"
140        )]
141        video_rid: conjure_object::ResourceIdentifier,
142    ) -> Result<
143        super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
144        conjure_http::private::Error,
145    >;
146    #[endpoint(
147        method = POST,
148        path = "/video/v1/videos/batch-get-ingest-status",
149        name = "batchGetIngestStatus",
150        produces = conjure_http::server::conjure::CollectionResponseSerializer
151    )]
152    fn batch_get_ingest_status(
153        &self,
154        #[auth]
155        auth_: conjure_object::BearerToken,
156        #[body(
157            deserializer = conjure_http::server::StdRequestDeserializer,
158            log_as = "videoRids"
159        )]
160        video_rids: std::collections::BTreeSet<conjure_object::ResourceIdentifier>,
161    ) -> Result<
162        std::collections::BTreeMap<
163            conjure_object::ResourceIdentifier,
164            super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
165        >,
166        conjure_http::private::Error,
167    >;
168    #[endpoint(
169        method = POST,
170        path = "/video/v1/videos/enriched-ingest-status",
171        name = "getEnrichedIngestStatus",
172        produces = conjure_http::server::conjure::CollectionResponseSerializer
173    )]
174    fn get_enriched_ingest_status(
175        &self,
176        #[auth]
177        auth_: conjure_object::BearerToken,
178        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
179        request: super::super::super::super::objects::scout::video::api::GetEnrichedVideoIngestStatusRequest,
180    ) -> Result<
181        Option<
182            super::super::super::super::objects::scout::video::api::EnrichedVideoIngestStatus,
183        >,
184        conjure_http::private::Error,
185    >;
186    /// Archives a video, which excludes it from search and hides it from being publicly visible, but does not
187    /// permanently delete it. Archived videos can be unarchived.
188    #[endpoint(
189        method = PUT,
190        path = "/video/v1/videos/{videoRid}/archive",
191        name = "archive"
192    )]
193    fn archive(
194        &self,
195        #[auth]
196        auth_: conjure_object::BearerToken,
197        #[path(
198            name = "videoRid",
199            decoder = conjure_http::server::conjure::FromPlainDecoder,
200            log_as = "videoRid"
201        )]
202        video_rid: conjure_object::ResourceIdentifier,
203    ) -> Result<(), conjure_http::private::Error>;
204    /// Unarchives a previously archived video.
205    #[endpoint(
206        method = PUT,
207        path = "/video/v1/videos/{videoRid}/unarchive",
208        name = "unarchive"
209    )]
210    fn unarchive(
211        &self,
212        #[auth]
213        auth_: conjure_object::BearerToken,
214        #[path(
215            name = "videoRid",
216            decoder = conjure_http::server::conjure::FromPlainDecoder,
217            log_as = "videoRid"
218        )]
219        video_rid: conjure_object::ResourceIdentifier,
220    ) -> Result<(), conjure_http::private::Error>;
221    /// Generates an HLS playlist for a video within optional time bounds.
222    /// Uses GET with query parameters for HLS.js compatibility.
223    /// The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds,
224    /// or all segments if no bounds are provided.
225    ///
226    /// Note: The start and end parameters must either both be provided or both be omitted.
227    /// Providing only one will result in a MissingTimestampBoundPair error.
228    #[endpoint(
229        method = GET,
230        path = "/video/v1/videos/{videoRid}/playlist",
231        name = "getPlaylist",
232        produces = conjure_http::server::conjure::BinaryResponseSerializer
233    )]
234    fn get_playlist(
235        &self,
236        #[auth]
237        auth_: conjure_object::BearerToken,
238        #[path(
239            name = "videoRid",
240            decoder = conjure_http::server::conjure::FromPlainDecoder,
241            log_as = "videoRid"
242        )]
243        video_rid: conjure_object::ResourceIdentifier,
244        #[query(
245            name = "start",
246            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
247        )]
248        start: Option<String>,
249        #[query(
250            name = "end",
251            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
252        )]
253        end: Option<String>,
254    ) -> Result<Self::GetPlaylistBody, conjure_http::private::Error>;
255    /// Returns the min and max absolute and media timestamps for each segment in a video. To be used during
256    /// frame-timestamp mapping.
257    #[endpoint(
258        method = GET,
259        path = "/video/v1/videos/{videoRid}/segment-summaries",
260        name = "getSegmentSummaries",
261        produces = conjure_http::server::conjure::CollectionResponseSerializer
262    )]
263    fn get_segment_summaries(
264        &self,
265        #[auth]
266        auth_: conjure_object::BearerToken,
267        #[path(
268            name = "videoRid",
269            decoder = conjure_http::server::conjure::FromPlainDecoder,
270            log_as = "videoRid"
271        )]
272        video_rid: conjure_object::ResourceIdentifier,
273    ) -> Result<
274        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
275        conjure_http::private::Error,
276    >;
277    /// Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of
278    /// bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given
279    /// bounds.
280    /// playlist will be limited to the given bounds.
281    #[endpoint(
282        method = POST,
283        path = "/video/v1/videos/{videoRid}/playlist-in-bounds",
284        name = "getPlaylistInBounds",
285        produces = conjure_http::server::conjure::BinaryResponseSerializer
286    )]
287    fn get_playlist_in_bounds(
288        &self,
289        #[auth]
290        auth_: conjure_object::BearerToken,
291        #[path(
292            name = "videoRid",
293            decoder = conjure_http::server::conjure::FromPlainDecoder,
294            log_as = "videoRid"
295        )]
296        video_rid: conjure_object::ResourceIdentifier,
297        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
298        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsRequest,
299    ) -> Result<Self::GetPlaylistInBoundsBody, conjure_http::private::Error>;
300    /// Generates an HLS playlist for a video series (identified by channel + tags) within bounds.
301    #[endpoint(
302        method = POST,
303        path = "/video/v2/videos/playlist-in-bounds",
304        name = "getPlaylistInBoundsV2",
305        produces = conjure_http::server::conjure::BinaryResponseSerializer
306    )]
307    fn get_playlist_in_bounds_v2(
308        &self,
309        #[auth]
310        auth_: conjure_object::BearerToken,
311        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
312        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsForChannelRequest,
313    ) -> Result<Self::GetPlaylistInBoundsV2Body, conjure_http::private::Error>;
314    /// Generates an HLS playlist for a video series within time bounds.
315    /// Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.
316    ///
317    /// Note: Both start and end parameters are required and must be provided together.
318    #[endpoint(
319        method = GET,
320        path = "/video/v2/videos/playlist",
321        name = "getPlaylistV2",
322        produces = conjure_http::server::conjure::BinaryResponseSerializer
323    )]
324    fn get_playlist_v2(
325        &self,
326        #[auth]
327        auth_: conjure_object::BearerToken,
328        #[query(
329            name = "dataSourceRid",
330            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
331            log_as = "dataSourceRid"
332        )]
333        data_source_rid: Option<conjure_object::ResourceIdentifier>,
334        #[query(
335            name = "assetRid",
336            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
337            log_as = "assetRid",
338            safe
339        )]
340        asset_rid: Option<
341            super::super::super::super::objects::scout::rids::api::AssetRid,
342        >,
343        #[query(
344            name = "dataScopeName",
345            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
346            log_as = "dataScopeName"
347        )]
348        data_scope_name: Option<String>,
349        #[query(
350            name = "channel",
351            decoder = conjure_http::server::conjure::FromPlainDecoder
352        )]
353        channel: String,
354        #[query(
355            name = "tags",
356            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
357        )]
358        tags: Option<String>,
359        #[query(
360            name = "start",
361            decoder = conjure_http::server::conjure::FromPlainDecoder
362        )]
363        start: String,
364        #[query(name = "end", decoder = conjure_http::server::conjure::FromPlainDecoder)]
365        end: String,
366    ) -> Result<Self::GetPlaylistV2Body, conjure_http::private::Error>;
367    /// Returns the min and max absolute and media timestamps for each segment in a video that overlap with an
368    /// optional set of bounds.
369    #[endpoint(
370        method = POST,
371        path = "/video/v1/videos/{videoRid}/segment-summaries-in-bounds",
372        name = "getSegmentSummariesInBounds",
373        produces = conjure_http::server::conjure::CollectionResponseSerializer
374    )]
375    fn get_segment_summaries_in_bounds(
376        &self,
377        #[auth]
378        auth_: conjure_object::BearerToken,
379        #[path(
380            name = "videoRid",
381            decoder = conjure_http::server::conjure::FromPlainDecoder,
382            log_as = "videoRid"
383        )]
384        video_rid: conjure_object::ResourceIdentifier,
385        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
386        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsRequest,
387    ) -> Result<
388        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
389        conjure_http::private::Error,
390    >;
391    /// Returns the min and max absolute and media timestamps for each segment matching a video series
392    /// (identified by channel + tags) within the specified bounds.
393    #[endpoint(
394        method = POST,
395        path = "/video/v2/videos/segment-summaries-in-bounds",
396        name = "getSegmentSummariesInBoundsV2",
397        produces = conjure_http::server::conjure::CollectionResponseSerializer
398    )]
399    fn get_segment_summaries_in_bounds_v2(
400        &self,
401        #[auth]
402        auth_: conjure_object::BearerToken,
403        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
404        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsForChannelRequest,
405    ) -> Result<
406        Vec<super::super::super::super::objects::scout::video::api::SegmentSummaryV2>,
407        conjure_http::private::Error,
408    >;
409    /// Returns aggregated segment metadata for a video channel series, including total frames,
410    /// segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.
411    #[endpoint(
412        method = POST,
413        path = "/video/v2/videos/segment-metadata",
414        name = "getSegmentMetadataV2",
415        produces = conjure_http::server::conjure::CollectionResponseSerializer
416    )]
417    fn get_segment_metadata_v2(
418        &self,
419        #[auth]
420        auth_: conjure_object::BearerToken,
421        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
422        request: super::super::super::super::objects::scout::video::api::GetSegmentMetadataForChannelRequest,
423    ) -> Result<
424        Option<
425            super::super::super::super::objects::scout::video::api::VideoChannelSegmentsMetadata,
426        >,
427        conjure_http::private::Error,
428    >;
429    /// Returns metadata for the segment within a video series containing the requested absolute timestamp.
430    #[endpoint(
431        method = POST,
432        path = "/video/v2/videos/get-segment-by-timestamp",
433        name = "getSegmentByTimestampV2",
434        produces = conjure_http::server::conjure::CollectionResponseSerializer
435    )]
436    fn get_segment_by_timestamp_v2(
437        &self,
438        #[auth]
439        auth_: conjure_object::BearerToken,
440        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
441        request: super::super::super::super::objects::scout::video::api::GetSegmentByTimestampV2Request,
442    ) -> Result<
443        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
444        conjure_http::private::Error,
445    >;
446    /// Returns metadata for the segment containing the requested absolute timestamp. If no segment contains
447    /// the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment
448    /// is found at or after the timestamp.
449    #[endpoint(
450        method = POST,
451        path = "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp",
452        name = "getSegmentAtOrAfterTimestamp",
453        produces = conjure_http::server::conjure::CollectionResponseSerializer
454    )]
455    fn get_segment_at_or_after_timestamp(
456        &self,
457        #[auth]
458        auth_: conjure_object::BearerToken,
459        #[path(
460            name = "videoRid",
461            decoder = conjure_http::server::conjure::FromPlainDecoder,
462            log_as = "videoRid"
463        )]
464        video_rid: conjure_object::ResourceIdentifier,
465        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
466        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampRequest,
467    ) -> Result<
468        Option<super::super::super::super::objects::scout::video::api::Segment>,
469        conjure_http::private::Error,
470    >;
471    /// Returns metadata for the segment containing the requested absolute timestamp for a video series
472    /// (identified by channel + tags). If no segment contains the timestamp, returns the closest segment
473    /// starting after the timestamp. Returns empty if no segment is found at or after the timestamp.
474    #[endpoint(
475        method = POST,
476        path = "/video/v2/videos/get-segment-at-or-after-timestamp",
477        name = "getSegmentAtOrAfterTimestampV2",
478        produces = conjure_http::server::conjure::CollectionResponseSerializer
479    )]
480    fn get_segment_at_or_after_timestamp_v2(
481        &self,
482        #[auth]
483        auth_: conjure_object::BearerToken,
484        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
485        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampV2Request,
486    ) -> Result<
487        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
488        conjure_http::private::Error,
489    >;
490    /// Returns the min and max absolute timestamps from non-archived video files associated with a given video that
491    /// overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments
492    /// that are inside or overlap with the bounds.
493    #[endpoint(
494        method = POST,
495        path = "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data",
496        name = "getFileSummaries",
497        produces = conjure_http::server::StdResponseSerializer
498    )]
499    fn get_file_summaries(
500        &self,
501        #[auth]
502        auth_: conjure_object::BearerToken,
503        #[path(
504            name = "videoRid",
505            decoder = conjure_http::server::conjure::FromPlainDecoder,
506            log_as = "videoRid"
507        )]
508        video_rid: conjure_object::ResourceIdentifier,
509        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
510        request: super::super::super::super::objects::scout::video::api::GetFileSummariesRequest,
511    ) -> Result<
512        super::super::super::super::objects::scout::video::api::GetFileSummariesResponse,
513        conjure_http::private::Error,
514    >;
515    /// Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers.
516    /// Enforces write permission on the video.
517    #[endpoint(
518        method = POST,
519        path = "/video/v1/videos/{videoRid}/streaming/whip",
520        name = "generateWhipStream",
521        produces = conjure_http::server::StdResponseSerializer
522    )]
523    fn generate_whip_stream(
524        &self,
525        #[auth]
526        auth_: conjure_object::BearerToken,
527        #[path(
528            name = "videoRid",
529            decoder = conjure_http::server::conjure::FromPlainDecoder,
530            log_as = "videoRid"
531        )]
532        video_rid: conjure_object::ResourceIdentifier,
533    ) -> Result<
534        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
535        conjure_http::private::Error,
536    >;
537    /// Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with
538    /// a MediaMTX JWT and ICE servers.
539    /// Currently only datasource-backed dataset channels are supported.
540    #[endpoint(
541        method = POST,
542        path = "/video/v2/videos/streaming/whip",
543        name = "generateWhipStreamV2",
544        produces = conjure_http::server::StdResponseSerializer
545    )]
546    fn generate_whip_stream_v2(
547        &self,
548        #[auth]
549        auth_: conjure_object::BearerToken,
550        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
551        request: super::super::super::super::objects::scout::video::api::GenerateWhipStreamV2Request,
552    ) -> Result<
553        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
554        conjure_http::private::Error,
555    >;
556    /// Returns WHEP URL, ICE servers, and token for playing back the active stream.
557    /// Returns empty if there is no active stream.
558    /// Enforces read permission on the video.
559    #[endpoint(
560        method = POST,
561        path = "/video/v1/videos/{videoRid}/streaming/whep",
562        name = "generateWhepStream",
563        produces = conjure_http::server::conjure::CollectionResponseSerializer
564    )]
565    fn generate_whep_stream(
566        &self,
567        #[auth]
568        auth_: conjure_object::BearerToken,
569        #[path(
570            name = "videoRid",
571            decoder = conjure_http::server::conjure::FromPlainDecoder,
572            log_as = "videoRid"
573        )]
574        video_rid: conjure_object::ResourceIdentifier,
575    ) -> Result<
576        Option<
577            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
578        >,
579        conjure_http::private::Error,
580    >;
581    /// Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream.
582    /// Returns empty if there is no active stream.
583    /// Currently only datasource-backed dataset channels are supported.
584    #[endpoint(
585        method = POST,
586        path = "/video/v2/videos/streaming/whep",
587        name = "generateWhepStreamV2",
588        produces = conjure_http::server::conjure::CollectionResponseSerializer
589    )]
590    fn generate_whep_stream_v2(
591        &self,
592        #[auth]
593        auth_: conjure_object::BearerToken,
594        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
595        request: super::super::super::super::objects::scout::video::api::GenerateWhepStreamV2Request,
596    ) -> Result<
597        Option<
598            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
599        >,
600        conjure_http::private::Error,
601    >;
602    /// Returns stream session metadata for a given stream ID scoped to the video.
603    /// Enforces read permission on the video.
604    #[endpoint(
605        method = GET,
606        path = "/video/v1/videos/{videoRid}/streaming/streams/{streamId}",
607        name = "getStream",
608        produces = conjure_http::server::conjure::CollectionResponseSerializer
609    )]
610    fn get_stream(
611        &self,
612        #[auth]
613        auth_: conjure_object::BearerToken,
614        #[path(
615            name = "videoRid",
616            decoder = conjure_http::server::conjure::FromPlainDecoder,
617            log_as = "videoRid"
618        )]
619        video_rid: conjure_object::ResourceIdentifier,
620        #[path(
621            name = "streamId",
622            decoder = conjure_http::server::conjure::FromPlainDecoder,
623            log_as = "streamId"
624        )]
625        stream_id: String,
626    ) -> Result<
627        Option<super::super::super::super::objects::scout::video::api::VideoStream>,
628        conjure_http::private::Error,
629    >;
630    /// Returns all stream sessions for a video that overlap with the specified time bounds.
631    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
632    /// Enforces read permission on the video.
633    #[endpoint(
634        method = POST,
635        path = "/video/v1/videos/{videoRid}/streaming/streams-in-bounds",
636        name = "getStreamsInBounds",
637        produces = conjure_http::server::StdResponseSerializer
638    )]
639    fn get_streams_in_bounds(
640        &self,
641        #[auth]
642        auth_: conjure_object::BearerToken,
643        #[path(
644            name = "videoRid",
645            decoder = conjure_http::server::conjure::FromPlainDecoder,
646            log_as = "videoRid"
647        )]
648        video_rid: conjure_object::ResourceIdentifier,
649        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
650        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsRequest,
651    ) -> Result<
652        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsResponse,
653        conjure_http::private::Error,
654    >;
655    /// Returns all channel-backed stream sessions for a dataset/channel that overlap with the specified time bounds.
656    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
657    /// Enforces read metadata permission on the dataset.
658    #[endpoint(
659        method = POST,
660        path = "/video/v2/videos/streaming/streams-in-bounds",
661        name = "getStreamsInBoundsV2",
662        produces = conjure_http::server::StdResponseSerializer
663    )]
664    fn get_streams_in_bounds_v2(
665        &self,
666        #[auth]
667        auth_: conjure_object::BearerToken,
668        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
669        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsForChannelRequest,
670    ) -> Result<
671        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsV2Response,
672        conjure_http::private::Error,
673    >;
674    /// Marks the active stream session as ended for the video.
675    /// Throws VIDEO_NOT_FOUND if no active stream exists.
676    /// Enforces write permission on the video.
677    #[endpoint(
678        method = POST,
679        path = "/video/v1/videos/{videoRid}/streaming/end",
680        name = "endStream",
681        produces = conjure_http::server::StdResponseSerializer
682    )]
683    fn end_stream(
684        &self,
685        #[auth]
686        auth_: conjure_object::BearerToken,
687        #[path(
688            name = "videoRid",
689            decoder = conjure_http::server::conjure::FromPlainDecoder,
690            log_as = "videoRid"
691        )]
692        video_rid: conjure_object::ResourceIdentifier,
693    ) -> Result<
694        super::super::super::super::objects::scout::video::api::EndStreamResponse,
695        conjure_http::private::Error,
696    >;
697    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
698    /// Validates JWT and logs session. Future: create video segments from uploaded files.
699    #[endpoint(
700        method = POST,
701        path = "/video/v1/segment/upload",
702        name = "uploadSegmentFromMediaMtx"
703    )]
704    fn upload_segment_from_media_mtx(
705        &self,
706        #[auth]
707        auth_: conjure_object::BearerToken,
708        #[query(
709            name = "streamPath",
710            decoder = conjure_http::server::conjure::FromPlainDecoder,
711            log_as = "streamPath"
712        )]
713        stream_path: String,
714        #[query(
715            name = "filePath",
716            decoder = conjure_http::server::conjure::FromPlainDecoder,
717            log_as = "filePath"
718        )]
719        file_path: String,
720        #[query(
721            name = "duration",
722            decoder = conjure_http::server::conjure::FromPlainDecoder
723        )]
724        duration: String,
725        #[query(
726            name = "minTimestampSeconds",
727            decoder = conjure_http::server::conjure::FromPlainDecoder,
728            log_as = "minTimestampSeconds"
729        )]
730        min_timestamp_seconds: conjure_object::SafeLong,
731        #[query(
732            name = "minTimestampNanos",
733            decoder = conjure_http::server::conjure::FromPlainDecoder,
734            log_as = "minTimestampNanos"
735        )]
736        min_timestamp_nanos: conjure_object::SafeLong,
737        #[header(
738            name = "Content-Length",
739            decoder = conjure_http::server::conjure::FromPlainDecoder,
740            log_as = "contentLength"
741        )]
742        content_length: conjure_object::SafeLong,
743        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
744        body: I,
745    ) -> Result<(), conjure_http::private::Error>;
746}
747/// The video service manages videos and video metadata.
748#[conjure_http::conjure_endpoints(name = "VideoService", use_legacy_error_serialization)]
749pub trait AsyncVideoService<#[request_body] I, #[response_writer] O> {
750    ///The body type returned by the `get_playlist` method.
751    type GetPlaylistBody: conjure_http::server::AsyncWriteBody<O> + 'static + Send;
752    ///The body type returned by the `get_playlist_in_bounds` method.
753    type GetPlaylistInBoundsBody: conjure_http::server::AsyncWriteBody<O>
754        + 'static
755        + Send;
756    ///The body type returned by the `get_playlist_in_bounds_v2` method.
757    type GetPlaylistInBoundsV2Body: conjure_http::server::AsyncWriteBody<O>
758        + 'static
759        + Send;
760    ///The body type returned by the `get_playlist_v2` method.
761    type GetPlaylistV2Body: conjure_http::server::AsyncWriteBody<O> + 'static + Send;
762    /// Returns video metadata associated with a video rid.
763    #[endpoint(
764        method = GET,
765        path = "/video/v1/videos/{videoRid}",
766        name = "get",
767        produces = conjure_http::server::StdResponseSerializer
768    )]
769    async fn get(
770        &self,
771        #[auth]
772        auth_: conjure_object::BearerToken,
773        #[path(
774            name = "videoRid",
775            decoder = conjure_http::server::conjure::FromPlainDecoder,
776            log_as = "videoRid"
777        )]
778        video_rid: conjure_object::ResourceIdentifier,
779    ) -> Result<
780        super::super::super::super::objects::scout::video::api::Video,
781        conjure_http::private::Error,
782    >;
783    /// Returns video metadata about each video given a set of video rids.
784    #[endpoint(
785        method = POST,
786        path = "/video/v1/videos/batchGet",
787        name = "batchGet",
788        produces = conjure_http::server::StdResponseSerializer
789    )]
790    async fn batch_get(
791        &self,
792        #[auth]
793        auth_: conjure_object::BearerToken,
794        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
795        request: super::super::super::super::objects::scout::video::api::GetVideosRequest,
796    ) -> Result<
797        super::super::super::super::objects::scout::video::api::GetVideosResponse,
798        conjure_http::private::Error,
799    >;
800    /// Returns metadata about videos that match a given query.
801    #[endpoint(
802        method = POST,
803        path = "/video/v1/videos/search",
804        name = "search",
805        produces = conjure_http::server::StdResponseSerializer
806    )]
807    async fn search(
808        &self,
809        #[auth]
810        auth_: conjure_object::BearerToken,
811        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
812        request: super::super::super::super::objects::scout::video::api::SearchVideosRequest,
813    ) -> Result<
814        super::super::super::super::objects::scout::video::api::SearchVideosResponse,
815        conjure_http::private::Error,
816    >;
817    /// Creates and persists a video entity with the given metadata.
818    #[endpoint(
819        method = POST,
820        path = "/video/v1/videos",
821        name = "create",
822        produces = conjure_http::server::StdResponseSerializer
823    )]
824    async fn create(
825        &self,
826        #[auth]
827        auth_: conjure_object::BearerToken,
828        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
829        request: super::super::super::super::objects::scout::video::api::CreateVideoRequest,
830    ) -> Result<
831        super::super::super::super::objects::scout::video::api::Video,
832        conjure_http::private::Error,
833    >;
834    /// Updates the metadata for a video associated with the given video rid.
835    #[endpoint(
836        method = PUT,
837        path = "/video/v1/videos/{videoRid}",
838        name = "updateMetadata",
839        produces = conjure_http::server::StdResponseSerializer
840    )]
841    async fn update_metadata(
842        &self,
843        #[auth]
844        auth_: conjure_object::BearerToken,
845        #[path(
846            name = "videoRid",
847            decoder = conjure_http::server::conjure::FromPlainDecoder,
848            log_as = "videoRid"
849        )]
850        video_rid: conjure_object::ResourceIdentifier,
851        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
852        request: super::super::super::super::objects::scout::video::api::UpdateVideoMetadataRequest,
853    ) -> Result<
854        super::super::super::super::objects::scout::video::api::Video,
855        conjure_http::private::Error,
856    >;
857    #[endpoint(
858        method = PUT,
859        path = "/video/v1/videos/{videoRid}/ingest-status",
860        name = "updateIngestStatus"
861    )]
862    async fn update_ingest_status(
863        &self,
864        #[auth]
865        auth_: conjure_object::BearerToken,
866        #[path(
867            name = "videoRid",
868            decoder = conjure_http::server::conjure::FromPlainDecoder,
869            log_as = "videoRid"
870        )]
871        video_rid: conjure_object::ResourceIdentifier,
872        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
873        request: super::super::super::super::objects::scout::video::api::UpdateIngestStatus,
874    ) -> Result<(), conjure_http::private::Error>;
875    #[endpoint(
876        method = GET,
877        path = "/video/v1/videos/{videoRid}/ingest-status",
878        name = "getIngestStatus",
879        produces = conjure_http::server::StdResponseSerializer
880    )]
881    async fn get_ingest_status(
882        &self,
883        #[auth]
884        auth_: conjure_object::BearerToken,
885        #[path(
886            name = "videoRid",
887            decoder = conjure_http::server::conjure::FromPlainDecoder,
888            log_as = "videoRid"
889        )]
890        video_rid: conjure_object::ResourceIdentifier,
891    ) -> Result<
892        super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
893        conjure_http::private::Error,
894    >;
895    #[endpoint(
896        method = POST,
897        path = "/video/v1/videos/batch-get-ingest-status",
898        name = "batchGetIngestStatus",
899        produces = conjure_http::server::conjure::CollectionResponseSerializer
900    )]
901    async fn batch_get_ingest_status(
902        &self,
903        #[auth]
904        auth_: conjure_object::BearerToken,
905        #[body(
906            deserializer = conjure_http::server::StdRequestDeserializer,
907            log_as = "videoRids"
908        )]
909        video_rids: std::collections::BTreeSet<conjure_object::ResourceIdentifier>,
910    ) -> Result<
911        std::collections::BTreeMap<
912            conjure_object::ResourceIdentifier,
913            super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
914        >,
915        conjure_http::private::Error,
916    >;
917    #[endpoint(
918        method = POST,
919        path = "/video/v1/videos/enriched-ingest-status",
920        name = "getEnrichedIngestStatus",
921        produces = conjure_http::server::conjure::CollectionResponseSerializer
922    )]
923    async fn get_enriched_ingest_status(
924        &self,
925        #[auth]
926        auth_: conjure_object::BearerToken,
927        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
928        request: super::super::super::super::objects::scout::video::api::GetEnrichedVideoIngestStatusRequest,
929    ) -> Result<
930        Option<
931            super::super::super::super::objects::scout::video::api::EnrichedVideoIngestStatus,
932        >,
933        conjure_http::private::Error,
934    >;
935    /// Archives a video, which excludes it from search and hides it from being publicly visible, but does not
936    /// permanently delete it. Archived videos can be unarchived.
937    #[endpoint(
938        method = PUT,
939        path = "/video/v1/videos/{videoRid}/archive",
940        name = "archive"
941    )]
942    async fn archive(
943        &self,
944        #[auth]
945        auth_: conjure_object::BearerToken,
946        #[path(
947            name = "videoRid",
948            decoder = conjure_http::server::conjure::FromPlainDecoder,
949            log_as = "videoRid"
950        )]
951        video_rid: conjure_object::ResourceIdentifier,
952    ) -> Result<(), conjure_http::private::Error>;
953    /// Unarchives a previously archived video.
954    #[endpoint(
955        method = PUT,
956        path = "/video/v1/videos/{videoRid}/unarchive",
957        name = "unarchive"
958    )]
959    async fn unarchive(
960        &self,
961        #[auth]
962        auth_: conjure_object::BearerToken,
963        #[path(
964            name = "videoRid",
965            decoder = conjure_http::server::conjure::FromPlainDecoder,
966            log_as = "videoRid"
967        )]
968        video_rid: conjure_object::ResourceIdentifier,
969    ) -> Result<(), conjure_http::private::Error>;
970    /// Generates an HLS playlist for a video within optional time bounds.
971    /// Uses GET with query parameters for HLS.js compatibility.
972    /// The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds,
973    /// or all segments if no bounds are provided.
974    ///
975    /// Note: The start and end parameters must either both be provided or both be omitted.
976    /// Providing only one will result in a MissingTimestampBoundPair error.
977    #[endpoint(
978        method = GET,
979        path = "/video/v1/videos/{videoRid}/playlist",
980        name = "getPlaylist",
981        produces = conjure_http::server::conjure::BinaryResponseSerializer
982    )]
983    async fn get_playlist(
984        &self,
985        #[auth]
986        auth_: conjure_object::BearerToken,
987        #[path(
988            name = "videoRid",
989            decoder = conjure_http::server::conjure::FromPlainDecoder,
990            log_as = "videoRid"
991        )]
992        video_rid: conjure_object::ResourceIdentifier,
993        #[query(
994            name = "start",
995            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
996        )]
997        start: Option<String>,
998        #[query(
999            name = "end",
1000            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1001        )]
1002        end: Option<String>,
1003    ) -> Result<Self::GetPlaylistBody, conjure_http::private::Error>;
1004    /// Returns the min and max absolute and media timestamps for each segment in a video. To be used during
1005    /// frame-timestamp mapping.
1006    #[endpoint(
1007        method = GET,
1008        path = "/video/v1/videos/{videoRid}/segment-summaries",
1009        name = "getSegmentSummaries",
1010        produces = conjure_http::server::conjure::CollectionResponseSerializer
1011    )]
1012    async fn get_segment_summaries(
1013        &self,
1014        #[auth]
1015        auth_: conjure_object::BearerToken,
1016        #[path(
1017            name = "videoRid",
1018            decoder = conjure_http::server::conjure::FromPlainDecoder,
1019            log_as = "videoRid"
1020        )]
1021        video_rid: conjure_object::ResourceIdentifier,
1022    ) -> Result<
1023        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
1024        conjure_http::private::Error,
1025    >;
1026    /// Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of
1027    /// bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given
1028    /// bounds.
1029    /// playlist will be limited to the given bounds.
1030    #[endpoint(
1031        method = POST,
1032        path = "/video/v1/videos/{videoRid}/playlist-in-bounds",
1033        name = "getPlaylistInBounds",
1034        produces = conjure_http::server::conjure::BinaryResponseSerializer
1035    )]
1036    async fn get_playlist_in_bounds(
1037        &self,
1038        #[auth]
1039        auth_: conjure_object::BearerToken,
1040        #[path(
1041            name = "videoRid",
1042            decoder = conjure_http::server::conjure::FromPlainDecoder,
1043            log_as = "videoRid"
1044        )]
1045        video_rid: conjure_object::ResourceIdentifier,
1046        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1047        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsRequest,
1048    ) -> Result<Self::GetPlaylistInBoundsBody, conjure_http::private::Error>;
1049    /// Generates an HLS playlist for a video series (identified by channel + tags) within bounds.
1050    #[endpoint(
1051        method = POST,
1052        path = "/video/v2/videos/playlist-in-bounds",
1053        name = "getPlaylistInBoundsV2",
1054        produces = conjure_http::server::conjure::BinaryResponseSerializer
1055    )]
1056    async fn get_playlist_in_bounds_v2(
1057        &self,
1058        #[auth]
1059        auth_: conjure_object::BearerToken,
1060        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1061        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsForChannelRequest,
1062    ) -> Result<Self::GetPlaylistInBoundsV2Body, conjure_http::private::Error>;
1063    /// Generates an HLS playlist for a video series within time bounds.
1064    /// Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.
1065    ///
1066    /// Note: Both start and end parameters are required and must be provided together.
1067    #[endpoint(
1068        method = GET,
1069        path = "/video/v2/videos/playlist",
1070        name = "getPlaylistV2",
1071        produces = conjure_http::server::conjure::BinaryResponseSerializer
1072    )]
1073    async fn get_playlist_v2(
1074        &self,
1075        #[auth]
1076        auth_: conjure_object::BearerToken,
1077        #[query(
1078            name = "dataSourceRid",
1079            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1080            log_as = "dataSourceRid"
1081        )]
1082        data_source_rid: Option<conjure_object::ResourceIdentifier>,
1083        #[query(
1084            name = "assetRid",
1085            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1086            log_as = "assetRid",
1087            safe
1088        )]
1089        asset_rid: Option<
1090            super::super::super::super::objects::scout::rids::api::AssetRid,
1091        >,
1092        #[query(
1093            name = "dataScopeName",
1094            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1095            log_as = "dataScopeName"
1096        )]
1097        data_scope_name: Option<String>,
1098        #[query(
1099            name = "channel",
1100            decoder = conjure_http::server::conjure::FromPlainDecoder
1101        )]
1102        channel: String,
1103        #[query(
1104            name = "tags",
1105            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1106        )]
1107        tags: Option<String>,
1108        #[query(
1109            name = "start",
1110            decoder = conjure_http::server::conjure::FromPlainDecoder
1111        )]
1112        start: String,
1113        #[query(name = "end", decoder = conjure_http::server::conjure::FromPlainDecoder)]
1114        end: String,
1115    ) -> Result<Self::GetPlaylistV2Body, conjure_http::private::Error>;
1116    /// Returns the min and max absolute and media timestamps for each segment in a video that overlap with an
1117    /// optional set of bounds.
1118    #[endpoint(
1119        method = POST,
1120        path = "/video/v1/videos/{videoRid}/segment-summaries-in-bounds",
1121        name = "getSegmentSummariesInBounds",
1122        produces = conjure_http::server::conjure::CollectionResponseSerializer
1123    )]
1124    async fn get_segment_summaries_in_bounds(
1125        &self,
1126        #[auth]
1127        auth_: conjure_object::BearerToken,
1128        #[path(
1129            name = "videoRid",
1130            decoder = conjure_http::server::conjure::FromPlainDecoder,
1131            log_as = "videoRid"
1132        )]
1133        video_rid: conjure_object::ResourceIdentifier,
1134        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1135        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsRequest,
1136    ) -> Result<
1137        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
1138        conjure_http::private::Error,
1139    >;
1140    /// Returns the min and max absolute and media timestamps for each segment matching a video series
1141    /// (identified by channel + tags) within the specified bounds.
1142    #[endpoint(
1143        method = POST,
1144        path = "/video/v2/videos/segment-summaries-in-bounds",
1145        name = "getSegmentSummariesInBoundsV2",
1146        produces = conjure_http::server::conjure::CollectionResponseSerializer
1147    )]
1148    async fn get_segment_summaries_in_bounds_v2(
1149        &self,
1150        #[auth]
1151        auth_: conjure_object::BearerToken,
1152        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1153        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsForChannelRequest,
1154    ) -> Result<
1155        Vec<super::super::super::super::objects::scout::video::api::SegmentSummaryV2>,
1156        conjure_http::private::Error,
1157    >;
1158    /// Returns aggregated segment metadata for a video channel series, including total frames,
1159    /// segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.
1160    #[endpoint(
1161        method = POST,
1162        path = "/video/v2/videos/segment-metadata",
1163        name = "getSegmentMetadataV2",
1164        produces = conjure_http::server::conjure::CollectionResponseSerializer
1165    )]
1166    async fn get_segment_metadata_v2(
1167        &self,
1168        #[auth]
1169        auth_: conjure_object::BearerToken,
1170        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1171        request: super::super::super::super::objects::scout::video::api::GetSegmentMetadataForChannelRequest,
1172    ) -> Result<
1173        Option<
1174            super::super::super::super::objects::scout::video::api::VideoChannelSegmentsMetadata,
1175        >,
1176        conjure_http::private::Error,
1177    >;
1178    /// Returns metadata for the segment within a video series containing the requested absolute timestamp.
1179    #[endpoint(
1180        method = POST,
1181        path = "/video/v2/videos/get-segment-by-timestamp",
1182        name = "getSegmentByTimestampV2",
1183        produces = conjure_http::server::conjure::CollectionResponseSerializer
1184    )]
1185    async fn get_segment_by_timestamp_v2(
1186        &self,
1187        #[auth]
1188        auth_: conjure_object::BearerToken,
1189        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1190        request: super::super::super::super::objects::scout::video::api::GetSegmentByTimestampV2Request,
1191    ) -> Result<
1192        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
1193        conjure_http::private::Error,
1194    >;
1195    /// Returns metadata for the segment containing the requested absolute timestamp. If no segment contains
1196    /// the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment
1197    /// is found at or after the timestamp.
1198    #[endpoint(
1199        method = POST,
1200        path = "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp",
1201        name = "getSegmentAtOrAfterTimestamp",
1202        produces = conjure_http::server::conjure::CollectionResponseSerializer
1203    )]
1204    async fn get_segment_at_or_after_timestamp(
1205        &self,
1206        #[auth]
1207        auth_: conjure_object::BearerToken,
1208        #[path(
1209            name = "videoRid",
1210            decoder = conjure_http::server::conjure::FromPlainDecoder,
1211            log_as = "videoRid"
1212        )]
1213        video_rid: conjure_object::ResourceIdentifier,
1214        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1215        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampRequest,
1216    ) -> Result<
1217        Option<super::super::super::super::objects::scout::video::api::Segment>,
1218        conjure_http::private::Error,
1219    >;
1220    /// Returns metadata for the segment containing the requested absolute timestamp for a video series
1221    /// (identified by channel + tags). If no segment contains the timestamp, returns the closest segment
1222    /// starting after the timestamp. Returns empty if no segment is found at or after the timestamp.
1223    #[endpoint(
1224        method = POST,
1225        path = "/video/v2/videos/get-segment-at-or-after-timestamp",
1226        name = "getSegmentAtOrAfterTimestampV2",
1227        produces = conjure_http::server::conjure::CollectionResponseSerializer
1228    )]
1229    async fn get_segment_at_or_after_timestamp_v2(
1230        &self,
1231        #[auth]
1232        auth_: conjure_object::BearerToken,
1233        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1234        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampV2Request,
1235    ) -> Result<
1236        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
1237        conjure_http::private::Error,
1238    >;
1239    /// Returns the min and max absolute timestamps from non-archived video files associated with a given video that
1240    /// overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments
1241    /// that are inside or overlap with the bounds.
1242    #[endpoint(
1243        method = POST,
1244        path = "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data",
1245        name = "getFileSummaries",
1246        produces = conjure_http::server::StdResponseSerializer
1247    )]
1248    async fn get_file_summaries(
1249        &self,
1250        #[auth]
1251        auth_: conjure_object::BearerToken,
1252        #[path(
1253            name = "videoRid",
1254            decoder = conjure_http::server::conjure::FromPlainDecoder,
1255            log_as = "videoRid"
1256        )]
1257        video_rid: conjure_object::ResourceIdentifier,
1258        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1259        request: super::super::super::super::objects::scout::video::api::GetFileSummariesRequest,
1260    ) -> Result<
1261        super::super::super::super::objects::scout::video::api::GetFileSummariesResponse,
1262        conjure_http::private::Error,
1263    >;
1264    /// Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers.
1265    /// Enforces write permission on the video.
1266    #[endpoint(
1267        method = POST,
1268        path = "/video/v1/videos/{videoRid}/streaming/whip",
1269        name = "generateWhipStream",
1270        produces = conjure_http::server::StdResponseSerializer
1271    )]
1272    async fn generate_whip_stream(
1273        &self,
1274        #[auth]
1275        auth_: conjure_object::BearerToken,
1276        #[path(
1277            name = "videoRid",
1278            decoder = conjure_http::server::conjure::FromPlainDecoder,
1279            log_as = "videoRid"
1280        )]
1281        video_rid: conjure_object::ResourceIdentifier,
1282    ) -> Result<
1283        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
1284        conjure_http::private::Error,
1285    >;
1286    /// Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with
1287    /// a MediaMTX JWT and ICE servers.
1288    /// Currently only datasource-backed dataset channels are supported.
1289    #[endpoint(
1290        method = POST,
1291        path = "/video/v2/videos/streaming/whip",
1292        name = "generateWhipStreamV2",
1293        produces = conjure_http::server::StdResponseSerializer
1294    )]
1295    async fn generate_whip_stream_v2(
1296        &self,
1297        #[auth]
1298        auth_: conjure_object::BearerToken,
1299        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1300        request: super::super::super::super::objects::scout::video::api::GenerateWhipStreamV2Request,
1301    ) -> Result<
1302        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
1303        conjure_http::private::Error,
1304    >;
1305    /// Returns WHEP URL, ICE servers, and token for playing back the active stream.
1306    /// Returns empty if there is no active stream.
1307    /// Enforces read permission on the video.
1308    #[endpoint(
1309        method = POST,
1310        path = "/video/v1/videos/{videoRid}/streaming/whep",
1311        name = "generateWhepStream",
1312        produces = conjure_http::server::conjure::CollectionResponseSerializer
1313    )]
1314    async fn generate_whep_stream(
1315        &self,
1316        #[auth]
1317        auth_: conjure_object::BearerToken,
1318        #[path(
1319            name = "videoRid",
1320            decoder = conjure_http::server::conjure::FromPlainDecoder,
1321            log_as = "videoRid"
1322        )]
1323        video_rid: conjure_object::ResourceIdentifier,
1324    ) -> Result<
1325        Option<
1326            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
1327        >,
1328        conjure_http::private::Error,
1329    >;
1330    /// Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream.
1331    /// Returns empty if there is no active stream.
1332    /// Currently only datasource-backed dataset channels are supported.
1333    #[endpoint(
1334        method = POST,
1335        path = "/video/v2/videos/streaming/whep",
1336        name = "generateWhepStreamV2",
1337        produces = conjure_http::server::conjure::CollectionResponseSerializer
1338    )]
1339    async fn generate_whep_stream_v2(
1340        &self,
1341        #[auth]
1342        auth_: conjure_object::BearerToken,
1343        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1344        request: super::super::super::super::objects::scout::video::api::GenerateWhepStreamV2Request,
1345    ) -> Result<
1346        Option<
1347            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
1348        >,
1349        conjure_http::private::Error,
1350    >;
1351    /// Returns stream session metadata for a given stream ID scoped to the video.
1352    /// Enforces read permission on the video.
1353    #[endpoint(
1354        method = GET,
1355        path = "/video/v1/videos/{videoRid}/streaming/streams/{streamId}",
1356        name = "getStream",
1357        produces = conjure_http::server::conjure::CollectionResponseSerializer
1358    )]
1359    async fn get_stream(
1360        &self,
1361        #[auth]
1362        auth_: conjure_object::BearerToken,
1363        #[path(
1364            name = "videoRid",
1365            decoder = conjure_http::server::conjure::FromPlainDecoder,
1366            log_as = "videoRid"
1367        )]
1368        video_rid: conjure_object::ResourceIdentifier,
1369        #[path(
1370            name = "streamId",
1371            decoder = conjure_http::server::conjure::FromPlainDecoder,
1372            log_as = "streamId"
1373        )]
1374        stream_id: String,
1375    ) -> Result<
1376        Option<super::super::super::super::objects::scout::video::api::VideoStream>,
1377        conjure_http::private::Error,
1378    >;
1379    /// Returns all stream sessions for a video that overlap with the specified time bounds.
1380    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
1381    /// Enforces read permission on the video.
1382    #[endpoint(
1383        method = POST,
1384        path = "/video/v1/videos/{videoRid}/streaming/streams-in-bounds",
1385        name = "getStreamsInBounds",
1386        produces = conjure_http::server::StdResponseSerializer
1387    )]
1388    async fn get_streams_in_bounds(
1389        &self,
1390        #[auth]
1391        auth_: conjure_object::BearerToken,
1392        #[path(
1393            name = "videoRid",
1394            decoder = conjure_http::server::conjure::FromPlainDecoder,
1395            log_as = "videoRid"
1396        )]
1397        video_rid: conjure_object::ResourceIdentifier,
1398        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1399        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsRequest,
1400    ) -> Result<
1401        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsResponse,
1402        conjure_http::private::Error,
1403    >;
1404    /// Returns all channel-backed stream sessions for a dataset/channel that overlap with the specified time bounds.
1405    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
1406    /// Enforces read metadata permission on the dataset.
1407    #[endpoint(
1408        method = POST,
1409        path = "/video/v2/videos/streaming/streams-in-bounds",
1410        name = "getStreamsInBoundsV2",
1411        produces = conjure_http::server::StdResponseSerializer
1412    )]
1413    async fn get_streams_in_bounds_v2(
1414        &self,
1415        #[auth]
1416        auth_: conjure_object::BearerToken,
1417        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1418        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsForChannelRequest,
1419    ) -> Result<
1420        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsV2Response,
1421        conjure_http::private::Error,
1422    >;
1423    /// Marks the active stream session as ended for the video.
1424    /// Throws VIDEO_NOT_FOUND if no active stream exists.
1425    /// Enforces write permission on the video.
1426    #[endpoint(
1427        method = POST,
1428        path = "/video/v1/videos/{videoRid}/streaming/end",
1429        name = "endStream",
1430        produces = conjure_http::server::StdResponseSerializer
1431    )]
1432    async fn end_stream(
1433        &self,
1434        #[auth]
1435        auth_: conjure_object::BearerToken,
1436        #[path(
1437            name = "videoRid",
1438            decoder = conjure_http::server::conjure::FromPlainDecoder,
1439            log_as = "videoRid"
1440        )]
1441        video_rid: conjure_object::ResourceIdentifier,
1442    ) -> Result<
1443        super::super::super::super::objects::scout::video::api::EndStreamResponse,
1444        conjure_http::private::Error,
1445    >;
1446    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
1447    /// Validates JWT and logs session. Future: create video segments from uploaded files.
1448    #[endpoint(
1449        method = POST,
1450        path = "/video/v1/segment/upload",
1451        name = "uploadSegmentFromMediaMtx"
1452    )]
1453    async fn upload_segment_from_media_mtx(
1454        &self,
1455        #[auth]
1456        auth_: conjure_object::BearerToken,
1457        #[query(
1458            name = "streamPath",
1459            decoder = conjure_http::server::conjure::FromPlainDecoder,
1460            log_as = "streamPath"
1461        )]
1462        stream_path: String,
1463        #[query(
1464            name = "filePath",
1465            decoder = conjure_http::server::conjure::FromPlainDecoder,
1466            log_as = "filePath"
1467        )]
1468        file_path: String,
1469        #[query(
1470            name = "duration",
1471            decoder = conjure_http::server::conjure::FromPlainDecoder
1472        )]
1473        duration: String,
1474        #[query(
1475            name = "minTimestampSeconds",
1476            decoder = conjure_http::server::conjure::FromPlainDecoder,
1477            log_as = "minTimestampSeconds"
1478        )]
1479        min_timestamp_seconds: conjure_object::SafeLong,
1480        #[query(
1481            name = "minTimestampNanos",
1482            decoder = conjure_http::server::conjure::FromPlainDecoder,
1483            log_as = "minTimestampNanos"
1484        )]
1485        min_timestamp_nanos: conjure_object::SafeLong,
1486        #[header(
1487            name = "Content-Length",
1488            decoder = conjure_http::server::conjure::FromPlainDecoder,
1489            log_as = "contentLength"
1490        )]
1491        content_length: conjure_object::SafeLong,
1492        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
1493        body: I,
1494    ) -> Result<(), conjure_http::private::Error>;
1495}
1496/// The video service manages videos and video metadata.
1497#[conjure_http::conjure_endpoints(
1498    name = "VideoService",
1499    use_legacy_error_serialization,
1500    local
1501)]
1502pub trait LocalAsyncVideoService<#[request_body] I, #[response_writer] O> {
1503    ///The body type returned by the `get_playlist` method.
1504    type GetPlaylistBody: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
1505    ///The body type returned by the `get_playlist_in_bounds` method.
1506    type GetPlaylistInBoundsBody: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
1507    ///The body type returned by the `get_playlist_in_bounds_v2` method.
1508    type GetPlaylistInBoundsV2Body: conjure_http::server::LocalAsyncWriteBody<O>
1509        + 'static;
1510    ///The body type returned by the `get_playlist_v2` method.
1511    type GetPlaylistV2Body: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
1512    /// Returns video metadata associated with a video rid.
1513    #[endpoint(
1514        method = GET,
1515        path = "/video/v1/videos/{videoRid}",
1516        name = "get",
1517        produces = conjure_http::server::StdResponseSerializer
1518    )]
1519    async fn get(
1520        &self,
1521        #[auth]
1522        auth_: conjure_object::BearerToken,
1523        #[path(
1524            name = "videoRid",
1525            decoder = conjure_http::server::conjure::FromPlainDecoder,
1526            log_as = "videoRid"
1527        )]
1528        video_rid: conjure_object::ResourceIdentifier,
1529    ) -> Result<
1530        super::super::super::super::objects::scout::video::api::Video,
1531        conjure_http::private::Error,
1532    >;
1533    /// Returns video metadata about each video given a set of video rids.
1534    #[endpoint(
1535        method = POST,
1536        path = "/video/v1/videos/batchGet",
1537        name = "batchGet",
1538        produces = conjure_http::server::StdResponseSerializer
1539    )]
1540    async fn batch_get(
1541        &self,
1542        #[auth]
1543        auth_: conjure_object::BearerToken,
1544        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1545        request: super::super::super::super::objects::scout::video::api::GetVideosRequest,
1546    ) -> Result<
1547        super::super::super::super::objects::scout::video::api::GetVideosResponse,
1548        conjure_http::private::Error,
1549    >;
1550    /// Returns metadata about videos that match a given query.
1551    #[endpoint(
1552        method = POST,
1553        path = "/video/v1/videos/search",
1554        name = "search",
1555        produces = conjure_http::server::StdResponseSerializer
1556    )]
1557    async fn search(
1558        &self,
1559        #[auth]
1560        auth_: conjure_object::BearerToken,
1561        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1562        request: super::super::super::super::objects::scout::video::api::SearchVideosRequest,
1563    ) -> Result<
1564        super::super::super::super::objects::scout::video::api::SearchVideosResponse,
1565        conjure_http::private::Error,
1566    >;
1567    /// Creates and persists a video entity with the given metadata.
1568    #[endpoint(
1569        method = POST,
1570        path = "/video/v1/videos",
1571        name = "create",
1572        produces = conjure_http::server::StdResponseSerializer
1573    )]
1574    async fn create(
1575        &self,
1576        #[auth]
1577        auth_: conjure_object::BearerToken,
1578        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1579        request: super::super::super::super::objects::scout::video::api::CreateVideoRequest,
1580    ) -> Result<
1581        super::super::super::super::objects::scout::video::api::Video,
1582        conjure_http::private::Error,
1583    >;
1584    /// Updates the metadata for a video associated with the given video rid.
1585    #[endpoint(
1586        method = PUT,
1587        path = "/video/v1/videos/{videoRid}",
1588        name = "updateMetadata",
1589        produces = conjure_http::server::StdResponseSerializer
1590    )]
1591    async fn update_metadata(
1592        &self,
1593        #[auth]
1594        auth_: conjure_object::BearerToken,
1595        #[path(
1596            name = "videoRid",
1597            decoder = conjure_http::server::conjure::FromPlainDecoder,
1598            log_as = "videoRid"
1599        )]
1600        video_rid: conjure_object::ResourceIdentifier,
1601        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1602        request: super::super::super::super::objects::scout::video::api::UpdateVideoMetadataRequest,
1603    ) -> Result<
1604        super::super::super::super::objects::scout::video::api::Video,
1605        conjure_http::private::Error,
1606    >;
1607    #[endpoint(
1608        method = PUT,
1609        path = "/video/v1/videos/{videoRid}/ingest-status",
1610        name = "updateIngestStatus"
1611    )]
1612    async fn update_ingest_status(
1613        &self,
1614        #[auth]
1615        auth_: conjure_object::BearerToken,
1616        #[path(
1617            name = "videoRid",
1618            decoder = conjure_http::server::conjure::FromPlainDecoder,
1619            log_as = "videoRid"
1620        )]
1621        video_rid: conjure_object::ResourceIdentifier,
1622        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1623        request: super::super::super::super::objects::scout::video::api::UpdateIngestStatus,
1624    ) -> Result<(), conjure_http::private::Error>;
1625    #[endpoint(
1626        method = GET,
1627        path = "/video/v1/videos/{videoRid}/ingest-status",
1628        name = "getIngestStatus",
1629        produces = conjure_http::server::StdResponseSerializer
1630    )]
1631    async fn get_ingest_status(
1632        &self,
1633        #[auth]
1634        auth_: conjure_object::BearerToken,
1635        #[path(
1636            name = "videoRid",
1637            decoder = conjure_http::server::conjure::FromPlainDecoder,
1638            log_as = "videoRid"
1639        )]
1640        video_rid: conjure_object::ResourceIdentifier,
1641    ) -> Result<
1642        super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
1643        conjure_http::private::Error,
1644    >;
1645    #[endpoint(
1646        method = POST,
1647        path = "/video/v1/videos/batch-get-ingest-status",
1648        name = "batchGetIngestStatus",
1649        produces = conjure_http::server::conjure::CollectionResponseSerializer
1650    )]
1651    async fn batch_get_ingest_status(
1652        &self,
1653        #[auth]
1654        auth_: conjure_object::BearerToken,
1655        #[body(
1656            deserializer = conjure_http::server::StdRequestDeserializer,
1657            log_as = "videoRids"
1658        )]
1659        video_rids: std::collections::BTreeSet<conjure_object::ResourceIdentifier>,
1660    ) -> Result<
1661        std::collections::BTreeMap<
1662            conjure_object::ResourceIdentifier,
1663            super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
1664        >,
1665        conjure_http::private::Error,
1666    >;
1667    #[endpoint(
1668        method = POST,
1669        path = "/video/v1/videos/enriched-ingest-status",
1670        name = "getEnrichedIngestStatus",
1671        produces = conjure_http::server::conjure::CollectionResponseSerializer
1672    )]
1673    async fn get_enriched_ingest_status(
1674        &self,
1675        #[auth]
1676        auth_: conjure_object::BearerToken,
1677        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1678        request: super::super::super::super::objects::scout::video::api::GetEnrichedVideoIngestStatusRequest,
1679    ) -> Result<
1680        Option<
1681            super::super::super::super::objects::scout::video::api::EnrichedVideoIngestStatus,
1682        >,
1683        conjure_http::private::Error,
1684    >;
1685    /// Archives a video, which excludes it from search and hides it from being publicly visible, but does not
1686    /// permanently delete it. Archived videos can be unarchived.
1687    #[endpoint(
1688        method = PUT,
1689        path = "/video/v1/videos/{videoRid}/archive",
1690        name = "archive"
1691    )]
1692    async fn archive(
1693        &self,
1694        #[auth]
1695        auth_: conjure_object::BearerToken,
1696        #[path(
1697            name = "videoRid",
1698            decoder = conjure_http::server::conjure::FromPlainDecoder,
1699            log_as = "videoRid"
1700        )]
1701        video_rid: conjure_object::ResourceIdentifier,
1702    ) -> Result<(), conjure_http::private::Error>;
1703    /// Unarchives a previously archived video.
1704    #[endpoint(
1705        method = PUT,
1706        path = "/video/v1/videos/{videoRid}/unarchive",
1707        name = "unarchive"
1708    )]
1709    async fn unarchive(
1710        &self,
1711        #[auth]
1712        auth_: conjure_object::BearerToken,
1713        #[path(
1714            name = "videoRid",
1715            decoder = conjure_http::server::conjure::FromPlainDecoder,
1716            log_as = "videoRid"
1717        )]
1718        video_rid: conjure_object::ResourceIdentifier,
1719    ) -> Result<(), conjure_http::private::Error>;
1720    /// Generates an HLS playlist for a video within optional time bounds.
1721    /// Uses GET with query parameters for HLS.js compatibility.
1722    /// The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds,
1723    /// or all segments if no bounds are provided.
1724    ///
1725    /// Note: The start and end parameters must either both be provided or both be omitted.
1726    /// Providing only one will result in a MissingTimestampBoundPair error.
1727    #[endpoint(
1728        method = GET,
1729        path = "/video/v1/videos/{videoRid}/playlist",
1730        name = "getPlaylist",
1731        produces = conjure_http::server::conjure::BinaryResponseSerializer
1732    )]
1733    async fn get_playlist(
1734        &self,
1735        #[auth]
1736        auth_: conjure_object::BearerToken,
1737        #[path(
1738            name = "videoRid",
1739            decoder = conjure_http::server::conjure::FromPlainDecoder,
1740            log_as = "videoRid"
1741        )]
1742        video_rid: conjure_object::ResourceIdentifier,
1743        #[query(
1744            name = "start",
1745            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1746        )]
1747        start: Option<String>,
1748        #[query(
1749            name = "end",
1750            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1751        )]
1752        end: Option<String>,
1753    ) -> Result<Self::GetPlaylistBody, conjure_http::private::Error>;
1754    /// Returns the min and max absolute and media timestamps for each segment in a video. To be used during
1755    /// frame-timestamp mapping.
1756    #[endpoint(
1757        method = GET,
1758        path = "/video/v1/videos/{videoRid}/segment-summaries",
1759        name = "getSegmentSummaries",
1760        produces = conjure_http::server::conjure::CollectionResponseSerializer
1761    )]
1762    async fn get_segment_summaries(
1763        &self,
1764        #[auth]
1765        auth_: conjure_object::BearerToken,
1766        #[path(
1767            name = "videoRid",
1768            decoder = conjure_http::server::conjure::FromPlainDecoder,
1769            log_as = "videoRid"
1770        )]
1771        video_rid: conjure_object::ResourceIdentifier,
1772    ) -> Result<
1773        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
1774        conjure_http::private::Error,
1775    >;
1776    /// Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of
1777    /// bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given
1778    /// bounds.
1779    /// playlist will be limited to the given bounds.
1780    #[endpoint(
1781        method = POST,
1782        path = "/video/v1/videos/{videoRid}/playlist-in-bounds",
1783        name = "getPlaylistInBounds",
1784        produces = conjure_http::server::conjure::BinaryResponseSerializer
1785    )]
1786    async fn get_playlist_in_bounds(
1787        &self,
1788        #[auth]
1789        auth_: conjure_object::BearerToken,
1790        #[path(
1791            name = "videoRid",
1792            decoder = conjure_http::server::conjure::FromPlainDecoder,
1793            log_as = "videoRid"
1794        )]
1795        video_rid: conjure_object::ResourceIdentifier,
1796        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1797        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsRequest,
1798    ) -> Result<Self::GetPlaylistInBoundsBody, conjure_http::private::Error>;
1799    /// Generates an HLS playlist for a video series (identified by channel + tags) within bounds.
1800    #[endpoint(
1801        method = POST,
1802        path = "/video/v2/videos/playlist-in-bounds",
1803        name = "getPlaylistInBoundsV2",
1804        produces = conjure_http::server::conjure::BinaryResponseSerializer
1805    )]
1806    async fn get_playlist_in_bounds_v2(
1807        &self,
1808        #[auth]
1809        auth_: conjure_object::BearerToken,
1810        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1811        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsForChannelRequest,
1812    ) -> Result<Self::GetPlaylistInBoundsV2Body, conjure_http::private::Error>;
1813    /// Generates an HLS playlist for a video series within time bounds.
1814    /// Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.
1815    ///
1816    /// Note: Both start and end parameters are required and must be provided together.
1817    #[endpoint(
1818        method = GET,
1819        path = "/video/v2/videos/playlist",
1820        name = "getPlaylistV2",
1821        produces = conjure_http::server::conjure::BinaryResponseSerializer
1822    )]
1823    async fn get_playlist_v2(
1824        &self,
1825        #[auth]
1826        auth_: conjure_object::BearerToken,
1827        #[query(
1828            name = "dataSourceRid",
1829            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1830            log_as = "dataSourceRid"
1831        )]
1832        data_source_rid: Option<conjure_object::ResourceIdentifier>,
1833        #[query(
1834            name = "assetRid",
1835            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1836            log_as = "assetRid",
1837            safe
1838        )]
1839        asset_rid: Option<
1840            super::super::super::super::objects::scout::rids::api::AssetRid,
1841        >,
1842        #[query(
1843            name = "dataScopeName",
1844            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1845            log_as = "dataScopeName"
1846        )]
1847        data_scope_name: Option<String>,
1848        #[query(
1849            name = "channel",
1850            decoder = conjure_http::server::conjure::FromPlainDecoder
1851        )]
1852        channel: String,
1853        #[query(
1854            name = "tags",
1855            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1856        )]
1857        tags: Option<String>,
1858        #[query(
1859            name = "start",
1860            decoder = conjure_http::server::conjure::FromPlainDecoder
1861        )]
1862        start: String,
1863        #[query(name = "end", decoder = conjure_http::server::conjure::FromPlainDecoder)]
1864        end: String,
1865    ) -> Result<Self::GetPlaylistV2Body, conjure_http::private::Error>;
1866    /// Returns the min and max absolute and media timestamps for each segment in a video that overlap with an
1867    /// optional set of bounds.
1868    #[endpoint(
1869        method = POST,
1870        path = "/video/v1/videos/{videoRid}/segment-summaries-in-bounds",
1871        name = "getSegmentSummariesInBounds",
1872        produces = conjure_http::server::conjure::CollectionResponseSerializer
1873    )]
1874    async fn get_segment_summaries_in_bounds(
1875        &self,
1876        #[auth]
1877        auth_: conjure_object::BearerToken,
1878        #[path(
1879            name = "videoRid",
1880            decoder = conjure_http::server::conjure::FromPlainDecoder,
1881            log_as = "videoRid"
1882        )]
1883        video_rid: conjure_object::ResourceIdentifier,
1884        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1885        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsRequest,
1886    ) -> Result<
1887        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
1888        conjure_http::private::Error,
1889    >;
1890    /// Returns the min and max absolute and media timestamps for each segment matching a video series
1891    /// (identified by channel + tags) within the specified bounds.
1892    #[endpoint(
1893        method = POST,
1894        path = "/video/v2/videos/segment-summaries-in-bounds",
1895        name = "getSegmentSummariesInBoundsV2",
1896        produces = conjure_http::server::conjure::CollectionResponseSerializer
1897    )]
1898    async fn get_segment_summaries_in_bounds_v2(
1899        &self,
1900        #[auth]
1901        auth_: conjure_object::BearerToken,
1902        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1903        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsForChannelRequest,
1904    ) -> Result<
1905        Vec<super::super::super::super::objects::scout::video::api::SegmentSummaryV2>,
1906        conjure_http::private::Error,
1907    >;
1908    /// Returns aggregated segment metadata for a video channel series, including total frames,
1909    /// segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.
1910    #[endpoint(
1911        method = POST,
1912        path = "/video/v2/videos/segment-metadata",
1913        name = "getSegmentMetadataV2",
1914        produces = conjure_http::server::conjure::CollectionResponseSerializer
1915    )]
1916    async fn get_segment_metadata_v2(
1917        &self,
1918        #[auth]
1919        auth_: conjure_object::BearerToken,
1920        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1921        request: super::super::super::super::objects::scout::video::api::GetSegmentMetadataForChannelRequest,
1922    ) -> Result<
1923        Option<
1924            super::super::super::super::objects::scout::video::api::VideoChannelSegmentsMetadata,
1925        >,
1926        conjure_http::private::Error,
1927    >;
1928    /// Returns metadata for the segment within a video series containing the requested absolute timestamp.
1929    #[endpoint(
1930        method = POST,
1931        path = "/video/v2/videos/get-segment-by-timestamp",
1932        name = "getSegmentByTimestampV2",
1933        produces = conjure_http::server::conjure::CollectionResponseSerializer
1934    )]
1935    async fn get_segment_by_timestamp_v2(
1936        &self,
1937        #[auth]
1938        auth_: conjure_object::BearerToken,
1939        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1940        request: super::super::super::super::objects::scout::video::api::GetSegmentByTimestampV2Request,
1941    ) -> Result<
1942        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
1943        conjure_http::private::Error,
1944    >;
1945    /// Returns metadata for the segment containing the requested absolute timestamp. If no segment contains
1946    /// the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment
1947    /// is found at or after the timestamp.
1948    #[endpoint(
1949        method = POST,
1950        path = "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp",
1951        name = "getSegmentAtOrAfterTimestamp",
1952        produces = conjure_http::server::conjure::CollectionResponseSerializer
1953    )]
1954    async fn get_segment_at_or_after_timestamp(
1955        &self,
1956        #[auth]
1957        auth_: conjure_object::BearerToken,
1958        #[path(
1959            name = "videoRid",
1960            decoder = conjure_http::server::conjure::FromPlainDecoder,
1961            log_as = "videoRid"
1962        )]
1963        video_rid: conjure_object::ResourceIdentifier,
1964        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1965        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampRequest,
1966    ) -> Result<
1967        Option<super::super::super::super::objects::scout::video::api::Segment>,
1968        conjure_http::private::Error,
1969    >;
1970    /// Returns metadata for the segment containing the requested absolute timestamp for a video series
1971    /// (identified by channel + tags). If no segment contains the timestamp, returns the closest segment
1972    /// starting after the timestamp. Returns empty if no segment is found at or after the timestamp.
1973    #[endpoint(
1974        method = POST,
1975        path = "/video/v2/videos/get-segment-at-or-after-timestamp",
1976        name = "getSegmentAtOrAfterTimestampV2",
1977        produces = conjure_http::server::conjure::CollectionResponseSerializer
1978    )]
1979    async fn get_segment_at_or_after_timestamp_v2(
1980        &self,
1981        #[auth]
1982        auth_: conjure_object::BearerToken,
1983        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1984        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampV2Request,
1985    ) -> Result<
1986        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
1987        conjure_http::private::Error,
1988    >;
1989    /// Returns the min and max absolute timestamps from non-archived video files associated with a given video that
1990    /// overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments
1991    /// that are inside or overlap with the bounds.
1992    #[endpoint(
1993        method = POST,
1994        path = "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data",
1995        name = "getFileSummaries",
1996        produces = conjure_http::server::StdResponseSerializer
1997    )]
1998    async fn get_file_summaries(
1999        &self,
2000        #[auth]
2001        auth_: conjure_object::BearerToken,
2002        #[path(
2003            name = "videoRid",
2004            decoder = conjure_http::server::conjure::FromPlainDecoder,
2005            log_as = "videoRid"
2006        )]
2007        video_rid: conjure_object::ResourceIdentifier,
2008        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
2009        request: super::super::super::super::objects::scout::video::api::GetFileSummariesRequest,
2010    ) -> Result<
2011        super::super::super::super::objects::scout::video::api::GetFileSummariesResponse,
2012        conjure_http::private::Error,
2013    >;
2014    /// Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers.
2015    /// Enforces write permission on the video.
2016    #[endpoint(
2017        method = POST,
2018        path = "/video/v1/videos/{videoRid}/streaming/whip",
2019        name = "generateWhipStream",
2020        produces = conjure_http::server::StdResponseSerializer
2021    )]
2022    async fn generate_whip_stream(
2023        &self,
2024        #[auth]
2025        auth_: conjure_object::BearerToken,
2026        #[path(
2027            name = "videoRid",
2028            decoder = conjure_http::server::conjure::FromPlainDecoder,
2029            log_as = "videoRid"
2030        )]
2031        video_rid: conjure_object::ResourceIdentifier,
2032    ) -> Result<
2033        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
2034        conjure_http::private::Error,
2035    >;
2036    /// Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with
2037    /// a MediaMTX JWT and ICE servers.
2038    /// Currently only datasource-backed dataset channels are supported.
2039    #[endpoint(
2040        method = POST,
2041        path = "/video/v2/videos/streaming/whip",
2042        name = "generateWhipStreamV2",
2043        produces = conjure_http::server::StdResponseSerializer
2044    )]
2045    async fn generate_whip_stream_v2(
2046        &self,
2047        #[auth]
2048        auth_: conjure_object::BearerToken,
2049        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
2050        request: super::super::super::super::objects::scout::video::api::GenerateWhipStreamV2Request,
2051    ) -> Result<
2052        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
2053        conjure_http::private::Error,
2054    >;
2055    /// Returns WHEP URL, ICE servers, and token for playing back the active stream.
2056    /// Returns empty if there is no active stream.
2057    /// Enforces read permission on the video.
2058    #[endpoint(
2059        method = POST,
2060        path = "/video/v1/videos/{videoRid}/streaming/whep",
2061        name = "generateWhepStream",
2062        produces = conjure_http::server::conjure::CollectionResponseSerializer
2063    )]
2064    async fn generate_whep_stream(
2065        &self,
2066        #[auth]
2067        auth_: conjure_object::BearerToken,
2068        #[path(
2069            name = "videoRid",
2070            decoder = conjure_http::server::conjure::FromPlainDecoder,
2071            log_as = "videoRid"
2072        )]
2073        video_rid: conjure_object::ResourceIdentifier,
2074    ) -> Result<
2075        Option<
2076            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
2077        >,
2078        conjure_http::private::Error,
2079    >;
2080    /// Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream.
2081    /// Returns empty if there is no active stream.
2082    /// Currently only datasource-backed dataset channels are supported.
2083    #[endpoint(
2084        method = POST,
2085        path = "/video/v2/videos/streaming/whep",
2086        name = "generateWhepStreamV2",
2087        produces = conjure_http::server::conjure::CollectionResponseSerializer
2088    )]
2089    async fn generate_whep_stream_v2(
2090        &self,
2091        #[auth]
2092        auth_: conjure_object::BearerToken,
2093        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
2094        request: super::super::super::super::objects::scout::video::api::GenerateWhepStreamV2Request,
2095    ) -> Result<
2096        Option<
2097            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
2098        >,
2099        conjure_http::private::Error,
2100    >;
2101    /// Returns stream session metadata for a given stream ID scoped to the video.
2102    /// Enforces read permission on the video.
2103    #[endpoint(
2104        method = GET,
2105        path = "/video/v1/videos/{videoRid}/streaming/streams/{streamId}",
2106        name = "getStream",
2107        produces = conjure_http::server::conjure::CollectionResponseSerializer
2108    )]
2109    async fn get_stream(
2110        &self,
2111        #[auth]
2112        auth_: conjure_object::BearerToken,
2113        #[path(
2114            name = "videoRid",
2115            decoder = conjure_http::server::conjure::FromPlainDecoder,
2116            log_as = "videoRid"
2117        )]
2118        video_rid: conjure_object::ResourceIdentifier,
2119        #[path(
2120            name = "streamId",
2121            decoder = conjure_http::server::conjure::FromPlainDecoder,
2122            log_as = "streamId"
2123        )]
2124        stream_id: String,
2125    ) -> Result<
2126        Option<super::super::super::super::objects::scout::video::api::VideoStream>,
2127        conjure_http::private::Error,
2128    >;
2129    /// Returns all stream sessions for a video that overlap with the specified time bounds.
2130    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
2131    /// Enforces read permission on the video.
2132    #[endpoint(
2133        method = POST,
2134        path = "/video/v1/videos/{videoRid}/streaming/streams-in-bounds",
2135        name = "getStreamsInBounds",
2136        produces = conjure_http::server::StdResponseSerializer
2137    )]
2138    async fn get_streams_in_bounds(
2139        &self,
2140        #[auth]
2141        auth_: conjure_object::BearerToken,
2142        #[path(
2143            name = "videoRid",
2144            decoder = conjure_http::server::conjure::FromPlainDecoder,
2145            log_as = "videoRid"
2146        )]
2147        video_rid: conjure_object::ResourceIdentifier,
2148        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
2149        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsRequest,
2150    ) -> Result<
2151        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsResponse,
2152        conjure_http::private::Error,
2153    >;
2154    /// Returns all channel-backed stream sessions for a dataset/channel that overlap with the specified time bounds.
2155    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
2156    /// Enforces read metadata permission on the dataset.
2157    #[endpoint(
2158        method = POST,
2159        path = "/video/v2/videos/streaming/streams-in-bounds",
2160        name = "getStreamsInBoundsV2",
2161        produces = conjure_http::server::StdResponseSerializer
2162    )]
2163    async fn get_streams_in_bounds_v2(
2164        &self,
2165        #[auth]
2166        auth_: conjure_object::BearerToken,
2167        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
2168        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsForChannelRequest,
2169    ) -> Result<
2170        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsV2Response,
2171        conjure_http::private::Error,
2172    >;
2173    /// Marks the active stream session as ended for the video.
2174    /// Throws VIDEO_NOT_FOUND if no active stream exists.
2175    /// Enforces write permission on the video.
2176    #[endpoint(
2177        method = POST,
2178        path = "/video/v1/videos/{videoRid}/streaming/end",
2179        name = "endStream",
2180        produces = conjure_http::server::StdResponseSerializer
2181    )]
2182    async fn end_stream(
2183        &self,
2184        #[auth]
2185        auth_: conjure_object::BearerToken,
2186        #[path(
2187            name = "videoRid",
2188            decoder = conjure_http::server::conjure::FromPlainDecoder,
2189            log_as = "videoRid"
2190        )]
2191        video_rid: conjure_object::ResourceIdentifier,
2192    ) -> Result<
2193        super::super::super::super::objects::scout::video::api::EndStreamResponse,
2194        conjure_http::private::Error,
2195    >;
2196    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
2197    /// Validates JWT and logs session. Future: create video segments from uploaded files.
2198    #[endpoint(
2199        method = POST,
2200        path = "/video/v1/segment/upload",
2201        name = "uploadSegmentFromMediaMtx"
2202    )]
2203    async fn upload_segment_from_media_mtx(
2204        &self,
2205        #[auth]
2206        auth_: conjure_object::BearerToken,
2207        #[query(
2208            name = "streamPath",
2209            decoder = conjure_http::server::conjure::FromPlainDecoder,
2210            log_as = "streamPath"
2211        )]
2212        stream_path: String,
2213        #[query(
2214            name = "filePath",
2215            decoder = conjure_http::server::conjure::FromPlainDecoder,
2216            log_as = "filePath"
2217        )]
2218        file_path: String,
2219        #[query(
2220            name = "duration",
2221            decoder = conjure_http::server::conjure::FromPlainDecoder
2222        )]
2223        duration: String,
2224        #[query(
2225            name = "minTimestampSeconds",
2226            decoder = conjure_http::server::conjure::FromPlainDecoder,
2227            log_as = "minTimestampSeconds"
2228        )]
2229        min_timestamp_seconds: conjure_object::SafeLong,
2230        #[query(
2231            name = "minTimestampNanos",
2232            decoder = conjure_http::server::conjure::FromPlainDecoder,
2233            log_as = "minTimestampNanos"
2234        )]
2235        min_timestamp_nanos: conjure_object::SafeLong,
2236        #[header(
2237            name = "Content-Length",
2238            decoder = conjure_http::server::conjure::FromPlainDecoder,
2239            log_as = "contentLength"
2240        )]
2241        content_length: conjure_object::SafeLong,
2242        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
2243        body: I,
2244    ) -> Result<(), conjure_http::private::Error>;
2245}