use conjure_http::endpoint;
/// The video service manages videos and video metadata.
#[conjure_http::conjure_endpoints(name = "VideoService", use_legacy_error_serialization)]
pub trait VideoService<#[request_body] I, #[response_writer] O> {
    ///The body type returned by the `get_playlist` method.
    type GetPlaylistBody: conjure_http::server::WriteBody<O> + 'static;
    ///The body type returned by the `get_playlist_in_bounds` method.
    type GetPlaylistInBoundsBody: conjure_http::server::WriteBody<O> + 'static;
    ///The body type returned by the `get_playlist_in_bounds_v2` method.
    type GetPlaylistInBoundsV2Body: conjure_http::server::WriteBody<O> + 'static;
    ///The body type returned by the `get_playlist_v2` method.
    type GetPlaylistV2Body: conjure_http::server::WriteBody<O> + 'static;
    /// Returns video metadata associated with a video rid.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}",
        name = "get",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn get(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    /// Returns video metadata about each video given a set of video rids.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/batchGet",
        name = "batchGet",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn batch_get(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetVideosRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetVideosResponse,
        conjure_http::private::Error,
    >;
    /// Returns metadata about videos that match a given query.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/search",
        name = "search",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn search(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::SearchVideosRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::SearchVideosResponse,
        conjure_http::private::Error,
    >;
    /// Creates and persists a video entity with the given metadata.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos",
        name = "create",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn create(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::CreateVideoRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    /// Updates the metadata for a video associated with the given video rid.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}",
        name = "updateMetadata",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn update_metadata(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::UpdateVideoMetadataRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/ingest-status",
        name = "updateIngestStatus"
    )]
    fn update_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::UpdateIngestStatus,
    ) -> Result<(), conjure_http::private::Error>;
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/ingest-status",
        name = "getIngestStatus",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn get_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/batch-get-ingest-status",
        name = "batchGetIngestStatus",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn batch_get_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(
            deserializer = conjure_http::server::StdRequestDeserializer,
            log_as = "videoRids"
        )]
        video_rids: std::collections::BTreeSet<conjure_object::ResourceIdentifier>,
    ) -> Result<
        std::collections::BTreeMap<
            conjure_object::ResourceIdentifier,
            super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
        >,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/enriched-ingest-status",
        name = "getEnrichedIngestStatus",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_enriched_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetEnrichedVideoIngestStatusRequest,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::EnrichedVideoIngestStatus,
        >,
        conjure_http::private::Error,
    >;
    /// Archives a video, which excludes it from search and hides it from being publicly visible, but does not
    /// permanently delete it. Archived videos can be unarchived.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/archive",
        name = "archive"
    )]
    fn archive(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<(), conjure_http::private::Error>;
    /// Unarchives a previously archived video.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/unarchive",
        name = "unarchive"
    )]
    fn unarchive(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<(), conjure_http::private::Error>;
    /// Generates an HLS playlist for a video within optional time bounds.
    /// Uses GET with query parameters for HLS.js compatibility.
    /// The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds,
    /// or all segments if no bounds are provided.
    ///
    /// Note: The start and end parameters must either both be provided or both be omitted.
    /// Providing only one will result in a MissingTimestampBoundPair error.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/playlist",
        name = "getPlaylist",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    fn get_playlist(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[query(
            name = "start",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        start: Option<String>,
        #[query(
            name = "end",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        end: Option<String>,
    ) -> Result<Self::GetPlaylistBody, conjure_http::private::Error>;
    /// Returns the min and max absolute and media timestamps for each segment in a video. To be used during
    /// frame-timestamp mapping.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/segment-summaries",
        name = "getSegmentSummaries",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_segment_summaries(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
        conjure_http::private::Error,
    >;
    /// Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of
    /// bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given
    /// bounds.
    /// playlist will be limited to the given bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/playlist-in-bounds",
        name = "getPlaylistInBounds",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    fn get_playlist_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsRequest,
    ) -> Result<Self::GetPlaylistInBoundsBody, conjure_http::private::Error>;
    /// Generates an HLS playlist for a video series (identified by channel + tags) within bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/playlist-in-bounds",
        name = "getPlaylistInBoundsV2",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    fn get_playlist_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsForChannelRequest,
    ) -> Result<Self::GetPlaylistInBoundsV2Body, conjure_http::private::Error>;
    /// Generates an HLS playlist for a video series within time bounds.
    /// Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.
    ///
    /// Note: Both start and end parameters are required and must be provided together.
    #[endpoint(
        method = GET,
        path = "/video/v2/videos/playlist",
        name = "getPlaylistV2",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    fn get_playlist_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[query(
            name = "dataSourceRid",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "dataSourceRid"
        )]
        data_source_rid: Option<conjure_object::ResourceIdentifier>,
        #[query(
            name = "assetRid",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "assetRid",
            safe
        )]
        asset_rid: Option<
            super::super::super::super::objects::scout::rids::api::AssetRid,
        >,
        #[query(
            name = "dataScopeName",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "dataScopeName"
        )]
        data_scope_name: Option<String>,
        #[query(
            name = "channel",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        channel: String,
        #[query(
            name = "tags",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        tags: Option<String>,
        #[query(
            name = "start",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        start: String,
        #[query(name = "end", decoder = conjure_http::server::conjure::FromPlainDecoder)]
        end: String,
    ) -> Result<Self::GetPlaylistV2Body, conjure_http::private::Error>;
    /// Returns the min and max absolute and media timestamps for each segment in a video that overlap with an
    /// optional set of bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/segment-summaries-in-bounds",
        name = "getSegmentSummariesInBounds",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_segment_summaries_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsRequest,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
        conjure_http::private::Error,
    >;
    /// Returns the min and max absolute and media timestamps for each segment matching a video series
    /// (identified by channel + tags) within the specified bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/segment-summaries-in-bounds",
        name = "getSegmentSummariesInBoundsV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_segment_summaries_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsForChannelRequest,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummaryV2>,
        conjure_http::private::Error,
    >;
    /// Returns aggregated segment metadata for a video channel series, including total frames,
    /// segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/segment-metadata",
        name = "getSegmentMetadataV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_segment_metadata_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentMetadataForChannelRequest,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::VideoChannelSegmentsMetadata,
        >,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment within a video series containing the requested absolute timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/get-segment-by-timestamp",
        name = "getSegmentByTimestampV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_segment_by_timestamp_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentByTimestampV2Request,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment containing the requested absolute timestamp. If no segment contains
    /// the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment
    /// is found at or after the timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp",
        name = "getSegmentAtOrAfterTimestamp",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_segment_at_or_after_timestamp(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampRequest,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::Segment>,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment containing the requested absolute timestamp for a video series
    /// (identified by channel + tags). If no segment contains the timestamp, returns the closest segment
    /// starting after the timestamp. Returns empty if no segment is found at or after the timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/get-segment-at-or-after-timestamp",
        name = "getSegmentAtOrAfterTimestampV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_segment_at_or_after_timestamp_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampV2Request,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
        conjure_http::private::Error,
    >;
    /// Returns the min and max absolute timestamps from non-archived video files associated with a given video that
    /// overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments
    /// that are inside or overlap with the bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data",
        name = "getFileSummaries",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn get_file_summaries(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetFileSummariesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetFileSummariesResponse,
        conjure_http::private::Error,
    >;
    /// Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers.
    /// Enforces write permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/whip",
        name = "generateWhipStream",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn generate_whip_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
        conjure_http::private::Error,
    >;
    /// Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with
    /// a MediaMTX JWT and ICE servers.
    /// Currently only datasource-backed dataset channels are supported.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/whip",
        name = "generateWhipStreamV2",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn generate_whip_stream_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GenerateWhipStreamV2Request,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
        conjure_http::private::Error,
    >;
    /// Returns WHEP URL, ICE servers, and token for playing back the active stream.
    /// Returns empty if there is no active stream.
    /// Enforces read permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/whep",
        name = "generateWhepStream",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn generate_whep_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
        >,
        conjure_http::private::Error,
    >;
    /// Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream.
    /// Returns empty if there is no active stream.
    /// Currently only datasource-backed dataset channels are supported.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/whep",
        name = "generateWhepStreamV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn generate_whep_stream_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GenerateWhepStreamV2Request,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
        >,
        conjure_http::private::Error,
    >;
    /// Returns stream session metadata for a given stream ID scoped to the video.
    /// Enforces read permission on the video.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/streaming/streams/{streamId}",
        name = "getStream",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    fn get_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[path(
            name = "streamId",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "streamId"
        )]
        stream_id: String,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::VideoStream>,
        conjure_http::private::Error,
    >;
    /// Returns all stream sessions for a video that overlap with the specified time bounds.
    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
    /// Enforces read permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/streams-in-bounds",
        name = "getStreamsInBounds",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn get_streams_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsResponse,
        conjure_http::private::Error,
    >;
    /// Returns all channel-backed stream sessions for a dataset/channel that overlap with the specified time bounds.
    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
    /// Enforces read metadata permission on the dataset.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/streams-in-bounds",
        name = "getStreamsInBoundsV2",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn get_streams_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsForChannelRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsV2Response,
        conjure_http::private::Error,
    >;
    /// Returns the dataset files backing a video channel (identified by channel + tags), ordered by
    /// start timestamp ascending and paginated. Each entry carries the min/max absolute timestamps the
    /// file contributes to the channel. Optionally filtered by time bounds. Streamed sessions are not
    /// included; use getStreamsInBoundsV2 for those.
    /// Enforces read metadata permission on the datasource.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/channel-dataset-files",
        name = "listVideoChannelDatasetFiles",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn list_video_channel_dataset_files(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::ListVideoChannelDatasetFilesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::ListVideoChannelDatasetFilesResponse,
        conjure_http::private::Error,
    >;
    /// Updates one or more video dataset files in a channel in a single transaction. Each update may set a new
    /// absolute start timestamp (segments shifted so the earliest starts at the given timestamp), a scale
    /// parameter (frame timestamps rescaled around the file's start), and/or a new title (file name). If a
    /// resulting layout would overlap segments of another file in the channel, no files are updated and
    /// VIDEO_SEGMENT_CONFLICT is thrown (all-or-nothing). Returns the updated files with their new bounds.
    /// Currently only datasource-backed dataset channels are supported.
    /// Enforces write data permission on the datasource.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/channel-dataset-files/batch-update",
        name = "batchUpdateVideoChannelDatasetFiles",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn batch_update_video_channel_dataset_files(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::BatchUpdateVideoChannelDatasetFilesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::BatchUpdateVideoChannelDatasetFilesResponse,
        conjure_http::private::Error,
    >;
    /// Marks the active stream session as ended for the video.
    /// Throws VIDEO_NOT_FOUND if no active stream exists.
    /// Enforces write permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/end",
        name = "endStream",
        produces = conjure_http::server::StdResponseSerializer
    )]
    fn end_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::EndStreamResponse,
        conjure_http::private::Error,
    >;
    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
    /// Validates JWT and logs session. Future: create video segments from uploaded files.
    #[endpoint(
        method = POST,
        path = "/video/v1/segment/upload",
        name = "uploadSegmentFromMediaMtx"
    )]
    fn upload_segment_from_media_mtx(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[query(
            name = "streamPath",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "streamPath"
        )]
        stream_path: String,
        #[query(
            name = "filePath",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "filePath"
        )]
        file_path: String,
        #[query(
            name = "duration",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        duration: String,
        #[query(
            name = "minTimestampSeconds",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "minTimestampSeconds"
        )]
        min_timestamp_seconds: conjure_object::SafeLong,
        #[query(
            name = "minTimestampNanos",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "minTimestampNanos"
        )]
        min_timestamp_nanos: conjure_object::SafeLong,
        #[header(
            name = "Content-Length",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "contentLength"
        )]
        content_length: conjure_object::SafeLong,
        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
        body: I,
    ) -> Result<(), conjure_http::private::Error>;
}
/// The video service manages videos and video metadata.
#[conjure_http::conjure_endpoints(name = "VideoService", use_legacy_error_serialization)]
pub trait AsyncVideoService<#[request_body] I, #[response_writer] O> {
    ///The body type returned by the `get_playlist` method.
    type GetPlaylistBody: conjure_http::server::AsyncWriteBody<O> + 'static + Send;
    ///The body type returned by the `get_playlist_in_bounds` method.
    type GetPlaylistInBoundsBody: conjure_http::server::AsyncWriteBody<O>
        + 'static
        + Send;
    ///The body type returned by the `get_playlist_in_bounds_v2` method.
    type GetPlaylistInBoundsV2Body: conjure_http::server::AsyncWriteBody<O>
        + 'static
        + Send;
    ///The body type returned by the `get_playlist_v2` method.
    type GetPlaylistV2Body: conjure_http::server::AsyncWriteBody<O> + 'static + Send;
    /// Returns video metadata associated with a video rid.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}",
        name = "get",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    /// Returns video metadata about each video given a set of video rids.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/batchGet",
        name = "batchGet",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn batch_get(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetVideosRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetVideosResponse,
        conjure_http::private::Error,
    >;
    /// Returns metadata about videos that match a given query.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/search",
        name = "search",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn search(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::SearchVideosRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::SearchVideosResponse,
        conjure_http::private::Error,
    >;
    /// Creates and persists a video entity with the given metadata.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos",
        name = "create",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn create(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::CreateVideoRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    /// Updates the metadata for a video associated with the given video rid.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}",
        name = "updateMetadata",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn update_metadata(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::UpdateVideoMetadataRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/ingest-status",
        name = "updateIngestStatus"
    )]
    async fn update_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::UpdateIngestStatus,
    ) -> Result<(), conjure_http::private::Error>;
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/ingest-status",
        name = "getIngestStatus",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/batch-get-ingest-status",
        name = "batchGetIngestStatus",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn batch_get_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(
            deserializer = conjure_http::server::StdRequestDeserializer,
            log_as = "videoRids"
        )]
        video_rids: std::collections::BTreeSet<conjure_object::ResourceIdentifier>,
    ) -> Result<
        std::collections::BTreeMap<
            conjure_object::ResourceIdentifier,
            super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
        >,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/enriched-ingest-status",
        name = "getEnrichedIngestStatus",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_enriched_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetEnrichedVideoIngestStatusRequest,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::EnrichedVideoIngestStatus,
        >,
        conjure_http::private::Error,
    >;
    /// Archives a video, which excludes it from search and hides it from being publicly visible, but does not
    /// permanently delete it. Archived videos can be unarchived.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/archive",
        name = "archive"
    )]
    async fn archive(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<(), conjure_http::private::Error>;
    /// Unarchives a previously archived video.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/unarchive",
        name = "unarchive"
    )]
    async fn unarchive(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<(), conjure_http::private::Error>;
    /// Generates an HLS playlist for a video within optional time bounds.
    /// Uses GET with query parameters for HLS.js compatibility.
    /// The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds,
    /// or all segments if no bounds are provided.
    ///
    /// Note: The start and end parameters must either both be provided or both be omitted.
    /// Providing only one will result in a MissingTimestampBoundPair error.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/playlist",
        name = "getPlaylist",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    async fn get_playlist(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[query(
            name = "start",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        start: Option<String>,
        #[query(
            name = "end",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        end: Option<String>,
    ) -> Result<Self::GetPlaylistBody, conjure_http::private::Error>;
    /// Returns the min and max absolute and media timestamps for each segment in a video. To be used during
    /// frame-timestamp mapping.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/segment-summaries",
        name = "getSegmentSummaries",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_summaries(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
        conjure_http::private::Error,
    >;
    /// Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of
    /// bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given
    /// bounds.
    /// playlist will be limited to the given bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/playlist-in-bounds",
        name = "getPlaylistInBounds",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    async fn get_playlist_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsRequest,
    ) -> Result<Self::GetPlaylistInBoundsBody, conjure_http::private::Error>;
    /// Generates an HLS playlist for a video series (identified by channel + tags) within bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/playlist-in-bounds",
        name = "getPlaylistInBoundsV2",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    async fn get_playlist_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsForChannelRequest,
    ) -> Result<Self::GetPlaylistInBoundsV2Body, conjure_http::private::Error>;
    /// Generates an HLS playlist for a video series within time bounds.
    /// Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.
    ///
    /// Note: Both start and end parameters are required and must be provided together.
    #[endpoint(
        method = GET,
        path = "/video/v2/videos/playlist",
        name = "getPlaylistV2",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    async fn get_playlist_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[query(
            name = "dataSourceRid",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "dataSourceRid"
        )]
        data_source_rid: Option<conjure_object::ResourceIdentifier>,
        #[query(
            name = "assetRid",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "assetRid",
            safe
        )]
        asset_rid: Option<
            super::super::super::super::objects::scout::rids::api::AssetRid,
        >,
        #[query(
            name = "dataScopeName",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "dataScopeName"
        )]
        data_scope_name: Option<String>,
        #[query(
            name = "channel",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        channel: String,
        #[query(
            name = "tags",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        tags: Option<String>,
        #[query(
            name = "start",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        start: String,
        #[query(name = "end", decoder = conjure_http::server::conjure::FromPlainDecoder)]
        end: String,
    ) -> Result<Self::GetPlaylistV2Body, conjure_http::private::Error>;
    /// Returns the min and max absolute and media timestamps for each segment in a video that overlap with an
    /// optional set of bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/segment-summaries-in-bounds",
        name = "getSegmentSummariesInBounds",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_summaries_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsRequest,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
        conjure_http::private::Error,
    >;
    /// Returns the min and max absolute and media timestamps for each segment matching a video series
    /// (identified by channel + tags) within the specified bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/segment-summaries-in-bounds",
        name = "getSegmentSummariesInBoundsV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_summaries_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsForChannelRequest,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummaryV2>,
        conjure_http::private::Error,
    >;
    /// Returns aggregated segment metadata for a video channel series, including total frames,
    /// segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/segment-metadata",
        name = "getSegmentMetadataV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_metadata_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentMetadataForChannelRequest,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::VideoChannelSegmentsMetadata,
        >,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment within a video series containing the requested absolute timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/get-segment-by-timestamp",
        name = "getSegmentByTimestampV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_by_timestamp_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentByTimestampV2Request,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment containing the requested absolute timestamp. If no segment contains
    /// the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment
    /// is found at or after the timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp",
        name = "getSegmentAtOrAfterTimestamp",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_at_or_after_timestamp(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampRequest,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::Segment>,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment containing the requested absolute timestamp for a video series
    /// (identified by channel + tags). If no segment contains the timestamp, returns the closest segment
    /// starting after the timestamp. Returns empty if no segment is found at or after the timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/get-segment-at-or-after-timestamp",
        name = "getSegmentAtOrAfterTimestampV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_at_or_after_timestamp_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampV2Request,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
        conjure_http::private::Error,
    >;
    /// Returns the min and max absolute timestamps from non-archived video files associated with a given video that
    /// overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments
    /// that are inside or overlap with the bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data",
        name = "getFileSummaries",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get_file_summaries(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetFileSummariesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetFileSummariesResponse,
        conjure_http::private::Error,
    >;
    /// Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers.
    /// Enforces write permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/whip",
        name = "generateWhipStream",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn generate_whip_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
        conjure_http::private::Error,
    >;
    /// Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with
    /// a MediaMTX JWT and ICE servers.
    /// Currently only datasource-backed dataset channels are supported.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/whip",
        name = "generateWhipStreamV2",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn generate_whip_stream_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GenerateWhipStreamV2Request,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
        conjure_http::private::Error,
    >;
    /// Returns WHEP URL, ICE servers, and token for playing back the active stream.
    /// Returns empty if there is no active stream.
    /// Enforces read permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/whep",
        name = "generateWhepStream",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn generate_whep_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
        >,
        conjure_http::private::Error,
    >;
    /// Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream.
    /// Returns empty if there is no active stream.
    /// Currently only datasource-backed dataset channels are supported.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/whep",
        name = "generateWhepStreamV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn generate_whep_stream_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GenerateWhepStreamV2Request,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
        >,
        conjure_http::private::Error,
    >;
    /// Returns stream session metadata for a given stream ID scoped to the video.
    /// Enforces read permission on the video.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/streaming/streams/{streamId}",
        name = "getStream",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[path(
            name = "streamId",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "streamId"
        )]
        stream_id: String,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::VideoStream>,
        conjure_http::private::Error,
    >;
    /// Returns all stream sessions for a video that overlap with the specified time bounds.
    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
    /// Enforces read permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/streams-in-bounds",
        name = "getStreamsInBounds",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get_streams_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsResponse,
        conjure_http::private::Error,
    >;
    /// Returns all channel-backed stream sessions for a dataset/channel that overlap with the specified time bounds.
    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
    /// Enforces read metadata permission on the dataset.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/streams-in-bounds",
        name = "getStreamsInBoundsV2",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get_streams_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsForChannelRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsV2Response,
        conjure_http::private::Error,
    >;
    /// Returns the dataset files backing a video channel (identified by channel + tags), ordered by
    /// start timestamp ascending and paginated. Each entry carries the min/max absolute timestamps the
    /// file contributes to the channel. Optionally filtered by time bounds. Streamed sessions are not
    /// included; use getStreamsInBoundsV2 for those.
    /// Enforces read metadata permission on the datasource.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/channel-dataset-files",
        name = "listVideoChannelDatasetFiles",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn list_video_channel_dataset_files(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::ListVideoChannelDatasetFilesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::ListVideoChannelDatasetFilesResponse,
        conjure_http::private::Error,
    >;
    /// Updates one or more video dataset files in a channel in a single transaction. Each update may set a new
    /// absolute start timestamp (segments shifted so the earliest starts at the given timestamp), a scale
    /// parameter (frame timestamps rescaled around the file's start), and/or a new title (file name). If a
    /// resulting layout would overlap segments of another file in the channel, no files are updated and
    /// VIDEO_SEGMENT_CONFLICT is thrown (all-or-nothing). Returns the updated files with their new bounds.
    /// Currently only datasource-backed dataset channels are supported.
    /// Enforces write data permission on the datasource.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/channel-dataset-files/batch-update",
        name = "batchUpdateVideoChannelDatasetFiles",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn batch_update_video_channel_dataset_files(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::BatchUpdateVideoChannelDatasetFilesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::BatchUpdateVideoChannelDatasetFilesResponse,
        conjure_http::private::Error,
    >;
    /// Marks the active stream session as ended for the video.
    /// Throws VIDEO_NOT_FOUND if no active stream exists.
    /// Enforces write permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/end",
        name = "endStream",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn end_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::EndStreamResponse,
        conjure_http::private::Error,
    >;
    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
    /// Validates JWT and logs session. Future: create video segments from uploaded files.
    #[endpoint(
        method = POST,
        path = "/video/v1/segment/upload",
        name = "uploadSegmentFromMediaMtx"
    )]
    async fn upload_segment_from_media_mtx(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[query(
            name = "streamPath",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "streamPath"
        )]
        stream_path: String,
        #[query(
            name = "filePath",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "filePath"
        )]
        file_path: String,
        #[query(
            name = "duration",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        duration: String,
        #[query(
            name = "minTimestampSeconds",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "minTimestampSeconds"
        )]
        min_timestamp_seconds: conjure_object::SafeLong,
        #[query(
            name = "minTimestampNanos",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "minTimestampNanos"
        )]
        min_timestamp_nanos: conjure_object::SafeLong,
        #[header(
            name = "Content-Length",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "contentLength"
        )]
        content_length: conjure_object::SafeLong,
        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
        body: I,
    ) -> Result<(), conjure_http::private::Error>;
}
/// The video service manages videos and video metadata.
#[conjure_http::conjure_endpoints(
    name = "VideoService",
    use_legacy_error_serialization,
    local
)]
pub trait LocalAsyncVideoService<#[request_body] I, #[response_writer] O> {
    ///The body type returned by the `get_playlist` method.
    type GetPlaylistBody: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
    ///The body type returned by the `get_playlist_in_bounds` method.
    type GetPlaylistInBoundsBody: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
    ///The body type returned by the `get_playlist_in_bounds_v2` method.
    type GetPlaylistInBoundsV2Body: conjure_http::server::LocalAsyncWriteBody<O>
        + 'static;
    ///The body type returned by the `get_playlist_v2` method.
    type GetPlaylistV2Body: conjure_http::server::LocalAsyncWriteBody<O> + 'static;
    /// Returns video metadata associated with a video rid.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}",
        name = "get",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    /// Returns video metadata about each video given a set of video rids.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/batchGet",
        name = "batchGet",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn batch_get(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetVideosRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetVideosResponse,
        conjure_http::private::Error,
    >;
    /// Returns metadata about videos that match a given query.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/search",
        name = "search",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn search(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::SearchVideosRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::SearchVideosResponse,
        conjure_http::private::Error,
    >;
    /// Creates and persists a video entity with the given metadata.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos",
        name = "create",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn create(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::CreateVideoRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    /// Updates the metadata for a video associated with the given video rid.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}",
        name = "updateMetadata",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn update_metadata(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::UpdateVideoMetadataRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::Video,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/ingest-status",
        name = "updateIngestStatus"
    )]
    async fn update_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::UpdateIngestStatus,
    ) -> Result<(), conjure_http::private::Error>;
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/ingest-status",
        name = "getIngestStatus",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/batch-get-ingest-status",
        name = "batchGetIngestStatus",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn batch_get_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(
            deserializer = conjure_http::server::StdRequestDeserializer,
            log_as = "videoRids"
        )]
        video_rids: std::collections::BTreeSet<conjure_object::ResourceIdentifier>,
    ) -> Result<
        std::collections::BTreeMap<
            conjure_object::ResourceIdentifier,
            super::super::super::super::objects::scout::video::api::DetailedIngestStatus,
        >,
        conjure_http::private::Error,
    >;
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/enriched-ingest-status",
        name = "getEnrichedIngestStatus",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_enriched_ingest_status(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetEnrichedVideoIngestStatusRequest,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::EnrichedVideoIngestStatus,
        >,
        conjure_http::private::Error,
    >;
    /// Archives a video, which excludes it from search and hides it from being publicly visible, but does not
    /// permanently delete it. Archived videos can be unarchived.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/archive",
        name = "archive"
    )]
    async fn archive(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<(), conjure_http::private::Error>;
    /// Unarchives a previously archived video.
    #[endpoint(
        method = PUT,
        path = "/video/v1/videos/{videoRid}/unarchive",
        name = "unarchive"
    )]
    async fn unarchive(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<(), conjure_http::private::Error>;
    /// Generates an HLS playlist for a video within optional time bounds.
    /// Uses GET with query parameters for HLS.js compatibility.
    /// The HLS playlist will contain links to all of the segments in the video that overlap with the given bounds,
    /// or all segments if no bounds are provided.
    ///
    /// Note: The start and end parameters must either both be provided or both be omitted.
    /// Providing only one will result in a MissingTimestampBoundPair error.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/playlist",
        name = "getPlaylist",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    async fn get_playlist(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[query(
            name = "start",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        start: Option<String>,
        #[query(
            name = "end",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        end: Option<String>,
    ) -> Result<Self::GetPlaylistBody, conjure_http::private::Error>;
    /// Returns the min and max absolute and media timestamps for each segment in a video. To be used during
    /// frame-timestamp mapping.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/segment-summaries",
        name = "getSegmentSummaries",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_summaries(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
        conjure_http::private::Error,
    >;
    /// Generates an HLS playlist for a video with the given video rid to enable playback within an optional set of
    /// bounds. The HLS playlist will contain links to all of the segments in the video that overlap with the given
    /// bounds.
    /// playlist will be limited to the given bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/playlist-in-bounds",
        name = "getPlaylistInBounds",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    async fn get_playlist_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsRequest,
    ) -> Result<Self::GetPlaylistInBoundsBody, conjure_http::private::Error>;
    /// Generates an HLS playlist for a video series (identified by channel + tags) within bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/playlist-in-bounds",
        name = "getPlaylistInBoundsV2",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    async fn get_playlist_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetPlaylistInBoundsForChannelRequest,
    ) -> Result<Self::GetPlaylistInBoundsV2Body, conjure_http::private::Error>;
    /// Generates an HLS playlist for a video series within time bounds.
    /// Specify either dataSourceRid OR (assetRid + dataScopeName) to identify the series source.
    ///
    /// Note: Both start and end parameters are required and must be provided together.
    #[endpoint(
        method = GET,
        path = "/video/v2/videos/playlist",
        name = "getPlaylistV2",
        produces = conjure_http::server::conjure::BinaryResponseSerializer
    )]
    async fn get_playlist_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[query(
            name = "dataSourceRid",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "dataSourceRid"
        )]
        data_source_rid: Option<conjure_object::ResourceIdentifier>,
        #[query(
            name = "assetRid",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "assetRid",
            safe
        )]
        asset_rid: Option<
            super::super::super::super::objects::scout::rids::api::AssetRid,
        >,
        #[query(
            name = "dataScopeName",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
            log_as = "dataScopeName"
        )]
        data_scope_name: Option<String>,
        #[query(
            name = "channel",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        channel: String,
        #[query(
            name = "tags",
            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
        )]
        tags: Option<String>,
        #[query(
            name = "start",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        start: String,
        #[query(name = "end", decoder = conjure_http::server::conjure::FromPlainDecoder)]
        end: String,
    ) -> Result<Self::GetPlaylistV2Body, conjure_http::private::Error>;
    /// Returns the min and max absolute and media timestamps for each segment in a video that overlap with an
    /// optional set of bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/segment-summaries-in-bounds",
        name = "getSegmentSummariesInBounds",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_summaries_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsRequest,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummary>,
        conjure_http::private::Error,
    >;
    /// Returns the min and max absolute and media timestamps for each segment matching a video series
    /// (identified by channel + tags) within the specified bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/segment-summaries-in-bounds",
        name = "getSegmentSummariesInBoundsV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_summaries_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentSummariesInBoundsForChannelRequest,
    ) -> Result<
        Vec<super::super::super::super::objects::scout::video::api::SegmentSummaryV2>,
        conjure_http::private::Error,
    >;
    /// Returns aggregated segment metadata for a video channel series, including total frames,
    /// segment count, min/max timestamps, and average frame rate. Optionally filter by time bounds.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/segment-metadata",
        name = "getSegmentMetadataV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_metadata_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentMetadataForChannelRequest,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::VideoChannelSegmentsMetadata,
        >,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment within a video series containing the requested absolute timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/get-segment-by-timestamp",
        name = "getSegmentByTimestampV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_by_timestamp_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentByTimestampV2Request,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment containing the requested absolute timestamp. If no segment contains
    /// the timestamp, returns the closest segment starting after the timestamp. Returns empty if no segment
    /// is found at or after the timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/get-segment-at-or-after-timestamp",
        name = "getSegmentAtOrAfterTimestamp",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_at_or_after_timestamp(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampRequest,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::Segment>,
        conjure_http::private::Error,
    >;
    /// Returns metadata for the segment containing the requested absolute timestamp for a video series
    /// (identified by channel + tags). If no segment contains the timestamp, returns the closest segment
    /// starting after the timestamp. Returns empty if no segment is found at or after the timestamp.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/get-segment-at-or-after-timestamp",
        name = "getSegmentAtOrAfterTimestampV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_segment_at_or_after_timestamp_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetSegmentAtOrAfterTimestampV2Request,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::SegmentV2>,
        conjure_http::private::Error,
    >;
    /// Returns the min and max absolute timestamps from non-archived video files associated with a given video that
    /// overlap with an optional set of bounds. The files on the edges of the bounds will be truncated to segments
    /// that are inside or overlap with the bounds.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/get-ranges-with-existing-segment-data",
        name = "getFileSummaries",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get_file_summaries(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer, safe)]
        request: super::super::super::super::objects::scout::video::api::GetFileSummariesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetFileSummariesResponse,
        conjure_http::private::Error,
    >;
    /// Generates a stream ID scoped to a video and returns a WHIP URL with a MediaMTX JWT and ICE servers.
    /// Enforces write permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/whip",
        name = "generateWhipStream",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn generate_whip_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
        conjure_http::private::Error,
    >;
    /// Generates a stream ID scoped to a channel-backed live video series and returns a WHIP URL with
    /// a MediaMTX JWT and ICE servers.
    /// Currently only datasource-backed dataset channels are supported.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/whip",
        name = "generateWhipStreamV2",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn generate_whip_stream_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GenerateWhipStreamV2Request,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GenerateWhipStreamResponse,
        conjure_http::private::Error,
    >;
    /// Returns WHEP URL, ICE servers, and token for playing back the active stream.
    /// Returns empty if there is no active stream.
    /// Enforces read permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/whep",
        name = "generateWhepStream",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn generate_whep_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
        >,
        conjure_http::private::Error,
    >;
    /// Returns WHEP URL, ICE servers, and token for playing back the active channel-backed live video stream.
    /// Returns empty if there is no active stream.
    /// Currently only datasource-backed dataset channels are supported.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/whep",
        name = "generateWhepStreamV2",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn generate_whep_stream_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GenerateWhepStreamV2Request,
    ) -> Result<
        Option<
            super::super::super::super::objects::scout::video::api::GenerateWhepStreamResponse,
        >,
        conjure_http::private::Error,
    >;
    /// Returns stream session metadata for a given stream ID scoped to the video.
    /// Enforces read permission on the video.
    #[endpoint(
        method = GET,
        path = "/video/v1/videos/{videoRid}/streaming/streams/{streamId}",
        name = "getStream",
        produces = conjure_http::server::conjure::CollectionResponseSerializer
    )]
    async fn get_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[path(
            name = "streamId",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "streamId"
        )]
        stream_id: String,
    ) -> Result<
        Option<super::super::super::super::objects::scout::video::api::VideoStream>,
        conjure_http::private::Error,
    >;
    /// Returns all stream sessions for a video that overlap with the specified time bounds.
    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
    /// Enforces read permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/streams-in-bounds",
        name = "getStreamsInBounds",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get_streams_in_bounds(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsResponse,
        conjure_http::private::Error,
    >;
    /// Returns all channel-backed stream sessions for a dataset/channel that overlap with the specified time bounds.
    /// A stream overlaps if there is any intersection between its [start, end] interval and the provided bounds.
    /// Enforces read metadata permission on the dataset.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/streaming/streams-in-bounds",
        name = "getStreamsInBoundsV2",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn get_streams_in_bounds_v2(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::GetStreamsInBoundsForChannelRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::GetStreamsInBoundsV2Response,
        conjure_http::private::Error,
    >;
    /// Returns the dataset files backing a video channel (identified by channel + tags), ordered by
    /// start timestamp ascending and paginated. Each entry carries the min/max absolute timestamps the
    /// file contributes to the channel. Optionally filtered by time bounds. Streamed sessions are not
    /// included; use getStreamsInBoundsV2 for those.
    /// Enforces read metadata permission on the datasource.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/channel-dataset-files",
        name = "listVideoChannelDatasetFiles",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn list_video_channel_dataset_files(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::ListVideoChannelDatasetFilesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::ListVideoChannelDatasetFilesResponse,
        conjure_http::private::Error,
    >;
    /// Updates one or more video dataset files in a channel in a single transaction. Each update may set a new
    /// absolute start timestamp (segments shifted so the earliest starts at the given timestamp), a scale
    /// parameter (frame timestamps rescaled around the file's start), and/or a new title (file name). If a
    /// resulting layout would overlap segments of another file in the channel, no files are updated and
    /// VIDEO_SEGMENT_CONFLICT is thrown (all-or-nothing). Returns the updated files with their new bounds.
    /// Currently only datasource-backed dataset channels are supported.
    /// Enforces write data permission on the datasource.
    #[endpoint(
        method = POST,
        path = "/video/v2/videos/channel-dataset-files/batch-update",
        name = "batchUpdateVideoChannelDatasetFiles",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn batch_update_video_channel_dataset_files(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
        request: super::super::super::super::objects::scout::video::api::BatchUpdateVideoChannelDatasetFilesRequest,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::BatchUpdateVideoChannelDatasetFilesResponse,
        conjure_http::private::Error,
    >;
    /// Marks the active stream session as ended for the video.
    /// Throws VIDEO_NOT_FOUND if no active stream exists.
    /// Enforces write permission on the video.
    #[endpoint(
        method = POST,
        path = "/video/v1/videos/{videoRid}/streaming/end",
        name = "endStream",
        produces = conjure_http::server::StdResponseSerializer
    )]
    async fn end_stream(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[path(
            name = "videoRid",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "videoRid"
        )]
        video_rid: conjure_object::ResourceIdentifier,
    ) -> Result<
        super::super::super::super::objects::scout::video::api::EndStreamResponse,
        conjure_http::private::Error,
    >;
    /// MediaMTX segment upload endpoint. Receives video segments from MediaMTX hooks.
    /// Validates JWT and logs session. Future: create video segments from uploaded files.
    #[endpoint(
        method = POST,
        path = "/video/v1/segment/upload",
        name = "uploadSegmentFromMediaMtx"
    )]
    async fn upload_segment_from_media_mtx(
        &self,
        #[auth]
        auth_: conjure_object::BearerToken,
        #[query(
            name = "streamPath",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "streamPath"
        )]
        stream_path: String,
        #[query(
            name = "filePath",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "filePath"
        )]
        file_path: String,
        #[query(
            name = "duration",
            decoder = conjure_http::server::conjure::FromPlainDecoder
        )]
        duration: String,
        #[query(
            name = "minTimestampSeconds",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "minTimestampSeconds"
        )]
        min_timestamp_seconds: conjure_object::SafeLong,
        #[query(
            name = "minTimestampNanos",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "minTimestampNanos"
        )]
        min_timestamp_nanos: conjure_object::SafeLong,
        #[header(
            name = "Content-Length",
            decoder = conjure_http::server::conjure::FromPlainDecoder,
            log_as = "contentLength"
        )]
        content_length: conjure_object::SafeLong,
        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
        body: I,
    ) -> Result<(), conjure_http::private::Error>;
}
