Skip to main content

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

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