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