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    /// Marks the active stream session as ended for the video.
678    /// Throws VIDEO_NOT_FOUND if no active stream exists.
679    /// Enforces write permission on the video.
680    #[endpoint(
681        method = POST,
682        path = "/video/v1/videos/{videoRid}/streaming/end",
683        name = "endStream",
684        produces = conjure_http::server::StdResponseSerializer
685    )]
686    fn end_stream(
687        &self,
688        #[auth]
689        auth_: conjure_object::BearerToken,
690        #[path(
691            name = "videoRid",
692            decoder = conjure_http::server::conjure::FromPlainDecoder,
693            log_as = "videoRid",
694            safe
695        )]
696        video_rid: super::super::super::super::objects::api::rids::VideoRid,
697    ) -> Result<
698        super::super::super::super::objects::scout::video::api::EndStreamResponse,
699        conjure_http::private::Error,
700    >;
701    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
702    /// Validates JWT and logs session. Future: create video segments from uploaded files.
703    #[endpoint(
704        method = POST,
705        path = "/video/v1/segment/upload",
706        name = "uploadSegmentFromMediaMtx"
707    )]
708    fn upload_segment_from_media_mtx(
709        &self,
710        #[auth]
711        auth_: conjure_object::BearerToken,
712        #[query(
713            name = "streamPath",
714            decoder = conjure_http::server::conjure::FromPlainDecoder,
715            log_as = "streamPath"
716        )]
717        stream_path: String,
718        #[query(
719            name = "filePath",
720            decoder = conjure_http::server::conjure::FromPlainDecoder,
721            log_as = "filePath"
722        )]
723        file_path: String,
724        #[query(
725            name = "duration",
726            decoder = conjure_http::server::conjure::FromPlainDecoder
727        )]
728        duration: String,
729        #[query(
730            name = "minTimestampSeconds",
731            decoder = conjure_http::server::conjure::FromPlainDecoder,
732            log_as = "minTimestampSeconds"
733        )]
734        min_timestamp_seconds: conjure_object::SafeLong,
735        #[query(
736            name = "minTimestampNanos",
737            decoder = conjure_http::server::conjure::FromPlainDecoder,
738            log_as = "minTimestampNanos"
739        )]
740        min_timestamp_nanos: conjure_object::SafeLong,
741        #[header(
742            name = "Content-Length",
743            decoder = conjure_http::server::conjure::FromPlainDecoder,
744            log_as = "contentLength"
745        )]
746        content_length: conjure_object::SafeLong,
747        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
748        body: I,
749    ) -> Result<(), conjure_http::private::Error>;
750}
751/// The video service manages videos and video metadata.
752#[conjure_http::conjure_endpoints(name = "VideoService", use_legacy_error_serialization)]
753pub trait AsyncVideoService<#[request_body] I, #[response_writer] O> {
754    ///The body type returned by the `get_playlist` method.
755    type GetPlaylistBody: conjure_http::server::AsyncWriteBody<O> + 'static + Send;
756    ///The body type returned by the `get_playlist_in_bounds` method.
757    type GetPlaylistInBoundsBody: conjure_http::server::AsyncWriteBody<O>
758        + 'static
759        + Send;
760    ///The body type returned by the `get_playlist_in_bounds_v2` method.
761    type GetPlaylistInBoundsV2Body: conjure_http::server::AsyncWriteBody<O>
762        + 'static
763        + Send;
764    ///The body type returned by the `get_playlist_v2` method.
765    type GetPlaylistV2Body: conjure_http::server::AsyncWriteBody<O> + 'static + Send;
766    /// Returns video metadata associated with a video rid.
767    #[endpoint(
768        method = GET,
769        path = "/video/v1/videos/{videoRid}",
770        name = "get",
771        produces = conjure_http::server::StdResponseSerializer
772    )]
773    async fn get(
774        &self,
775        #[auth]
776        auth_: conjure_object::BearerToken,
777        #[path(
778            name = "videoRid",
779            decoder = conjure_http::server::conjure::FromPlainDecoder,
780            log_as = "videoRid",
781            safe
782        )]
783        video_rid: super::super::super::super::objects::api::rids::VideoRid,
784    ) -> Result<
785        super::super::super::super::objects::scout::video::api::Video,
786        conjure_http::private::Error,
787    >;
788    /// Returns video metadata about each video given a set of video rids.
789    #[endpoint(
790        method = POST,
791        path = "/video/v1/videos/batchGet",
792        name = "batchGet",
793        produces = conjure_http::server::StdResponseSerializer
794    )]
795    async fn batch_get(
796        &self,
797        #[auth]
798        auth_: conjure_object::BearerToken,
799        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
800        request: super::super::super::super::objects::scout::video::api::GetVideosRequest,
801    ) -> Result<
802        super::super::super::super::objects::scout::video::api::GetVideosResponse,
803        conjure_http::private::Error,
804    >;
805    /// Returns metadata about videos that match a given query.
806    #[endpoint(
807        method = POST,
808        path = "/video/v1/videos/search",
809        name = "search",
810        produces = conjure_http::server::StdResponseSerializer
811    )]
812    async fn search(
813        &self,
814        #[auth]
815        auth_: conjure_object::BearerToken,
816        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
817        request: super::super::super::super::objects::scout::video::api::SearchVideosRequest,
818    ) -> Result<
819        super::super::super::super::objects::scout::video::api::SearchVideosResponse,
820        conjure_http::private::Error,
821    >;
822    /// Creates and persists a video entity with the given metadata.
823    #[endpoint(
824        method = POST,
825        path = "/video/v1/videos",
826        name = "create",
827        produces = conjure_http::server::StdResponseSerializer
828    )]
829    async fn create(
830        &self,
831        #[auth]
832        auth_: conjure_object::BearerToken,
833        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
834        request: super::super::super::super::objects::scout::video::api::CreateVideoRequest,
835    ) -> Result<
836        super::super::super::super::objects::scout::video::api::Video,
837        conjure_http::private::Error,
838    >;
839    /// Updates the metadata for a video associated with the given video rid.
840    #[endpoint(
841        method = PUT,
842        path = "/video/v1/videos/{videoRid}",
843        name = "updateMetadata",
844        produces = conjure_http::server::StdResponseSerializer
845    )]
846    async fn update_metadata(
847        &self,
848        #[auth]
849        auth_: conjure_object::BearerToken,
850        #[path(
851            name = "videoRid",
852            decoder = conjure_http::server::conjure::FromPlainDecoder,
853            log_as = "videoRid",
854            safe
855        )]
856        video_rid: super::super::super::super::objects::api::rids::VideoRid,
857        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
858        request: super::super::super::super::objects::scout::video::api::UpdateVideoMetadataRequest,
859    ) -> Result<
860        super::super::super::super::objects::scout::video::api::Video,
861        conjure_http::private::Error,
862    >;
863    #[endpoint(
864        method = PUT,
865        path = "/video/v1/videos/{videoRid}/ingest-status",
866        name = "updateIngestStatus"
867    )]
868    async fn update_ingest_status(
869        &self,
870        #[auth]
871        auth_: conjure_object::BearerToken,
872        #[path(
873            name = "videoRid",
874            decoder = conjure_http::server::conjure::FromPlainDecoder,
875            log_as = "videoRid",
876            safe
877        )]
878        video_rid: super::super::super::super::objects::api::rids::VideoRid,
879        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
880        request: super::super::super::super::objects::scout::video::api::UpdateIngestStatus,
881    ) -> Result<(), conjure_http::private::Error>;
882    #[endpoint(
883        method = GET,
884        path = "/video/v1/videos/{videoRid}/ingest-status",
885        name = "getIngestStatus",
886        produces = conjure_http::server::StdResponseSerializer
887    )]
888    async fn get_ingest_status(
889        &self,
890        #[auth]
891        auth_: conjure_object::BearerToken,
892        #[path(
893            name = "videoRid",
894            decoder = conjure_http::server::conjure::FromPlainDecoder,
895            log_as = "videoRid",
896            safe
897        )]
898        video_rid: super::super::super::super::objects::api::rids::VideoRid,
899    ) -> Result<
900        super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
901        conjure_http::private::Error,
902    >;
903    #[endpoint(
904        method = POST,
905        path = "/video/v1/videos/batch-get-ingest-status",
906        name = "batchGetIngestStatus",
907        produces = conjure_http::server::conjure::CollectionResponseSerializer
908    )]
909    async fn batch_get_ingest_status(
910        &self,
911        #[auth]
912        auth_: conjure_object::BearerToken,
913        #[body(
914            deserializer = conjure_http::server::StdRequestDeserializer,
915            log_as = "videoRids",
916            safe
917        )]
918        video_rids: std::collections::BTreeSet<
919            super::super::super::super::objects::api::rids::VideoRid,
920        >,
921    ) -> Result<
922        std::collections::BTreeMap<
923            super::super::super::super::objects::api::rids::VideoRid,
924            super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
925        >,
926        conjure_http::private::Error,
927    >;
928    #[endpoint(
929        method = POST,
930        path = "/video/v1/videos/enriched-ingest-status",
931        name = "getEnrichedIngestStatus",
932        produces = conjure_http::server::conjure::CollectionResponseSerializer
933    )]
934    async fn get_enriched_ingest_status(
935        &self,
936        #[auth]
937        auth_: conjure_object::BearerToken,
938        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
939        request: super::super::super::super::objects::scout::video::api::GetEnrichedVideoIngestStatusRequest,
940    ) -> Result<
941        Option<
942            super::super::super::super::objects::scout::video::api::EnrichedVideoIngestStatus,
943        >,
944        conjure_http::private::Error,
945    >;
946    /// Archives a video, which excludes it from search and hides it from being publicly visible, but does not
947    /// permanently delete it. Archived videos can be unarchived.
948    #[endpoint(
949        method = PUT,
950        path = "/video/v1/videos/{videoRid}/archive",
951        name = "archive"
952    )]
953    async fn archive(
954        &self,
955        #[auth]
956        auth_: conjure_object::BearerToken,
957        #[path(
958            name = "videoRid",
959            decoder = conjure_http::server::conjure::FromPlainDecoder,
960            log_as = "videoRid",
961            safe
962        )]
963        video_rid: super::super::super::super::objects::api::rids::VideoRid,
964    ) -> Result<(), conjure_http::private::Error>;
965    /// Unarchives a previously archived video.
966    #[endpoint(
967        method = PUT,
968        path = "/video/v1/videos/{videoRid}/unarchive",
969        name = "unarchive"
970    )]
971    async fn unarchive(
972        &self,
973        #[auth]
974        auth_: conjure_object::BearerToken,
975        #[path(
976            name = "videoRid",
977            decoder = conjure_http::server::conjure::FromPlainDecoder,
978            log_as = "videoRid",
979            safe
980        )]
981        video_rid: super::super::super::super::objects::api::rids::VideoRid,
982    ) -> Result<(), conjure_http::private::Error>;
983    /// Generates an HLS playlist for a video within optional time bounds.
984    /// Uses GET with query parameters for HLS.js compatibility.
985    /// The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds,
986    /// or all segments if no bounds are provided.
987    ///
988    /// Note: The start and end parameters must either both be provided or both be omitted.
989    /// Providing only one will result in a MissingTimestampBoundPair error.
990    #[endpoint(
991        method = GET,
992        path = "/video/v1/videos/{videoRid}/playlist",
993        name = "getPlaylist",
994        produces = conjure_http::server::conjure::BinaryResponseSerializer
995    )]
996    async fn get_playlist(
997        &self,
998        #[auth]
999        auth_: conjure_object::BearerToken,
1000        #[path(
1001            name = "videoRid",
1002            decoder = conjure_http::server::conjure::FromPlainDecoder,
1003            log_as = "videoRid",
1004            safe
1005        )]
1006        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1007        #[query(
1008            name = "start",
1009            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1010        )]
1011        start: Option<String>,
1012        #[query(
1013            name = "end",
1014            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1015        )]
1016        end: Option<String>,
1017    ) -> Result<Self::GetPlaylistBody, conjure_http::private::Error>;
1018    /// Returns the min and max absolute and media timestamps for each segment in a video. To be used during
1019    /// frame-timestamp mapping.
1020    #[endpoint(
1021        method = GET,
1022        path = "/video/v1/videos/{videoRid}/segment-summaries",
1023        name = "getSegmentSummaries",
1024        produces = conjure_http::server::conjure::CollectionResponseSerializer
1025    )]
1026    async fn get_segment_summaries(
1027        &self,
1028        #[auth]
1029        auth_: conjure_object::BearerToken,
1030        #[path(
1031            name = "videoRid",
1032            decoder = conjure_http::server::conjure::FromPlainDecoder,
1033            log_as = "videoRid",
1034            safe
1035        )]
1036        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1037    ) -> Result<
1038        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
1039        conjure_http::private::Error,
1040    >;
1041    /// Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of
1042    /// bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given
1043    /// bounds.
1044    /// playlist will be limited to the given bounds.
1045    #[endpoint(
1046        method = POST,
1047        path = "/video/v1/videos/{videoRid}/playlist-in-bounds",
1048        name = "getPlaylistInBounds",
1049        produces = conjure_http::server::conjure::BinaryResponseSerializer
1050    )]
1051    async fn get_playlist_in_bounds(
1052        &self,
1053        #[auth]
1054        auth_: conjure_object::BearerToken,
1055        #[path(
1056            name = "videoRid",
1057            decoder = conjure_http::server::conjure::FromPlainDecoder,
1058            log_as = "videoRid",
1059            safe
1060        )]
1061        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1062        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1063        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsRequest,
1064    ) -> Result<Self::GetPlaylistInBoundsBody, conjure_http::private::Error>;
1065    /// Generates an HLS playlist for a video series (identified by channel + tags) within bounds.
1066    #[endpoint(
1067        method = POST,
1068        path = "/video/v2/videos/playlist-in-bounds",
1069        name = "getPlaylistInBoundsV2",
1070        produces = conjure_http::server::conjure::BinaryResponseSerializer
1071    )]
1072    async fn get_playlist_in_bounds_v2(
1073        &self,
1074        #[auth]
1075        auth_: conjure_object::BearerToken,
1076        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1077        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsForChannelRequest,
1078    ) -> Result<Self::GetPlaylistInBoundsV2Body, conjure_http::private::Error>;
1079    /// Generates an HLS playlist for a video series within time bounds.
1080    /// Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.
1081    ///
1082    /// Note: Both start and end parameters are required and must be provided together.
1083    #[endpoint(
1084        method = GET,
1085        path = "/video/v2/videos/playlist",
1086        name = "getPlaylistV2",
1087        produces = conjure_http::server::conjure::BinaryResponseSerializer
1088    )]
1089    async fn get_playlist_v2(
1090        &self,
1091        #[auth]
1092        auth_: conjure_object::BearerToken,
1093        #[query(
1094            name = "dataSourceRid",
1095            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1096            log_as = "dataSourceRid",
1097            safe
1098        )]
1099        data_source_rid: Option<
1100            super::super::super::super::objects::api::rids::DataSourceRid,
1101        >,
1102        #[query(
1103            name = "assetRid",
1104            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1105            log_as = "assetRid",
1106            safe
1107        )]
1108        asset_rid: Option<
1109            super::super::super::super::objects::scout::rids::api::AssetRid,
1110        >,
1111        #[query(
1112            name = "dataScopeName",
1113            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1114            log_as = "dataScopeName"
1115        )]
1116        data_scope_name: Option<String>,
1117        #[query(
1118            name = "channel",
1119            decoder = conjure_http::server::conjure::FromPlainDecoder
1120        )]
1121        channel: String,
1122        #[query(
1123            name = "tags",
1124            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1125        )]
1126        tags: Option<String>,
1127        #[query(
1128            name = "start",
1129            decoder = conjure_http::server::conjure::FromPlainDecoder
1130        )]
1131        start: String,
1132        #[query(name = "end", decoder = conjure_http::server::conjure::FromPlainDecoder)]
1133        end: String,
1134    ) -> Result<Self::GetPlaylistV2Body, conjure_http::private::Error>;
1135    /// Returns the min and max absolute and media timestamps for each segment in a video that overlap with an
1136    /// optional set of bounds.
1137    #[endpoint(
1138        method = POST,
1139        path = "/video/v1/videos/{videoRid}/segment-summaries-in-bounds",
1140        name = "getSegmentSummariesInBounds",
1141        produces = conjure_http::server::conjure::CollectionResponseSerializer
1142    )]
1143    async fn get_segment_summaries_in_bounds(
1144        &self,
1145        #[auth]
1146        auth_: conjure_object::BearerToken,
1147        #[path(
1148            name = "videoRid",
1149            decoder = conjure_http::server::conjure::FromPlainDecoder,
1150            log_as = "videoRid",
1151            safe
1152        )]
1153        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1154        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1155        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsRequest,
1156    ) -> Result<
1157        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
1158        conjure_http::private::Error,
1159    >;
1160    /// Returns the min and max absolute and media timestamps for each segment matching a video series
1161    /// (identified by channel + tags) within the specified bounds.
1162    #[endpoint(
1163        method = POST,
1164        path = "/video/v2/videos/segment-summaries-in-bounds",
1165        name = "getSegmentSummariesInBoundsV2",
1166        produces = conjure_http::server::conjure::CollectionResponseSerializer
1167    )]
1168    async fn get_segment_summaries_in_bounds_v2(
1169        &self,
1170        #[auth]
1171        auth_: conjure_object::BearerToken,
1172        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1173        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsForChannelRequest,
1174    ) -> Result<
1175        Vec<super::super::super::super::objects::scout::video::api::SegmentSummaryV2>,
1176        conjure_http::private::Error,
1177    >;
1178    /// Returns aggregated segment metadata for a video channel series, including total frames,
1179    /// segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.
1180    #[endpoint(
1181        method = POST,
1182        path = "/video/v2/videos/segment-metadata",
1183        name = "getSegmentMetadataV2",
1184        produces = conjure_http::server::conjure::CollectionResponseSerializer
1185    )]
1186    async fn get_segment_metadata_v2(
1187        &self,
1188        #[auth]
1189        auth_: conjure_object::BearerToken,
1190        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1191        request: super::super::super::super::objects::scout::video::api::GetSegmentMetadataForChannelRequest,
1192    ) -> Result<
1193        Option<
1194            super::super::super::super::objects::scout::video::api::VideoChannelSegmentsMetadata,
1195        >,
1196        conjure_http::private::Error,
1197    >;
1198    /// Returns metadata for the segment within a video series containing the requested absolute timestamp.
1199    #[endpoint(
1200        method = POST,
1201        path = "/video/v2/videos/get-segment-by-timestamp",
1202        name = "getSegmentByTimestampV2",
1203        produces = conjure_http::server::conjure::CollectionResponseSerializer
1204    )]
1205    async fn get_segment_by_timestamp_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::GetSegmentByTimestampV2Request,
1211    ) -> Result<
1212        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
1213        conjure_http::private::Error,
1214    >;
1215    /// Returns metadata for the segment containing the requested absolute timestamp. If no segment contains
1216    /// the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment
1217    /// is found at or after the timestamp.
1218    #[endpoint(
1219        method = POST,
1220        path = "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp",
1221        name = "getSegmentAtOrAfterTimestamp",
1222        produces = conjure_http::server::conjure::CollectionResponseSerializer
1223    )]
1224    async fn get_segment_at_or_after_timestamp(
1225        &self,
1226        #[auth]
1227        auth_: conjure_object::BearerToken,
1228        #[path(
1229            name = "videoRid",
1230            decoder = conjure_http::server::conjure::FromPlainDecoder,
1231            log_as = "videoRid",
1232            safe
1233        )]
1234        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1235        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1236        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampRequest,
1237    ) -> Result<
1238        Option<super::super::super::super::objects::scout::video::api::Segment>,
1239        conjure_http::private::Error,
1240    >;
1241    /// Returns metadata for the segment containing the requested absolute timestamp for a video series
1242    /// (identified by channel + tags). If no segment contains the timestamp, returns the closest segment
1243    /// starting after the timestamp. Returns empty if no segment is found at or after the timestamp.
1244    #[endpoint(
1245        method = POST,
1246        path = "/video/v2/videos/get-segment-at-or-after-timestamp",
1247        name = "getSegmentAtOrAfterTimestampV2",
1248        produces = conjure_http::server::conjure::CollectionResponseSerializer
1249    )]
1250    async fn get_segment_at_or_after_timestamp_v2(
1251        &self,
1252        #[auth]
1253        auth_: conjure_object::BearerToken,
1254        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1255        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampV2Request,
1256    ) -> Result<
1257        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
1258        conjure_http::private::Error,
1259    >;
1260    /// Returns the min and max absolute timestamps from non-archived video files associated with a given video that
1261    /// overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments
1262    /// that are inside or overlap with the bounds.
1263    #[endpoint(
1264        method = POST,
1265        path = "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data",
1266        name = "getFileSummaries",
1267        produces = conjure_http::server::StdResponseSerializer
1268    )]
1269    async fn get_file_summaries(
1270        &self,
1271        #[auth]
1272        auth_: conjure_object::BearerToken,
1273        #[path(
1274            name = "videoRid",
1275            decoder = conjure_http::server::conjure::FromPlainDecoder,
1276            log_as = "videoRid",
1277            safe
1278        )]
1279        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1280        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1281        request: super::super::super::super::objects::scout::video::api::GetFileSummariesRequest,
1282    ) -> Result<
1283        super::super::super::super::objects::scout::video::api::GetFileSummariesResponse,
1284        conjure_http::private::Error,
1285    >;
1286    /// Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers.
1287    /// Enforces write permission on the video.
1288    #[endpoint(
1289        method = POST,
1290        path = "/video/v1/videos/{videoRid}/streaming/whip",
1291        name = "generateWhipStream",
1292        produces = conjure_http::server::StdResponseSerializer
1293    )]
1294    async fn generate_whip_stream(
1295        &self,
1296        #[auth]
1297        auth_: conjure_object::BearerToken,
1298        #[path(
1299            name = "videoRid",
1300            decoder = conjure_http::server::conjure::FromPlainDecoder,
1301            log_as = "videoRid",
1302            safe
1303        )]
1304        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1305    ) -> Result<
1306        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
1307        conjure_http::private::Error,
1308    >;
1309    /// Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with
1310    /// a MediaMTX JWT and ICE servers.
1311    /// Currently only datasource-backed dataset channels are supported.
1312    #[endpoint(
1313        method = POST,
1314        path = "/video/v2/videos/streaming/whip",
1315        name = "generateWhipStreamV2",
1316        produces = conjure_http::server::StdResponseSerializer
1317    )]
1318    async fn generate_whip_stream_v2(
1319        &self,
1320        #[auth]
1321        auth_: conjure_object::BearerToken,
1322        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1323        request: super::super::super::super::objects::scout::video::api::GenerateWhipStreamV2Request,
1324    ) -> Result<
1325        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
1326        conjure_http::private::Error,
1327    >;
1328    /// Returns WHEP URL, ICE servers, and token for playing back the active stream.
1329    /// Returns empty if there is no active stream.
1330    /// Enforces read permission on the video.
1331    #[endpoint(
1332        method = POST,
1333        path = "/video/v1/videos/{videoRid}/streaming/whep",
1334        name = "generateWhepStream",
1335        produces = conjure_http::server::conjure::CollectionResponseSerializer
1336    )]
1337    async fn generate_whep_stream(
1338        &self,
1339        #[auth]
1340        auth_: conjure_object::BearerToken,
1341        #[path(
1342            name = "videoRid",
1343            decoder = conjure_http::server::conjure::FromPlainDecoder,
1344            log_as = "videoRid",
1345            safe
1346        )]
1347        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1348    ) -> Result<
1349        Option<
1350            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
1351        >,
1352        conjure_http::private::Error,
1353    >;
1354    /// Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream.
1355    /// Returns empty if there is no active stream.
1356    /// Currently only datasource-backed dataset channels are supported.
1357    #[endpoint(
1358        method = POST,
1359        path = "/video/v2/videos/streaming/whep",
1360        name = "generateWhepStreamV2",
1361        produces = conjure_http::server::conjure::CollectionResponseSerializer
1362    )]
1363    async fn generate_whep_stream_v2(
1364        &self,
1365        #[auth]
1366        auth_: conjure_object::BearerToken,
1367        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1368        request: super::super::super::super::objects::scout::video::api::GenerateWhepStreamV2Request,
1369    ) -> Result<
1370        Option<
1371            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
1372        >,
1373        conjure_http::private::Error,
1374    >;
1375    /// Returns stream session metadata for a given stream ID scoped to the video.
1376    /// Enforces read permission on the video.
1377    #[endpoint(
1378        method = GET,
1379        path = "/video/v1/videos/{videoRid}/streaming/streams/{streamId}",
1380        name = "getStream",
1381        produces = conjure_http::server::conjure::CollectionResponseSerializer
1382    )]
1383    async fn get_stream(
1384        &self,
1385        #[auth]
1386        auth_: conjure_object::BearerToken,
1387        #[path(
1388            name = "videoRid",
1389            decoder = conjure_http::server::conjure::FromPlainDecoder,
1390            log_as = "videoRid",
1391            safe
1392        )]
1393        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1394        #[path(
1395            name = "streamId",
1396            decoder = conjure_http::server::conjure::FromPlainDecoder,
1397            log_as = "streamId"
1398        )]
1399        stream_id: String,
1400    ) -> Result<
1401        Option<super::super::super::super::objects::scout::video::api::VideoStream>,
1402        conjure_http::private::Error,
1403    >;
1404    /// Returns all stream sessions for a video that overlap with the specified time bounds.
1405    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
1406    /// Enforces read permission on the video.
1407    #[endpoint(
1408        method = POST,
1409        path = "/video/v1/videos/{videoRid}/streaming/streams-in-bounds",
1410        name = "getStreamsInBounds",
1411        produces = conjure_http::server::StdResponseSerializer
1412    )]
1413    async fn get_streams_in_bounds(
1414        &self,
1415        #[auth]
1416        auth_: conjure_object::BearerToken,
1417        #[path(
1418            name = "videoRid",
1419            decoder = conjure_http::server::conjure::FromPlainDecoder,
1420            log_as = "videoRid",
1421            safe
1422        )]
1423        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1424        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1425        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsRequest,
1426    ) -> Result<
1427        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsResponse,
1428        conjure_http::private::Error,
1429    >;
1430    /// Marks the active stream session as ended for the video.
1431    /// Throws VIDEO_NOT_FOUND if no active stream exists.
1432    /// Enforces write permission on the video.
1433    #[endpoint(
1434        method = POST,
1435        path = "/video/v1/videos/{videoRid}/streaming/end",
1436        name = "endStream",
1437        produces = conjure_http::server::StdResponseSerializer
1438    )]
1439    async fn end_stream(
1440        &self,
1441        #[auth]
1442        auth_: conjure_object::BearerToken,
1443        #[path(
1444            name = "videoRid",
1445            decoder = conjure_http::server::conjure::FromPlainDecoder,
1446            log_as = "videoRid",
1447            safe
1448        )]
1449        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1450    ) -> Result<
1451        super::super::super::super::objects::scout::video::api::EndStreamResponse,
1452        conjure_http::private::Error,
1453    >;
1454    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
1455    /// Validates JWT and logs session. Future: create video segments from uploaded files.
1456    #[endpoint(
1457        method = POST,
1458        path = "/video/v1/segment/upload",
1459        name = "uploadSegmentFromMediaMtx"
1460    )]
1461    async fn upload_segment_from_media_mtx(
1462        &self,
1463        #[auth]
1464        auth_: conjure_object::BearerToken,
1465        #[query(
1466            name = "streamPath",
1467            decoder = conjure_http::server::conjure::FromPlainDecoder,
1468            log_as = "streamPath"
1469        )]
1470        stream_path: String,
1471        #[query(
1472            name = "filePath",
1473            decoder = conjure_http::server::conjure::FromPlainDecoder,
1474            log_as = "filePath"
1475        )]
1476        file_path: String,
1477        #[query(
1478            name = "duration",
1479            decoder = conjure_http::server::conjure::FromPlainDecoder
1480        )]
1481        duration: String,
1482        #[query(
1483            name = "minTimestampSeconds",
1484            decoder = conjure_http::server::conjure::FromPlainDecoder,
1485            log_as = "minTimestampSeconds"
1486        )]
1487        min_timestamp_seconds: conjure_object::SafeLong,
1488        #[query(
1489            name = "minTimestampNanos",
1490            decoder = conjure_http::server::conjure::FromPlainDecoder,
1491            log_as = "minTimestampNanos"
1492        )]
1493        min_timestamp_nanos: conjure_object::SafeLong,
1494        #[header(
1495            name = "Content-Length",
1496            decoder = conjure_http::server::conjure::FromPlainDecoder,
1497            log_as = "contentLength"
1498        )]
1499        content_length: conjure_object::SafeLong,
1500        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
1501        body: I,
1502    ) -> Result<(), conjure_http::private::Error>;
1503}
1504/// The video service manages videos and video metadata.
1505#[conjure_http::conjure_endpoints(
1506    name = "VideoService",
1507    use_legacy_error_serialization,
1508    local
1509)]
1510pub trait LocalAsyncVideoService<#[request_body] I, #[response_writer] O> {
1511    ///The body type returned by the `get_playlist` method.
1512    type GetPlaylistBody: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
1513    ///The body type returned by the `get_playlist_in_bounds` method.
1514    type GetPlaylistInBoundsBody: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
1515    ///The body type returned by the `get_playlist_in_bounds_v2` method.
1516    type GetPlaylistInBoundsV2Body: conjure_http::server::LocalAsyncWriteBody<O>
1517        + 'static;
1518    ///The body type returned by the `get_playlist_v2` method.
1519    type GetPlaylistV2Body: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
1520    /// Returns video metadata associated with a video rid.
1521    #[endpoint(
1522        method = GET,
1523        path = "/video/v1/videos/{videoRid}",
1524        name = "get",
1525        produces = conjure_http::server::StdResponseSerializer
1526    )]
1527    async fn get(
1528        &self,
1529        #[auth]
1530        auth_: conjure_object::BearerToken,
1531        #[path(
1532            name = "videoRid",
1533            decoder = conjure_http::server::conjure::FromPlainDecoder,
1534            log_as = "videoRid",
1535            safe
1536        )]
1537        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1538    ) -> Result<
1539        super::super::super::super::objects::scout::video::api::Video,
1540        conjure_http::private::Error,
1541    >;
1542    /// Returns video metadata about each video given a set of video rids.
1543    #[endpoint(
1544        method = POST,
1545        path = "/video/v1/videos/batchGet",
1546        name = "batchGet",
1547        produces = conjure_http::server::StdResponseSerializer
1548    )]
1549    async fn batch_get(
1550        &self,
1551        #[auth]
1552        auth_: conjure_object::BearerToken,
1553        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1554        request: super::super::super::super::objects::scout::video::api::GetVideosRequest,
1555    ) -> Result<
1556        super::super::super::super::objects::scout::video::api::GetVideosResponse,
1557        conjure_http::private::Error,
1558    >;
1559    /// Returns metadata about videos that match a given query.
1560    #[endpoint(
1561        method = POST,
1562        path = "/video/v1/videos/search",
1563        name = "search",
1564        produces = conjure_http::server::StdResponseSerializer
1565    )]
1566    async fn search(
1567        &self,
1568        #[auth]
1569        auth_: conjure_object::BearerToken,
1570        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1571        request: super::super::super::super::objects::scout::video::api::SearchVideosRequest,
1572    ) -> Result<
1573        super::super::super::super::objects::scout::video::api::SearchVideosResponse,
1574        conjure_http::private::Error,
1575    >;
1576    /// Creates and persists a video entity with the given metadata.
1577    #[endpoint(
1578        method = POST,
1579        path = "/video/v1/videos",
1580        name = "create",
1581        produces = conjure_http::server::StdResponseSerializer
1582    )]
1583    async fn create(
1584        &self,
1585        #[auth]
1586        auth_: conjure_object::BearerToken,
1587        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1588        request: super::super::super::super::objects::scout::video::api::CreateVideoRequest,
1589    ) -> Result<
1590        super::super::super::super::objects::scout::video::api::Video,
1591        conjure_http::private::Error,
1592    >;
1593    /// Updates the metadata for a video associated with the given video rid.
1594    #[endpoint(
1595        method = PUT,
1596        path = "/video/v1/videos/{videoRid}",
1597        name = "updateMetadata",
1598        produces = conjure_http::server::StdResponseSerializer
1599    )]
1600    async fn update_metadata(
1601        &self,
1602        #[auth]
1603        auth_: conjure_object::BearerToken,
1604        #[path(
1605            name = "videoRid",
1606            decoder = conjure_http::server::conjure::FromPlainDecoder,
1607            log_as = "videoRid",
1608            safe
1609        )]
1610        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1611        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1612        request: super::super::super::super::objects::scout::video::api::UpdateVideoMetadataRequest,
1613    ) -> Result<
1614        super::super::super::super::objects::scout::video::api::Video,
1615        conjure_http::private::Error,
1616    >;
1617    #[endpoint(
1618        method = PUT,
1619        path = "/video/v1/videos/{videoRid}/ingest-status",
1620        name = "updateIngestStatus"
1621    )]
1622    async fn update_ingest_status(
1623        &self,
1624        #[auth]
1625        auth_: conjure_object::BearerToken,
1626        #[path(
1627            name = "videoRid",
1628            decoder = conjure_http::server::conjure::FromPlainDecoder,
1629            log_as = "videoRid",
1630            safe
1631        )]
1632        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1633        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1634        request: super::super::super::super::objects::scout::video::api::UpdateIngestStatus,
1635    ) -> Result<(), conjure_http::private::Error>;
1636    #[endpoint(
1637        method = GET,
1638        path = "/video/v1/videos/{videoRid}/ingest-status",
1639        name = "getIngestStatus",
1640        produces = conjure_http::server::StdResponseSerializer
1641    )]
1642    async fn get_ingest_status(
1643        &self,
1644        #[auth]
1645        auth_: conjure_object::BearerToken,
1646        #[path(
1647            name = "videoRid",
1648            decoder = conjure_http::server::conjure::FromPlainDecoder,
1649            log_as = "videoRid",
1650            safe
1651        )]
1652        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1653    ) -> Result<
1654        super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
1655        conjure_http::private::Error,
1656    >;
1657    #[endpoint(
1658        method = POST,
1659        path = "/video/v1/videos/batch-get-ingest-status",
1660        name = "batchGetIngestStatus",
1661        produces = conjure_http::server::conjure::CollectionResponseSerializer
1662    )]
1663    async fn batch_get_ingest_status(
1664        &self,
1665        #[auth]
1666        auth_: conjure_object::BearerToken,
1667        #[body(
1668            deserializer = conjure_http::server::StdRequestDeserializer,
1669            log_as = "videoRids",
1670            safe
1671        )]
1672        video_rids: std::collections::BTreeSet<
1673            super::super::super::super::objects::api::rids::VideoRid,
1674        >,
1675    ) -> Result<
1676        std::collections::BTreeMap<
1677            super::super::super::super::objects::api::rids::VideoRid,
1678            super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
1679        >,
1680        conjure_http::private::Error,
1681    >;
1682    #[endpoint(
1683        method = POST,
1684        path = "/video/v1/videos/enriched-ingest-status",
1685        name = "getEnrichedIngestStatus",
1686        produces = conjure_http::server::conjure::CollectionResponseSerializer
1687    )]
1688    async fn get_enriched_ingest_status(
1689        &self,
1690        #[auth]
1691        auth_: conjure_object::BearerToken,
1692        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1693        request: super::super::super::super::objects::scout::video::api::GetEnrichedVideoIngestStatusRequest,
1694    ) -> Result<
1695        Option<
1696            super::super::super::super::objects::scout::video::api::EnrichedVideoIngestStatus,
1697        >,
1698        conjure_http::private::Error,
1699    >;
1700    /// Archives a video, which excludes it from search and hides it from being publicly visible, but does not
1701    /// permanently delete it. Archived videos can be unarchived.
1702    #[endpoint(
1703        method = PUT,
1704        path = "/video/v1/videos/{videoRid}/archive",
1705        name = "archive"
1706    )]
1707    async fn archive(
1708        &self,
1709        #[auth]
1710        auth_: conjure_object::BearerToken,
1711        #[path(
1712            name = "videoRid",
1713            decoder = conjure_http::server::conjure::FromPlainDecoder,
1714            log_as = "videoRid",
1715            safe
1716        )]
1717        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1718    ) -> Result<(), conjure_http::private::Error>;
1719    /// Unarchives a previously archived video.
1720    #[endpoint(
1721        method = PUT,
1722        path = "/video/v1/videos/{videoRid}/unarchive",
1723        name = "unarchive"
1724    )]
1725    async fn unarchive(
1726        &self,
1727        #[auth]
1728        auth_: conjure_object::BearerToken,
1729        #[path(
1730            name = "videoRid",
1731            decoder = conjure_http::server::conjure::FromPlainDecoder,
1732            log_as = "videoRid",
1733            safe
1734        )]
1735        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1736    ) -> Result<(), conjure_http::private::Error>;
1737    /// Generates an HLS playlist for a video within optional time bounds.
1738    /// Uses GET with query parameters for HLS.js compatibility.
1739    /// The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds,
1740    /// or all segments if no bounds are provided.
1741    ///
1742    /// Note: The start and end parameters must either both be provided or both be omitted.
1743    /// Providing only one will result in a MissingTimestampBoundPair error.
1744    #[endpoint(
1745        method = GET,
1746        path = "/video/v1/videos/{videoRid}/playlist",
1747        name = "getPlaylist",
1748        produces = conjure_http::server::conjure::BinaryResponseSerializer
1749    )]
1750    async fn get_playlist(
1751        &self,
1752        #[auth]
1753        auth_: conjure_object::BearerToken,
1754        #[path(
1755            name = "videoRid",
1756            decoder = conjure_http::server::conjure::FromPlainDecoder,
1757            log_as = "videoRid",
1758            safe
1759        )]
1760        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1761        #[query(
1762            name = "start",
1763            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1764        )]
1765        start: Option<String>,
1766        #[query(
1767            name = "end",
1768            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1769        )]
1770        end: Option<String>,
1771    ) -> Result<Self::GetPlaylistBody, conjure_http::private::Error>;
1772    /// Returns the min and max absolute and media timestamps for each segment in a video. To be used during
1773    /// frame-timestamp mapping.
1774    #[endpoint(
1775        method = GET,
1776        path = "/video/v1/videos/{videoRid}/segment-summaries",
1777        name = "getSegmentSummaries",
1778        produces = conjure_http::server::conjure::CollectionResponseSerializer
1779    )]
1780    async fn get_segment_summaries(
1781        &self,
1782        #[auth]
1783        auth_: conjure_object::BearerToken,
1784        #[path(
1785            name = "videoRid",
1786            decoder = conjure_http::server::conjure::FromPlainDecoder,
1787            log_as = "videoRid",
1788            safe
1789        )]
1790        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1791    ) -> Result<
1792        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
1793        conjure_http::private::Error,
1794    >;
1795    /// Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of
1796    /// bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given
1797    /// bounds.
1798    /// playlist will be limited to the given bounds.
1799    #[endpoint(
1800        method = POST,
1801        path = "/video/v1/videos/{videoRid}/playlist-in-bounds",
1802        name = "getPlaylistInBounds",
1803        produces = conjure_http::server::conjure::BinaryResponseSerializer
1804    )]
1805    async fn get_playlist_in_bounds(
1806        &self,
1807        #[auth]
1808        auth_: conjure_object::BearerToken,
1809        #[path(
1810            name = "videoRid",
1811            decoder = conjure_http::server::conjure::FromPlainDecoder,
1812            log_as = "videoRid",
1813            safe
1814        )]
1815        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1816        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1817        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsRequest,
1818    ) -> Result<Self::GetPlaylistInBoundsBody, conjure_http::private::Error>;
1819    /// Generates an HLS playlist for a video series (identified by channel + tags) within bounds.
1820    #[endpoint(
1821        method = POST,
1822        path = "/video/v2/videos/playlist-in-bounds",
1823        name = "getPlaylistInBoundsV2",
1824        produces = conjure_http::server::conjure::BinaryResponseSerializer
1825    )]
1826    async fn get_playlist_in_bounds_v2(
1827        &self,
1828        #[auth]
1829        auth_: conjure_object::BearerToken,
1830        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1831        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsForChannelRequest,
1832    ) -> Result<Self::GetPlaylistInBoundsV2Body, conjure_http::private::Error>;
1833    /// Generates an HLS playlist for a video series within time bounds.
1834    /// Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.
1835    ///
1836    /// Note: Both start and end parameters are required and must be provided together.
1837    #[endpoint(
1838        method = GET,
1839        path = "/video/v2/videos/playlist",
1840        name = "getPlaylistV2",
1841        produces = conjure_http::server::conjure::BinaryResponseSerializer
1842    )]
1843    async fn get_playlist_v2(
1844        &self,
1845        #[auth]
1846        auth_: conjure_object::BearerToken,
1847        #[query(
1848            name = "dataSourceRid",
1849            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1850            log_as = "dataSourceRid",
1851            safe
1852        )]
1853        data_source_rid: Option<
1854            super::super::super::super::objects::api::rids::DataSourceRid,
1855        >,
1856        #[query(
1857            name = "assetRid",
1858            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1859            log_as = "assetRid",
1860            safe
1861        )]
1862        asset_rid: Option<
1863            super::super::super::super::objects::scout::rids::api::AssetRid,
1864        >,
1865        #[query(
1866            name = "dataScopeName",
1867            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
1868            log_as = "dataScopeName"
1869        )]
1870        data_scope_name: Option<String>,
1871        #[query(
1872            name = "channel",
1873            decoder = conjure_http::server::conjure::FromPlainDecoder
1874        )]
1875        channel: String,
1876        #[query(
1877            name = "tags",
1878            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
1879        )]
1880        tags: Option<String>,
1881        #[query(
1882            name = "start",
1883            decoder = conjure_http::server::conjure::FromPlainDecoder
1884        )]
1885        start: String,
1886        #[query(name = "end", decoder = conjure_http::server::conjure::FromPlainDecoder)]
1887        end: String,
1888    ) -> Result<Self::GetPlaylistV2Body, conjure_http::private::Error>;
1889    /// Returns the min and max absolute and media timestamps for each segment in a video that overlap with an
1890    /// optional set of bounds.
1891    #[endpoint(
1892        method = POST,
1893        path = "/video/v1/videos/{videoRid}/segment-summaries-in-bounds",
1894        name = "getSegmentSummariesInBounds",
1895        produces = conjure_http::server::conjure::CollectionResponseSerializer
1896    )]
1897    async fn get_segment_summaries_in_bounds(
1898        &self,
1899        #[auth]
1900        auth_: conjure_object::BearerToken,
1901        #[path(
1902            name = "videoRid",
1903            decoder = conjure_http::server::conjure::FromPlainDecoder,
1904            log_as = "videoRid",
1905            safe
1906        )]
1907        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1908        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1909        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsRequest,
1910    ) -> Result<
1911        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
1912        conjure_http::private::Error,
1913    >;
1914    /// Returns the min and max absolute and media timestamps for each segment matching a video series
1915    /// (identified by channel + tags) within the specified bounds.
1916    #[endpoint(
1917        method = POST,
1918        path = "/video/v2/videos/segment-summaries-in-bounds",
1919        name = "getSegmentSummariesInBoundsV2",
1920        produces = conjure_http::server::conjure::CollectionResponseSerializer
1921    )]
1922    async fn get_segment_summaries_in_bounds_v2(
1923        &self,
1924        #[auth]
1925        auth_: conjure_object::BearerToken,
1926        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1927        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsForChannelRequest,
1928    ) -> Result<
1929        Vec<super::super::super::super::objects::scout::video::api::SegmentSummaryV2>,
1930        conjure_http::private::Error,
1931    >;
1932    /// Returns aggregated segment metadata for a video channel series, including total frames,
1933    /// segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.
1934    #[endpoint(
1935        method = POST,
1936        path = "/video/v2/videos/segment-metadata",
1937        name = "getSegmentMetadataV2",
1938        produces = conjure_http::server::conjure::CollectionResponseSerializer
1939    )]
1940    async fn get_segment_metadata_v2(
1941        &self,
1942        #[auth]
1943        auth_: conjure_object::BearerToken,
1944        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1945        request: super::super::super::super::objects::scout::video::api::GetSegmentMetadataForChannelRequest,
1946    ) -> Result<
1947        Option<
1948            super::super::super::super::objects::scout::video::api::VideoChannelSegmentsMetadata,
1949        >,
1950        conjure_http::private::Error,
1951    >;
1952    /// Returns metadata for the segment within a video series containing the requested absolute timestamp.
1953    #[endpoint(
1954        method = POST,
1955        path = "/video/v2/videos/get-segment-by-timestamp",
1956        name = "getSegmentByTimestampV2",
1957        produces = conjure_http::server::conjure::CollectionResponseSerializer
1958    )]
1959    async fn get_segment_by_timestamp_v2(
1960        &self,
1961        #[auth]
1962        auth_: conjure_object::BearerToken,
1963        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
1964        request: super::super::super::super::objects::scout::video::api::GetSegmentByTimestampV2Request,
1965    ) -> Result<
1966        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
1967        conjure_http::private::Error,
1968    >;
1969    /// Returns metadata for the segment containing the requested absolute timestamp. If no segment contains
1970    /// the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment
1971    /// is found at or after the timestamp.
1972    #[endpoint(
1973        method = POST,
1974        path = "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp",
1975        name = "getSegmentAtOrAfterTimestamp",
1976        produces = conjure_http::server::conjure::CollectionResponseSerializer
1977    )]
1978    async fn get_segment_at_or_after_timestamp(
1979        &self,
1980        #[auth]
1981        auth_: conjure_object::BearerToken,
1982        #[path(
1983            name = "videoRid",
1984            decoder = conjure_http::server::conjure::FromPlainDecoder,
1985            log_as = "videoRid",
1986            safe
1987        )]
1988        video_rid: super::super::super::super::objects::api::rids::VideoRid,
1989        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
1990        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampRequest,
1991    ) -> Result<
1992        Option<super::super::super::super::objects::scout::video::api::Segment>,
1993        conjure_http::private::Error,
1994    >;
1995    /// Returns metadata for the segment containing the requested absolute timestamp for a video series
1996    /// (identified by channel + tags). If no segment contains the timestamp, returns the closest segment
1997    /// starting after the timestamp. Returns empty if no segment is found at or after the timestamp.
1998    #[endpoint(
1999        method = POST,
2000        path = "/video/v2/videos/get-segment-at-or-after-timestamp",
2001        name = "getSegmentAtOrAfterTimestampV2",
2002        produces = conjure_http::server::conjure::CollectionResponseSerializer
2003    )]
2004    async fn get_segment_at_or_after_timestamp_v2(
2005        &self,
2006        #[auth]
2007        auth_: conjure_object::BearerToken,
2008        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
2009        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampV2Request,
2010    ) -> Result<
2011        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
2012        conjure_http::private::Error,
2013    >;
2014    /// Returns the min and max absolute timestamps from non-archived video files associated with a given video that
2015    /// overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments
2016    /// that are inside or overlap with the bounds.
2017    #[endpoint(
2018        method = POST,
2019        path = "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data",
2020        name = "getFileSummaries",
2021        produces = conjure_http::server::StdResponseSerializer
2022    )]
2023    async fn get_file_summaries(
2024        &self,
2025        #[auth]
2026        auth_: conjure_object::BearerToken,
2027        #[path(
2028            name = "videoRid",
2029            decoder = conjure_http::server::conjure::FromPlainDecoder,
2030            log_as = "videoRid",
2031            safe
2032        )]
2033        video_rid: super::super::super::super::objects::api::rids::VideoRid,
2034        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
2035        request: super::super::super::super::objects::scout::video::api::GetFileSummariesRequest,
2036    ) -> Result<
2037        super::super::super::super::objects::scout::video::api::GetFileSummariesResponse,
2038        conjure_http::private::Error,
2039    >;
2040    /// Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers.
2041    /// Enforces write permission on the video.
2042    #[endpoint(
2043        method = POST,
2044        path = "/video/v1/videos/{videoRid}/streaming/whip",
2045        name = "generateWhipStream",
2046        produces = conjure_http::server::StdResponseSerializer
2047    )]
2048    async fn generate_whip_stream(
2049        &self,
2050        #[auth]
2051        auth_: conjure_object::BearerToken,
2052        #[path(
2053            name = "videoRid",
2054            decoder = conjure_http::server::conjure::FromPlainDecoder,
2055            log_as = "videoRid",
2056            safe
2057        )]
2058        video_rid: super::super::super::super::objects::api::rids::VideoRid,
2059    ) -> Result<
2060        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
2061        conjure_http::private::Error,
2062    >;
2063    /// Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with
2064    /// a MediaMTX JWT and ICE servers.
2065    /// Currently only datasource-backed dataset channels are supported.
2066    #[endpoint(
2067        method = POST,
2068        path = "/video/v2/videos/streaming/whip",
2069        name = "generateWhipStreamV2",
2070        produces = conjure_http::server::StdResponseSerializer
2071    )]
2072    async fn generate_whip_stream_v2(
2073        &self,
2074        #[auth]
2075        auth_: conjure_object::BearerToken,
2076        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
2077        request: super::super::super::super::objects::scout::video::api::GenerateWhipStreamV2Request,
2078    ) -> Result<
2079        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
2080        conjure_http::private::Error,
2081    >;
2082    /// Returns WHEP URL, ICE servers, and token for playing back the active stream.
2083    /// Returns empty if there is no active stream.
2084    /// Enforces read permission on the video.
2085    #[endpoint(
2086        method = POST,
2087        path = "/video/v1/videos/{videoRid}/streaming/whep",
2088        name = "generateWhepStream",
2089        produces = conjure_http::server::conjure::CollectionResponseSerializer
2090    )]
2091    async fn generate_whep_stream(
2092        &self,
2093        #[auth]
2094        auth_: conjure_object::BearerToken,
2095        #[path(
2096            name = "videoRid",
2097            decoder = conjure_http::server::conjure::FromPlainDecoder,
2098            log_as = "videoRid",
2099            safe
2100        )]
2101        video_rid: super::super::super::super::objects::api::rids::VideoRid,
2102    ) -> Result<
2103        Option<
2104            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
2105        >,
2106        conjure_http::private::Error,
2107    >;
2108    /// Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream.
2109    /// Returns empty if there is no active stream.
2110    /// Currently only datasource-backed dataset channels are supported.
2111    #[endpoint(
2112        method = POST,
2113        path = "/video/v2/videos/streaming/whep",
2114        name = "generateWhepStreamV2",
2115        produces = conjure_http::server::conjure::CollectionResponseSerializer
2116    )]
2117    async fn generate_whep_stream_v2(
2118        &self,
2119        #[auth]
2120        auth_: conjure_object::BearerToken,
2121        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
2122        request: super::super::super::super::objects::scout::video::api::GenerateWhepStreamV2Request,
2123    ) -> Result<
2124        Option<
2125            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
2126        >,
2127        conjure_http::private::Error,
2128    >;
2129    /// Returns stream session metadata for a given stream ID scoped to the video.
2130    /// Enforces read permission on the video.
2131    #[endpoint(
2132        method = GET,
2133        path = "/video/v1/videos/{videoRid}/streaming/streams/{streamId}",
2134        name = "getStream",
2135        produces = conjure_http::server::conjure::CollectionResponseSerializer
2136    )]
2137    async fn get_stream(
2138        &self,
2139        #[auth]
2140        auth_: conjure_object::BearerToken,
2141        #[path(
2142            name = "videoRid",
2143            decoder = conjure_http::server::conjure::FromPlainDecoder,
2144            log_as = "videoRid",
2145            safe
2146        )]
2147        video_rid: super::super::super::super::objects::api::rids::VideoRid,
2148        #[path(
2149            name = "streamId",
2150            decoder = conjure_http::server::conjure::FromPlainDecoder,
2151            log_as = "streamId"
2152        )]
2153        stream_id: String,
2154    ) -> Result<
2155        Option<super::super::super::super::objects::scout::video::api::VideoStream>,
2156        conjure_http::private::Error,
2157    >;
2158    /// Returns all stream sessions for a video that overlap with the specified time bounds.
2159    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
2160    /// Enforces read permission on the video.
2161    #[endpoint(
2162        method = POST,
2163        path = "/video/v1/videos/{videoRid}/streaming/streams-in-bounds",
2164        name = "getStreamsInBounds",
2165        produces = conjure_http::server::StdResponseSerializer
2166    )]
2167    async fn get_streams_in_bounds(
2168        &self,
2169        #[auth]
2170        auth_: conjure_object::BearerToken,
2171        #[path(
2172            name = "videoRid",
2173            decoder = conjure_http::server::conjure::FromPlainDecoder,
2174            log_as = "videoRid",
2175            safe
2176        )]
2177        video_rid: super::super::super::super::objects::api::rids::VideoRid,
2178        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
2179        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsRequest,
2180    ) -> Result<
2181        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsResponse,
2182        conjure_http::private::Error,
2183    >;
2184    /// Marks the active stream session as ended for the video.
2185    /// Throws VIDEO_NOT_FOUND if no active stream exists.
2186    /// Enforces write permission on the video.
2187    #[endpoint(
2188        method = POST,
2189        path = "/video/v1/videos/{videoRid}/streaming/end",
2190        name = "endStream",
2191        produces = conjure_http::server::StdResponseSerializer
2192    )]
2193    async fn end_stream(
2194        &self,
2195        #[auth]
2196        auth_: conjure_object::BearerToken,
2197        #[path(
2198            name = "videoRid",
2199            decoder = conjure_http::server::conjure::FromPlainDecoder,
2200            log_as = "videoRid",
2201            safe
2202        )]
2203        video_rid: super::super::super::super::objects::api::rids::VideoRid,
2204    ) -> Result<
2205        super::super::super::super::objects::scout::video::api::EndStreamResponse,
2206        conjure_http::private::Error,
2207    >;
2208    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
2209    /// Validates JWT and logs session. Future: create video segments from uploaded files.
2210    #[endpoint(
2211        method = POST,
2212        path = "/video/v1/segment/upload",
2213        name = "uploadSegmentFromMediaMtx"
2214    )]
2215    async fn upload_segment_from_media_mtx(
2216        &self,
2217        #[auth]
2218        auth_: conjure_object::BearerToken,
2219        #[query(
2220            name = "streamPath",
2221            decoder = conjure_http::server::conjure::FromPlainDecoder,
2222            log_as = "streamPath"
2223        )]
2224        stream_path: String,
2225        #[query(
2226            name = "filePath",
2227            decoder = conjure_http::server::conjure::FromPlainDecoder,
2228            log_as = "filePath"
2229        )]
2230        file_path: String,
2231        #[query(
2232            name = "duration",
2233            decoder = conjure_http::server::conjure::FromPlainDecoder
2234        )]
2235        duration: String,
2236        #[query(
2237            name = "minTimestampSeconds",
2238            decoder = conjure_http::server::conjure::FromPlainDecoder,
2239            log_as = "minTimestampSeconds"
2240        )]
2241        min_timestamp_seconds: conjure_object::SafeLong,
2242        #[query(
2243            name = "minTimestampNanos",
2244            decoder = conjure_http::server::conjure::FromPlainDecoder,
2245            log_as = "minTimestampNanos"
2246        )]
2247        min_timestamp_nanos: conjure_object::SafeLong,
2248        #[header(
2249            name = "Content-Length",
2250            decoder = conjure_http::server::conjure::FromPlainDecoder,
2251            log_as = "contentLength"
2252        )]
2253        content_length: conjure_object::SafeLong,
2254        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
2255        body: I,
2256    ) -> Result<(), conjure_http::private::Error>;
2257}