Skip to main content

async_openai/
video.rs

1use crate::{
2    config::Config,
3    error::OpenAIError,
4    types::videos::{
5        CreateVideoCharacterRequest, CreateVideoEditRequest, CreateVideoExtendRequest,
6        CreateVideoRequest, DeletedVideoResource, RemixVideoRequest, VideoCharacterResource,
7        VideoListResource, VideoResource,
8    },
9    Client, RequestOptions,
10};
11use bytes::Bytes;
12
13/// Video generation with Sora
14/// Related guide: [Video generation](https://platform.openai.com/docs/guides/video-generation)
15pub struct Videos<'c, C: Config> {
16    client: &'c Client<C>,
17    pub(crate) request_options: RequestOptions,
18}
19
20impl<'c, C: Config> Videos<'c, C> {
21    pub fn new(client: &'c Client<C>) -> Self {
22        Self {
23            client,
24            request_options: RequestOptions::new(),
25        }
26    }
27
28    /// Create a video
29    #[crate::byot(
30        T0 = Clone,
31        R = serde::de::DeserializeOwned,
32        where_clause =  "reqwest::multipart::Form: crate::traits::AsyncTryFrom<T0, Error = OpenAIError>",
33    )]
34    pub async fn create(&self, request: CreateVideoRequest) -> Result<VideoResource, OpenAIError> {
35        self.client
36            .post_form("/videos", request, &self.request_options)
37            .await
38    }
39
40    /// Create a video remix
41    #[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
42    pub async fn remix(
43        &self,
44        video_id: &str,
45        request: RemixVideoRequest,
46    ) -> Result<VideoResource, OpenAIError> {
47        self.client
48            .post(
49                &format!("/videos/{video_id}/remix"),
50                request,
51                &self.request_options,
52            )
53            .await
54    }
55
56    /// Create a character from an uploaded video.
57    #[crate::byot(
58        T0 = Clone,
59        R = serde::de::DeserializeOwned,
60        where_clause = "reqwest::multipart::Form: crate::traits::AsyncTryFrom<T0, Error = OpenAIError>",
61    )]
62    pub async fn create_character(
63        &self,
64        request: CreateVideoCharacterRequest,
65    ) -> Result<VideoCharacterResource, OpenAIError> {
66        self.client
67            .post_form("/videos/characters", request, &self.request_options)
68            .await
69    }
70
71    /// Fetch a character by its ID.
72    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
73    pub async fn get_character(
74        &self,
75        character_id: &str,
76    ) -> Result<VideoCharacterResource, OpenAIError> {
77        self.client
78            .get(
79                &format!("/videos/characters/{character_id}"),
80                &self.request_options,
81            )
82            .await
83    }
84
85    /// Create a new video generation job by editing a source video.
86    #[crate::byot(
87        T0 = Clone,
88        R = serde::de::DeserializeOwned,
89        where_clause = "reqwest::multipart::Form: crate::traits::AsyncTryFrom<T0, Error = OpenAIError>",
90    )]
91    pub async fn edit(
92        &self,
93        request: CreateVideoEditRequest,
94    ) -> Result<VideoResource, OpenAIError> {
95        self.client
96            .post_form("/videos/edits", request, &self.request_options)
97            .await
98    }
99
100    /// Create an extension of a completed video.
101    #[crate::byot(
102        T0 = Clone,
103        R = serde::de::DeserializeOwned,
104        where_clause = "reqwest::multipart::Form: crate::traits::AsyncTryFrom<T0, Error = OpenAIError>",
105    )]
106    pub async fn extend(
107        &self,
108        request: CreateVideoExtendRequest,
109    ) -> Result<VideoResource, OpenAIError> {
110        self.client
111            .post_form("/videos/extensions", request, &self.request_options)
112            .await
113    }
114
115    /// Retrieves a video by its ID.
116    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
117    pub async fn retrieve(&self, video_id: &str) -> Result<VideoResource, OpenAIError> {
118        self.client
119            .get(&format!("/videos/{}", video_id), &self.request_options)
120            .await
121    }
122
123    /// Delete a Video
124    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
125    pub async fn delete(&self, video_id: &str) -> Result<DeletedVideoResource, OpenAIError> {
126        self.client
127            .delete(&format!("/videos/{}", video_id), &self.request_options)
128            .await
129    }
130
131    /// List Videos
132    #[crate::byot(R = serde::de::DeserializeOwned)]
133    pub async fn list(&self) -> Result<VideoListResource, OpenAIError> {
134        self.client.get("/videos", &self.request_options).await
135    }
136
137    /// Download video content.
138    /// Variant can be provided as query parameter
139    pub async fn download_content(&self, video_id: &str) -> Result<Bytes, OpenAIError> {
140        let (bytes, _headers) = self
141            .client
142            .get_raw(
143                &format!("/videos/{video_id}/content"),
144                &self.request_options,
145            )
146            .await?;
147        Ok(bytes)
148    }
149}