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